HTML + CSS 终极面试全攻略(八股文 + 场景题 + 工程落地)

定位:不仅能回答"是什么",还能讲清楚"为什么、怎么落地、踩过哪些坑"。


目录

  • [1. HTML 篇](#1. HTML 篇 "#1-html-%E7%AF%87")
    • [1.1 语义化(Semantic HTML)](#1.1 语义化(Semantic HTML) "#11-%E8%AF%AD%E4%B9%89%E5%8C%96semantic-html")
    • [1.2 块级/行内/行内块](#1.2 块级/行内/行内块 "#12-%E5%9D%97%E7%BA%A7%E8%A1%8C%E5%86%85%E8%A1%8C%E5%86%85%E5%9D%97")
    • [1.3 scriptasync / defer 区别](#1.3 script 的 async / defer 区别 "#13-script-%E7%9A%84-async--defer-%E5%8C%BA%E5%88%AB")
    • [1.4 meta viewport](#1.4 meta viewport "#14-meta-viewport")
    • [1.5 imgalt、懒加载与图片性能](#1.5 img 的 alt、懒加载与图片性能 "#15-img-%E7%9A%84-alt%E6%87%92%E5%8A%A0%E8%BD%BD%E4%B8%8E%E5%9B%BE%E7%89%87%E6%80%A7%E8%83%BD")
    • [1.6 表单与可访问性(A11y)](#1.6 表单与可访问性(A11y) "#16-%E8%A1%A8%E5%8D%95%E4%B8%8E%E5%8F%AF%E8%AE%BF%E9%97%AE%E6%80%A7a11y")
  • [2. CSS 基础与原理篇](#2. CSS 基础与原理篇 "#2-css-%E5%9F%BA%E7%A1%80%E4%B8%8E%E5%8E%9F%E7%90%86%E7%AF%87")
    • [2.1 选择器优先级(Specificity)](#2.1 选择器优先级(Specificity) "#21-%E9%80%89%E6%8B%A9%E5%99%A8%E4%BC%98%E5%85%88%E7%BA%A7specificity")
    • [2.2 盒模型与 box-sizing](#2.2 盒模型与 box-sizing "#22-%E7%9B%92%E6%A8%A1%E5%9E%8B%E4%B8%8E-box-sizing")
    • [2.3 BFC(块级格式化上下文)](#2.3 BFC(块级格式化上下文) "#23-bfc%E5%9D%97%E7%BA%A7%E6%A0%BC%E5%BC%8F%E5%8C%96%E4%B8%8A%E4%B8%8B%E6%96%87")
    • [2.4 浮动与清除浮动](#2.4 浮动与清除浮动 "#24-%E6%B5%AE%E5%8A%A8%E4%B8%8E%E6%B8%85%E9%99%A4%E6%B5%AE%E5%8A%A8")
    • [2.5 position:relative/absolute/fixed/sticky](#2.5 position:relative/absolute/fixed/sticky "#25-positionrelativeabsolutefixedsticky")
    • [2.6 Flex:flex: 1、压缩、溢出与 min-width: 0](#2.6 Flex:flex: 1、压缩、溢出与 min-width: 0 "#26-flexflex-1%E5%8E%8B%E7%BC%A9%E6%BA%A2%E5%87%BA%E4%B8%8E-min-width-0")
    • [2.7 Grid:二维布局加分项](#2.7 Grid:二维布局加分项 "#27-grid%E4%BA%8C%E7%BB%B4%E5%B8%83%E5%B1%80%E5%8A%A0%E5%88%86%E9%A1%B9")
    • [2.8 常见居中方案](#2.8 常见居中方案 "#28-%E5%B8%B8%E8%A7%81%E5%B1%85%E4%B8%AD%E6%96%B9%E6%A1%88")
    • [2.9 z-index 与层叠上下文(Stacking Context)](#2.9 z-index 与层叠上下文(Stacking Context) "#29-z-index-%E4%B8%8E%E5%B1%82%E5%8F%A0%E4%B8%8A%E4%B8%8B%E6%96%87stacking-context")
    • [2.10 继承、层叠、计算值(CSS 三板斧)](#2.10 继承、层叠、计算值(CSS 三板斧) "#210-%E7%BB%A7%E6%89%BF%E5%B1%82%E5%8F%A0%E8%AE%A1%E7%AE%97%E5%80%BCcss-%E4%B8%89%E6%9D%BF%E6%96%A7")
    • [2.11 响应式单位与媒体查询](#2.11 响应式单位与媒体查询 "#211-%E5%93%8D%E5%BA%94%E5%BC%8F%E5%8D%95%E4%BD%8D%E4%B8%8E%E5%AA%92%E4%BD%93%E6%9F%A5%E8%AF%A2")
    • [2.12 transition vs animation 与性能要点](#2.12 transition vs animation 与性能要点 "#212-transition-vs-animation-%E4%B8%8E%E6%80%A7%E8%83%BD%E8%A6%81%E7%82%B9")
  • [3. 工程化与落地(公司最常用)](#3. 工程化与落地(公司最常用) "#3-%E5%B7%A5%E7%A8%8B%E5%8C%96%E4%B8%8E%E8%90%BD%E5%9C%B0%E5%85%AC%E5%8F%B8%E6%9C%80%E5%B8%B8%E7%94%A8")
    • [3.1 移动端适配选型:rem / vw / rpx / scale](#3.1 移动端适配选型:rem / vw / rpx / scale "#31-%E7%A7%BB%E5%8A%A8%E7%AB%AF%E9%80%82%E9%85%8D%E9%80%89%E5%9E%8Brem--vw--rpx--scale")
    • [3.2 H5(Vue/React)方案:PostCSS 自动转换(推荐写 px)](#3.2 H5(Vue/React)方案:PostCSS 自动转换(推荐写 px) "#32-h5vuereact-%E6%96%B9%E6%A1%88postcss-%E8%87%AA%E5%8A%A8%E8%BD%AC%E6%8D%A2%E6%8E%A8%E8%8D%90%E5%86%99-px")
    • [3.3 uni-app / 小程序:rpx 与安全区](#3.3 uni-app / 小程序:rpx 与安全区 "#33-uni-app--%E5%B0%8F%E7%A8%8B%E5%BA%8Frpx-%E4%B8%8E%E5%AE%89%E5%85%A8%E5%8C%BA")
    • [3.4 PC 响应式(B 端/官网):版心 + 断点 + Flex/Grid](#3.4 PC 响应式(B 端/官网):版心 + 断点 + Flex/Grid "#34-pc-%E5%93%8D%E5%BA%94%E5%BC%8Fb-%E7%AB%AF%E5%AE%98%E7%BD%91%E7%89%88%E5%BF%83--%E6%96%AD%E7%82%B9--flexgrid")
    • [3.5 大屏可视化:容器等比缩放(transform: scale)](#3.5 大屏可视化:容器等比缩放(transform: scale) "#35-%E5%A4%A7%E5%B1%8F%E5%8F%AF%E8%A7%86%E5%8C%96%E5%AE%B9%E5%99%A8%E7%AD%89%E6%AF%94%E7%BC%A9%E6%94%BEtransform-scale")
    • [3.6 移动端 1px 问题(Retina)](#3.6 移动端 1px 问题(Retina) "#36-%E7%A7%BB%E5%8A%A8%E7%AB%AF-1px-%E9%97%AE%E9%A2%98retina")
    • [3.7 隐藏元素:display:none / visibility:hidden / opacity:0](#3.7 隐藏元素:display:none / visibility:hidden / opacity:0 "#37-%E9%9A%90%E8%97%8F%E5%85%83%E7%B4%A0displaynone--visibilityhidden--opacity0")
    • [3.8 响应式布局 SOP(步骤 + 不同场景方案)](#3.8 响应式布局 SOP(步骤 + 不同场景方案) "#38-%E5%93%8D%E5%BA%94%E5%BC%8F%E5%B8%83%E5%B1%80-sop%E6%AD%A5%E9%AA%A4--%E4%B8%8D%E5%90%8C%E5%9C%BA%E6%99%AF%E6%96%B9%E6%A1%88")
  • [4. 高频场景题(面试直接用)](#4. 高频场景题(面试直接用) "#4-%E9%AB%98%E9%A2%91%E5%9C%BA%E6%99%AF%E9%A2%98%E9%9D%A2%E8%AF%95%E7%9B%B4%E6%8E%A5%E7%94%A8")

1. HTML 篇

1.1 语义化(Semantic HTML)

  • 是什么
    • 使用符合内容含义的标签(header/nav/main/article/section/aside/footerh1-h6pul/lifigure/figcaption 等)描述结构,而不是全用 div/span
  • 为什么(收益)
    • SEO:搜索引擎更容易理解页面结构与权重。
    • 可访问性(A11y):读屏软件更好解析;键盘导航更顺。
    • 可维护性:结构清晰,样式/脚本更容易定位。
    • 默认行为 :例如 button 天然可聚焦、可键盘触发。
  • 常见追问
    • section vs divsection 表示主题分区(通常应该有标题),div 是无语义容器。
    • em/strong vs i/b:前者强调语义,后者偏展示。
  • 常见坑
    • div 冒充按钮但缺少 role="button"tabindex="0"、键盘事件。

1.2 块级/行内/行内块

  • 块级(block) :独占一行;可设置 width/height/margin/padding
  • 行内(inline) :不独占一行;width/height 通常不生效;margin-top/bottom 通常不生效。
  • 行内块(inline-block) :不独占一行,但可设置 width/height
  • 追问:inline-block 空白间隙怎么解决
    • 删除标签间空白/换行;父元素 font-size:0;或者直接改用 flex/grid

1.3 scriptasync / defer 区别

  • async/defer:下载+执行会阻塞 HTML 解析。
  • defer:并行下载;等 DOM 解析完成后按顺序执行;适合业务脚本。
  • async:并行下载;下载完立刻执行(可能打断解析);顺序不保证;适合统计/埋点。
  • 追问
    • type="module":模块脚本默认行为更接近 defer(并行下载,解析后执行)。

1.4 meta viewport

常用写法:

html 复制代码
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
  • 作用:控制移动端布局视口宽度与缩放,避免页面被缩小。
  • 工程提醒
    • 不建议为了"防缩放"随意加 user-scalable=no(可访问性风险)。

1.5 imgalt、懒加载与图片性能

  • alt:图片加载失败的替代文本;对 SEO/读屏重要。
  • 懒加载
    • 原生:loading="lazy"
    • 更强控制:IntersectionObserver
  • 响应式图片srcset/sizes(按容器加载不同分辨率)。

1.6 表单与可访问性(A11y)

  • labelinput 绑定
    • label for="id" + input id="id",或 label 包裹 input
  • button 默认类型
    • form 内默认 type="submit",非提交按钮要显式写 type="button"

2. CSS 基础与原理篇

2.1 选择器优先级(Specificity)

  • 常见优先级从高到低
    • !important > 行内样式 > #id > .class/[attr]/:pseudo-class > tag/::pseudo-element > 通配 */继承
  • 同级规则
    • 优先级相同:后写覆盖先写。
    • :not() 本身不加权重,但括号里的选择器会增加权重。

2.2 盒模型与 box-sizing

  • 标准盒模型width/height 只包含 content
  • 工程推荐 :全局 box-sizing: border-box;,布局更符合"视觉宽度"。

2.3 BFC(块级格式化上下文)

  • 人话解释:BFC 是一个独立的渲染区域/布局"结界",内部布局不会在某些方面影响外部。
  • 常见触发方式
    • overflowvisible
    • display: flow-root(推荐)/flex/grid/inline-block
    • position: absolute/fixed
  • 经典用途
    • 清除浮动造成的父元素高度塌陷
    • 避免 margin 合并
    • 两栏布局:让右侧自适应不被浮动覆盖

2.4 浮动与清除浮动

  • 塌陷原因:浮动元素脱离普通流,不撑开父元素高度。
  • 清除方式
    • 伪元素 clearfix
    • 触发 BFC:overflow: hiddendisplay: flow-root

2.5 position:relative/absolute/fixed/sticky

  • relative:不脱离文档流;偏移相对自身原位置。
  • absolute:脱离文档流;相对最近定位祖先。
  • fixed:相对视口;注意某些场景会受祖先 transform 影响。
  • sticky:滚动到阈值后吸顶;必须指定 top/left/...

2.6 Flex:flex: 1、压缩、溢出与 min-width: 0

  • flex: 1 常见解释flex: 1 1 0%,用于均分剩余空间。
  • 高频坑:长文本把布局撑爆
    • Flex 子项默认 min-width: auto,内容过长会撑开。
    • 工程解法 :在需要截断/可滚动的子项上加 min-width: 0

2.7 Grid:二维布局加分项

  • 更适合二维栅格布局;常用 repeat()minmax()frgap

2.8 常见居中方案

  • Flex:
css 复制代码
.parent { display: flex; justify-content: center; align-items: center; }
  • Grid:
css 复制代码
.parent { display: grid; place-items: center; }
  • 绝对定位 + transform:
css 复制代码
.child { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }

2.9 z-index 与层叠上下文(Stacking Context)

  • 结论z-index 只在同一层叠上下文里比较。
  • 常见创建层叠上下文
    • position 非 static + z-index 非 auto
    • transform 非 none、opacity < 1

2.10 继承、层叠、计算值(CSS 三板斧)

  • 继承 :如 colorfont-* 常继承;margin/padding/border 不继承。
  • 层叠:来源 + 权重 + 顺序共同决定。

2.11 响应式单位与媒体查询

  • 单位:%/rem/em/vw/vh 各有场景。
  • 断点:@media (max-width: 768px) { ... } 等。

2.12 transition vs animation 与性能要点

  • transition:状态变化触发。
  • animation@keyframes 更复杂时间线。
  • 性能建议 :优先动画 transform/opacity,避免高频动画 top/left/width/height

3. 工程化与落地(公司最常用)

3.1 移动端适配选型:rem / vw / rpx / scale

  • 核心结论
    • 你不应该让开发"手写 rem/vw",而是:代码里写 px,构建阶段自动转换
    • 场景选型:
      • 新 H5 项目 :更偏向 vw(PostCSS 转换)
      • 老项目/兼容性要求极高rem(动态 root + PostCSS 转换)
      • uni-app/小程序rpx
      • 大屏可视化 :容器等比缩放 transform: scale()

3.2 H5(Vue/React)方案:PostCSS 自动转换(推荐写 px

方案 A:vw(推荐)+ postcss-px-to-viewport

  • 典型配置(postcss.config.js
js 复制代码
module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      viewportWidth: 375,
      unitPrecision: 5,
      viewportUnit: 'vw',
      selectorBlackList: ['.ignore', '.hairlines'],
      minPixelValue: 1,
      mediaQuery: false,
      exclude: [/node_modules/],
    },
  },
}
  • 公司里最常见的坑
    • UI 库(如 Vant)设计基准可能与业务设计稿不同(375 vs 750),不做隔离会导致 UI 库整体缩小/放大。
    • 常见处理:exclude UI 库,或者使用支持动态 viewportWidth 的插件版本按路径区分。

方案 B:rem(经典)+ amfe-flexible + postcss-pxtorem

  • 核心点 :动态设置 htmlfont-size,并在构建阶段将 pxrem
  • 典型配置要点(按 UI 库/业务代码区分 rootValue)
js 复制代码
module.exports = {
  plugins: {
    'postcss-pxtorem': {
      rootValue({ file }) {
        return file.indexOf('vant') !== -1 ? 37.5 : 75
      },
      propList: ['*'],
      selectorBlackList: ['.norem'],
    },
  },
}

3.3 uni-app / 小程序:rpx 与安全区

  • 单位 :优先 rpx,常配合 750 设计稿心智最一致。
  • 布局 :以 flex 为主,少用硬编码高度。
  • 安全区(底部 Home 指示条)
css 复制代码
.page {
  padding-bottom: env(safe-area-inset-bottom);
}

3.4 PC 响应式(B 端/官网):版心 + 断点 + Flex/Grid

  • 不要在 PC 全站做 rem/vw 等比缩放(屏幕跨度太大,体验不可控)。
  • 常见落地组合
    • 版心:max-width: 1200px/1440px; margin: 0 auto;
    • 布局:Flex/Grid
    • 断点:对关键布局重排
css 复制代码
@media screen and (max-width: 992px) {
  .sidebar { display: none; }
}

3.5 大屏可视化:容器等比缩放(transform: scale

  • 适用:强视觉还原、固定画布(如 1920x1080)。
  • 核心代码(监听 resize 计算 scale)
js 复制代码
function fitScreen() {
  const designW = 1920
  const designH = 1080
  const scaleX = window.innerWidth / designW
  const scaleY = window.innerHeight / designH
  const scale = Math.min(scaleX, scaleY)
  const el = document.getElementById('screen')
  el.style.transform = `scale(${scale})`
  el.style.transformOrigin = 'left top'
}

fitScreen()
window.addEventListener('resize', fitScreen)
  • 注意 :如果涉及点击/拖拽坐标,需要按 scale 反算。

3.6 移动端 1px 问题(Retina)

  • 现象 :高 DPR 屏上 1px 视觉上变粗。
  • 常见落地:伪元素 + 缩放
css 复制代码
.border-1px {
  position: relative;
}

.border-1px::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: #ccc;
  transform: scaleY(0.5);
  transform-origin: 0 0;
}

3.7 隐藏元素:display:none / visibility:hidden / opacity:0

  • display: none:不占位;触发 reflow;不可点击。
  • visibility: hidden:占位;触发 repaint;不可点击。
  • opacity: 0:占位;通常 repaint;仍可点击(除非配合 pointer-events: none)。

3.8 响应式布局 SOP(步骤 + 不同场景方案)

你可以把这一节当成:面试回答模板 + 项目落地 SOP(标准操作流程)。

3.8.1 先给结论:响应式不是一个技术点,是"策略组合"

  • A. 等比缩放 :页面整体按比例放大缩小
    • 常见:大屏看板、强还原活动页
  • B. 响应式重排 :不同宽度下布局结构变化
    • 常见:PC 官网 / B 端
  • C. 流式自适应 :布局不大改,但局部宽高、字体、间距自适应
    • 常见:移动端业务 H5

3.8.2 落地步骤(SOP:从需求到上线)

  • Step 1:明确输入条件(必须问清)

    • 设计基准:设计稿宽度(375 / 750 / 1200 / 1920x1080
    • 目标设备:移动端 H5(WebView/浏览器)/ PC / 小程序(含 uni-app)/ 大屏
    • 是否允许重排:是否能接受某些屏幕变成单列、某些模块折行
    • 兼容性要求:最低 iOS/Android/浏览器版本
    • 关键体验约束:固定底栏/弹窗、长列表、图表/Canvas 等
  • Step 2:先选布局骨架(优先级:Grid > Flex > 传统)

    • 二维区域布局/栅格:优先 grid
    • 一维布局(横排/竖排):优先 flex
    • 避免用 float 作为布局系统(除非老项目维护)
  • Step 3:确定"尺寸体系"(决定 rem/vw/px/clamp 的组合)

    • 移动端 H5:推荐"写 px + PostCSS 自动转换为 vw/rem"
    • PC:以 px 为主 + 版心 + 断点(必要时少量 %/fr
    • 大屏:内部按设计稿 px,外层容器 transform: scale()
  • Step 4:断点策略(不是越多越好)

    • 移动端:通常少断点,更多靠流式布局;必要时单独考虑 Pad(>=768
    • PC:常用 3-5 个断点(如 1200/992/768/576)就够用
    • 大屏:优先等比缩放,不建议靠大量断点救火
  • Step 5:上线前兜底(公司里最容易翻车的地方)

    • 文本溢出:单行/多行省略号,Flex 子项记得 min-width: 0
    • 图片:max-width: 100%、必要时 object-fit: cover
    • 安全区:env(safe-area-inset-bottom)
    • 性能:动画只动 transform/opacity;长列表考虑虚拟列表

3.8.3 不同场景的"对口方案"(可直接落地)

  • 移动端 H5(业务页/内嵌页)

    • 目标:流式自适应为主,不追求像素级完全一致
    • 推荐:flex/grid + PostCSS(px -> vw)+ clamp() 做上下限 + 安全区/1px/弹窗兜底
  • PC 官网 / B 端后台

    • 目标:断点重排 + 版心控制阅读宽度
    • 推荐:Grid 做栅格区域 + Flex 做组件内部;max-width 版心;关键断点重排(侧边栏折叠等)
  • uni-app / 小程序

    • 目标:利用平台原生适配能力
    • 推荐:rpx + flex;优先使用生态组件库,减少引入写死 px 的第三方 H5 样式
  • 大屏可视化(DataV/看板)

    • 目标:严格保真,不换行、不乱跑位
    • 推荐:内部按设计稿 px 写,外层 transform: scale(),交互坐标按 scale 反算

3.8.4 面试一句话收尾(背下来)

"响应式我会先明确目标是等比缩放还是断点重排。移动端业务页用 Flex/Grid + PostCSS 的 vw(必要时 clamp)保证流式自适应;PC 端用版心 + 断点做结构重排;小程序用 rpx;大屏用容器 scale 保真。最后统一补齐文本溢出、安全区、1px、弹窗与性能兜底。"


4. 高频场景题(面试直接用)

4.1 三栏布局:两侧固定,中间自适应

  • 可背诵答案(30 秒版)

    • "我会优先用 flex:左右两栏固定宽度,中间一栏 flex: 1 占满剩余空间。中间为了防止长文本把布局撑爆,会显式加 min-width: 0,再配合 overflow: hidden; text-overflow: ellipsis; 或内部滚动。"
  • 推荐实现(Flex)

html 复制代码
<div class="layout">
  <aside class="left">left</aside>
  <main class="mid">middle middle middle ...</main>
  <aside class="right">right</aside>
</div>
css 复制代码
.layout {
  display: flex;
}

.left,
.right {
  width: 200px;
  flex: 0 0 200px;
}

.mid {
  flex: 1;
  min-width: 0; /* 关键:允许在 flex 容器内缩小,避免长内容撑爆 */
}
  • 高频追问
    • 为什么要 min-width: 0:Flex 子项默认 min-width: auto,内容过长会让它不愿意缩小。
    • 不用 flex 你还有方案吗:Grid(更适合二维),以及老方案(float + BFC/定位)但现代不推荐。

4.2 弹窗 z-index: 9999 仍被遮住

  • 可背诵答案(30 秒版)

    • "z-index 只在同一个层叠上下文里比较。如果弹窗的祖先元素创建了层叠上下文(比如 transformopacity<1position+z-index),那弹窗的 z-index 再大也只能在这个上下文里排队,盖不住别的上下文。工程上我通常把弹窗挂到 body(React Portal / Vue Teleport),从根层级统一管理。"
  • 如何快速定位(排查路径)

    • 检查弹窗及其祖先是否存在:
      • transform: translateZ(0) / transform: ...
      • opacity < 1
      • position 非 static 且 z-index 非 auto
      • filterwill-change
  • 工程落地建议

    • 组件库/业务统一方案 :全站只有一个 #modal-root,所有弹窗都挂载到这里。
    • 管理策略:用"弹窗栈"管理层级(比如每开一个弹窗,z-index 递增)。

4.3 position: sticky 不生效

  • 可背诵答案(30 秒版)

    • "sticky 需要一个滚动容器,并且必须指定 top/left/right/bottom 其中一个阈值。常见失效原因是祖先设置了 overflow: hidden/auto/scroll 改变了滚动容器,或者容器高度不足导致根本触发不了吸附。"
  • 常见失效清单(面试官最爱挖坑)

    • 没写 top(最常见)
    • 父级/祖先 overflowvisible(尤其 overflow: hidden
    • 滚动发生在另一个容器(不是你以为的 window)
    • sticky 元素所在容器高度不够(滚动距离不足)
  • 参考代码

css 复制代码
.sticky {
  position: sticky;
  top: 0;
  z-index: 10;
}

4.4 回流(reflow)/重绘(repaint)与优化

  • 可背诵答案(60 秒版)

    • "回流是布局计算阶段(尺寸/位置变化导致 Layout 重新算),重绘是像素绘制阶段(颜色/阴影变化触发 Paint)。回流一定会引起重绘,重绘不一定回流。优化上:尽量减少触发布局的属性变化,把动画放到 transform/opacity,批量读写 DOM,避免强制同步布局(比如频繁读 offsetHeight)。长列表用虚拟列表,图片用懒加载。"
  • 常见触发回流的操作(会被追问)

    • 改几何属性:width/height/padding/margin/top/left/border(部分)
    • 插入/删除 DOM 节点,改变字体大小
    • 读取布局信息会触发"强制同步布局":offsetHeight/getBoundingClientRect(在你前面有写操作时)
  • 工程级优化清单

    • 动画:只动 transform/opacity(必要时 will-change,但别滥用)
    • DOM:合并操作(改 class 而不是逐条改 style),读写分离
    • 长列表:虚拟列表/分页渲染
    • 新特性加分:content-visibility: auto;(对长页面有帮助)

4.5 两栏布局:左固定右自适应(最常用)

  • Flex 推荐写法
css 复制代码
.wrap { display: flex; }
.left { width: 240px; flex: 0 0 240px; }
.right { flex: 1; min-width: 0; }
  • 追问点
    • 右侧内容长导致撑开:同样用 min-width: 0

4.6 文本溢出省略号:单行/多行

  • 单行省略号
css 复制代码
.ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
  • 多行省略号(常问,含兼容性)
css 复制代码
.clamp {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
}
  • 追问点
    • 多行省略号是非标准方案(WebKit 私有),复杂场景可能要用 JS 计算。

4.7 图片底部为什么会有"缝隙"?怎么解决

  • 原因(面试点)
    • img 默认是 inline 元素,会按基线对齐,基线下方留空给"下行字母"(descender)空间。
  • 解决方案
    • img { display: block; }
    • 或者父元素 line-height: 0(不推荐,影响可读性)
    • vertical-align: middle/bottom;

4.8 移动端底部安全区(iPhone 刘海屏/小白条)

  • CSS 落地
css 复制代码
.footer {
  padding-bottom: env(safe-area-inset-bottom);
}
  • 追问点
    • 除了 padding,还要做"固定底栏 + 占位",避免内容被遮挡。

4.9 滚动穿透(弹窗打开后背景还能滚)怎么处理

  • 典型场景
    • 移动端弹窗(mask)出现后,背景页面仍能滚动。
  • 工程思路
    • Web:打开弹窗时锁住 body 滚动(记录滚动位置,关闭后恢复)。
    • iOS 上对 position: fixed/滚动容器要特别小心。

4.10 清除浮动有哪些方式?为什么现在更推荐 Flex/Grid

  • 可背诵答案(60 秒版)

    • "清除浮动本质是解决 float 脱离普通文档流导致的父元素高度塌陷。常见方案有三类:
      1. 经典 clearfix 伪元素清除;
      2. 让父容器触发 BFC(比如 overflow: hidden);
      3. 更现代语义化的 display: flow-root。 但在新业务里我更倾向用 Flex/Grid 直接做布局,原因是 float 本身是为文字环绕设计的,不适合作为布局系统;Flex/Grid 更语义、更稳定、响应式更好,后期维护也不会出现各种清除浮动/塌陷的历史问题。"
  • 先把原理说清楚:为什么会"高度塌陷"

    • 浮动元素会脱离普通流,父元素计算高度时只看普通流子元素,导致:
      • 父容器高度变成 0(或只等于非浮动子元素高度)
      • 后续兄弟元素上移/覆盖
  • 方案 A:clearfix(经典方案,兼容性强)

css 复制代码
.clearfix::after {
  content: "";
  display: block;
  clear: both;
}
  • 优点

    • 兼容性极好;不依赖布局上下文;老项目常见。
  • 缺点

    • 属于"历史包袱式"的补丁写法:你得记得给父容器加类名;结构不够语义化。
  • 追问点

    • 为什么 clear: both 有效:它会让伪元素排在浮动元素下方,从而撑开父容器高度。
  • 方案 B:触发 BFC(常用但要注意副作用)

css 复制代码
.bfc {
  overflow: hidden; /* 或 auto/scroll,非 visible */
}
  • 优点

    • 一行代码解决塌陷;顺便能隔离 margin 合并等问题。
  • 缺点 / 风险

    • 可能裁剪溢出内容(比如阴影、下拉菜单、绝对定位的浮层)。
    • 如果你用 auto/scroll 可能引入滚动条。
  • 方案 C:display: flow-root(推荐写法:语义明确、无裁剪副作用)

css 复制代码
.flow-root {
  display: flow-root;
}
  • 优点

    • 直接创建新的 BFC,且不像 overflow:hidden 那样裁剪内容。
    • 可读性强:看代码就知道"这是个独立的块级格式化上下文"。
  • 缺点

    • 老旧浏览器兼容性不如 clearfix(现代项目通常没问题)。
  • 为什么现代更推荐 Flex/Grid(工程化理由)

    • 语义与目的匹配
      • float 设计初衷是"文字环绕图片",不是布局系统;拿 float 做布局会不断触发补丁需求。
    • 更少的隐式规则/坑
      • float 布局经常伴随:清除浮动、塌陷、浮动覆盖、margin 合并等问题。
      • Flex/Grid 天然是布局模型,容器与子项职责清晰。
    • 响应式更自然
      • Flex 的自适应、换行、对齐;Grid 的二维栅格与区域布局,做响应式更直观。
    • 可维护性更好
      • 代码更短、更一致;团队新人不需要背一堆历史兼容技巧。
  • 加分回答:什么时候仍然会用 float?

    • 文字环绕图片(比如富文本内容)
    • 老项目维护(不大动结构的情况下,用 clearfix/BFC 快速止血)
相关推荐
珑墨2 小时前
【迭代器】js 迭代器与可迭代对象终极详解
前端·javascript·vue.js
Fantastic_sj2 小时前
[代码例题] var 和 let 在循环中的作用域差异,以及闭包和事件循环的影响
开发语言·前端·javascript
HashTang3 小时前
【AI 编程实战】第 3 篇:后端小白也能写 API:AI 带我 1 小时搭完 Next.js 服务
前端·后端·ai编程
三年三月3 小时前
React 中 CSS Modules 详解
前端·css
JANG10243 小时前
【Linux】常用指令
linux·服务器·javascript
粉末的沉淀3 小时前
tauri:关闭窗口后最小化到托盘
前端·javascript·vue.js
赵庆明老师3 小时前
NET 使用SmtpClient 发送邮件
java·服务器·前端
绝世唐门三哥3 小时前
使用Intersection Observer js实现超出视口固定底部按钮
开发语言·前端·javascript
南山安3 小时前
Vue学习:ref响应式数据、v-指令、computed
javascript·vue.js·面试