ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

前端面试HTML与CSS核心考点:盒模型、BFC、层叠上下文与布局实战

前端面试HTML与CSS核心考点:盒模型、BFC、层叠上下文与布局实战

前端面试里有一类题特别有意思:面试官不问你框架原理,也不考算法,就盯着 HTML 和 CSS 这些"老古董"问。很多人准备面试时把大量时间花在 JS 手写题和框架源码上,结果一坐下来,对面来一句"说说 BFC 是什么,能解决什么问题",脑子瞬间空白。我自己就吃过这个亏,早年一次面试,被问到外边距合并,我支支吾吾说了半天"就是会合并",面试官追问"什么情况下不会合并",直接卡壳。后来复盘才发现,HTML 和 CSS 这块的知识点看着零散,其实背后有一套很清晰的逻辑:布局规则、层叠规则、盒模型规则,三条主线串起来,绝大多数面试题都能归到其中某一类。

这篇内容面向的是准备前端面试的朋友,不管你是刚学完三件套的新手,还是工作几年但基础有点松动的老手,都能从里面找到能直接用的东西。我会把 HTML 和 CSS 面试里出现频率最高、也最容易答砸的知识点拆开讲,重点不是背答案,而是搞清楚"为什么是这样",因为面试官真正想听的,是你对渲染规则的理解,而不是一段背诵稿。下面这些内容,都是我在实际面试、带人、以及被面试的过程中反复验证过的,尽量说人话,配可运行的例子,方便你直接拿去练。

1. 盒模型与尺寸计算:面试第一道送分题还是送命题

盒模型这个概念,几乎每场面试都会碰到,但答得好的人不多。大部分人能说出content-box和border-box的区别,再往下问"一个 div 设了 width: 200px,padding 20px,border 5px,实际占多宽",就开始犹豫了。这道题的本质,是考察你对"宽度到底算哪部分"的理解是否清晰。

1.1 标准盒模型和怪异盒模型的真实差异

先把这个说透。CSS 里盒模型分两种,标准盒模型(box-sizing: content-box,也是默认值)和怪异盒模型(box-sizing: border-box)。区别就一句话:你设置的 width 到底包不包含 padding 和 border。

标准盒模型下,width只算内容区,元素实际占据的宽度是width + padding-left + padding-right + border-left + border-right。怪异盒模型下,width已经包含了 padding 和 border,内容区宽度是width - padding - border。

拿上面那道题算一下:width: 200px,左右 padding 各 20px,左右 border 各 5px。

  • 标准盒模型:实际占宽 = 200 + 20×2 + 5×2 = 250px,内容区就是 200px。
  • 怪异盒模型:实际占宽 = 200px,内容区 = 200 - 40 - 10 = 150px。

面试时我建议你直接把这两个数字报出来,然后补一句"所以做响应式布局时我一般全局设成 border-box,这样宽度好算"。这句话很加分,因为它说明你不是死记概念,而是知道它在工程里怎么用。

提示:全局设border-box的常见写法是*, *::before, *::after { box-sizing: border-box; },注意带上伪元素,否则伪元素还是标准盒模型,容易在细节上翻车。

1.2 为什么工程里几乎都用 border-box

这个问题面试官很爱追问。答案不复杂:为了让"设多宽就是多宽"这件事成立。设想一个三栏布局,每栏width: 33.33%,如果每栏还有 10px 的 padding,标准盒模型下三栏加起来就超过 100%,直接换行。用border-box就不会有这个问题,因为 padding 被算进宽度里了。

再举个更实际的例子。做一个卡片组件,设计稿标注宽度 300px,内边距 16px,边框 1px。用标准盒模型,你得自己算width: 300 - 32 - 2 = 266px,改一次设计稿就得重算一次。用border-box,直接写width: 300px,padding 和 border 随便调,总宽度纹丝不动。这就是它成为事实标准的原因——减少心智负担,让尺寸可预测。

不过有个坑要提醒:border-box下如果 padding 加 border 超过了 width,内容区会被压成 0,元素看起来"消失"了。我见过有人设了width: 50px; padding: 30px,结果内容完全看不见,排查半天。这种情况浏览器不会报错,只会默默把内容区算成 0,所以设小尺寸元素时要留个心眼。

1.3 一道变形题:百分比宽度参照谁

面试里经常有变体,比如"一个元素width: 50%,它的百分比是相对谁算的"。答案是相对包含块的 content 区宽度,注意是 content 区,不含 padding 和 border。这一点和padding、margin的百分比规则要区分开——padding和margin的百分比,无论上下左右,都是相对包含块的宽度算的,纵向也是拿宽度算,不是高度。这个反直觉的点经常被拿来出题。

我整理了一张表,把这几个容易混的百分比参照对象列清楚:

属性百分比参照对象备注
width包含块 content 宽度不含 padding/border
height包含块 content 高度包含块高度为 auto 时行为特殊
padding(四个方向)包含块宽度纵向也按宽度算
margin(四个方向)包含块宽度纵向也按宽度算
border-width不支持百分比只能用长度值

这张表建议直接记住,面试被问到能秒答,而且能顺带展示你连纵向 padding 按宽度算这种细节都清楚,可信度一下就上来了。

2. BFC:被问烂了但依然有人答不明白

BFC 全称块级格式化上下文(Block Formatting Context),是面试高频中的高频。但我发现很多人背了一堆"能清除浮动、能阻止外边距合并",却说不清它到底是什么。这就像知道药能治病,但不知道病理,换个问法就露馅。

2.1 用"独立容器"的类比理解 BFC

我的理解方式是这样的:BFC 就是页面上一个独立的渲染区域,里面的元素怎么排布,跟外面互不干扰。你可以把它想象成一个密封的盒子,盒子内部的布局规则自成一套,盒子外部的元素也别想影响里面。

从规范角度说,BFC 是一个块级盒子,它内部的块级盒子会在垂直方向上一个接一个地排列,垂直方向的距离由 margin 决定,同一个 BFC 内相邻块级盒子的 margin 会发生合并。关键在于"同一个 BFC 内"这几个字,理解了它,后面所有应用场景都能推出来。

那怎么触发 BFC?常见的方式有这么几种:

  • 根元素html本身就是一个 BFC;
  • float值不为none;
  • position为absolute或fixed;
  • display为inline-block、table-cell、flex、grid等;
  • overflow不为visible(比如hidden、auto、scroll)。

面试时能报出三四种就够了,但如果你能补一句"display: flow-root是专门为创建 BFC 设计的,没有副作用",面试官大概率会对你刮目相看。因为overflow: hidden虽然能触发 BFC,但它会裁剪溢出内容,还可能影响滚动,而flow-root就是干净地创建一个 BFC,不带来额外副作用。

2.2 三个经典应用场景的推导过程

光背"BFC 能干嘛"没用,得会推。我把三个最常考的场景拆开讲。

场景一:清除浮动。父元素里的子元素全部浮动后,父元素高度塌陷,因为浮动元素脱离了普通流,父元素"看不见"它们。给父元素触发 BFC 后,BFC 在计算高度时会把浮动子元素也算进去,高度就撑开了。推导逻辑是:BFC 的规则之一是"计算 BFC 高度时,浮动元素也参与计算"。

场景二:阻止外边距合并。两个相邻的兄弟元素,上面的margin-bottom: 30px,下面的margin-top: 20px,实际间距是 30px 而不是 50px,取较大值。这是因为它们在同一个 BFC 里。把其中一个包进新的 BFC,两者就不在同一个 BFC 了,margin 不再合并,间距变成 50px。父子元素之间的 margin 合并同理,给父元素触发 BFC 就能隔断。

场景三:阻止元素被浮动元素覆盖。一个浮动元素后面跟一个普通块级元素,普通元素会"无视"浮动元素,跑到它下面去,文字却会环绕。给普通元素触发 BFC,它就会避开浮动元素,形成类似两栏布局的效果。这个场景在做自适应布局时很实用。

我把这三个场景的触发方式和效果整理成表,方便对照记忆:

场景问题表现触发 BFC 后的效果原理
清除浮动父元素高度塌陷父元素高度被撑开BFC 高度计算包含浮动元素
阻止 margin 合并相邻 margin 取较大值margin 正常叠加不同 BFC 间不合并
避免浮动覆盖块级元素被浮动元素压住块级元素避开浮动BFC 不与浮动元素重叠

2.3 面试官追问"overflow: hidden 有什么副作用"怎么答

这是道进阶题,答好了能拉开差距。overflow: hidden触发 BFC 的同时,会带来几个副作用:一是裁剪溢出内容,如果子元素有超出父元素的部分(比如下拉菜单、tooltip),会被直接切掉;二是可能影响滚动,在某些场景下会阻止页面滚动或产生意外的滚动条;三是在移动端可能引发性能问题,因为overflow: hidden有时会触发额外的合成层。

所以我的建议是:能用flow-root就用flow-root,兼容性现在也够了。如果必须用overflow: hidden,要确认父元素内部没有需要溢出的内容。这个细节在面试里说出来,比单纯背"overflow: hidden 能清除浮动"高一个层次。

3. 层叠上下文与 z-index:为什么你的弹窗总被盖住

z-index 失效是前端开发里最常见的 bug 之一,也是面试爱考的点。很多人以为"z-index 数值大的就在上面",结果设了z-index: 9999还是被盖住,一脸懵。问题的根源在于:z-index 只在同一个层叠上下文里比较才有意义。

3.1 层叠上下文的形成条件

层叠上下文(stacking context)是 HTML 元素三维空间里的一个概念,可以理解成一个"图层"。同一个层叠上下文里,元素的层叠顺序由 z-index 和文档顺序决定;不同层叠上下文之间,先比较它们所属的上下文,再往下比。

形成层叠上下文的条件比 BFC 多一些,常见的有:

  • 根元素html;
  • position为absolute或relative且z-index不为auto;
  • position为fixed或sticky(现代浏览器里 sticky 也会形成);
  • flex或grid容器的子元素且z-index不为auto;
  • opacity小于 1;
  • transform、filter、perspective不为none;
  • will-change指定了上述属性;
  • isolation: isolate。

这里有个特别容易踩的坑:给元素加了transform或opacity,它会自动形成层叠上下文,哪怕你没设 z-index。我见过一个案例,一个弹窗组件为了做动画加了transform: translateY(0),结果弹窗的 z-index 再大也盖不住某个父级容器,因为那个父级容器形成了层叠上下文,弹窗被困在里面了。

3.2 一个真实的 z-index 失效排查过程

说个我实际遇到的场景。页面上有个固定定位的侧边栏,z-index: 100,还有个弹窗z-index: 1000,按理说弹窗应该在上面,但实际弹窗被侧边栏盖住了。排查过程是这样的:

第一步,看两者的 DOM 结构。发现弹窗和侧边栏不在同一个父级下,弹窗的父级是一个position: relative且z-index: 10的容器,侧边栏的父级是body直接子元素。

第二步,分析层叠上下文。弹窗的父容器因为position: relative加z-index: 10形成了层叠上下文,弹窗的z-index: 1000只在这个上下文内部有效。而侧边栏的z-index: 100是在根上下文里比较的。比较的是弹窗父容器的z-index: 10和侧边栏的z-index: 100,10 小于 100,所以整个弹窗容器被压在侧边栏下面,弹窗自己的 1000 根本没用。

第三步,解决方案。要么把弹窗挂到body下(用 Portal 的思路),要么把弹窗父容器的 z-index 提到 100 以上。实际项目里更推荐前者,因为弹窗本来就该脱离父级的层叠约束。

这个排查过程的核心思路是:z-index 失效时,不要盯着失效元素本身,要往上找它所在的层叠上下文,比较的是上下文之间的层级。这个思路面试时讲出来,比背概念有说服力得多。

3.3 层叠顺序的七层规则

同一个层叠上下文内,元素的绘制顺序是有明确规则的,从下到上大致是:

  1. 层叠上下文的背景和边框;
  2. z-index为负的定位元素;
  3. 块级盒子的背景和边框(普通流);
  4. 浮动元素;
  5. 行内盒子的内容(文字、图片等);
  6. z-index: auto或z-index: 0的定位元素;
  7. z-index为正的定位元素。

这个顺序解释了为什么"文字总能盖住背景"——行内内容在第 5 层,普通块级背景在第 3 层。也解释了为什么负 z-index 的元素会跑到父元素背景下面。面试时如果能把这几层说清楚,基本可以确定你对层叠的理解是扎实的。

4. 定位与文档流:position 的五个值到底怎么选

position 是 CSS 布局的基础,但面试里经常问得很细,比如"absolute 相对谁定位""fixed 和 sticky 的区别""relative 不设偏移量有什么用"。这些问题看着简单,答全不容易。

4.1 五个定位值的定位基准

先把基准说清楚,这是最容易混的地方:

  • static:默认值,元素在普通流里,top/right/bottom/left和z-index都不生效。
  • relative:相对自身原来的位置偏移,元素原本占据的空间保留,不影响其他元素布局。
  • absolute:相对最近的非 static 定位的祖先元素偏移,找不到就相对初始包含块(可以理解为视口或 html)。元素脱离文档流,不占空间。
  • fixed:相对视口偏移,滚动页面时位置不变。元素脱离文档流。
  • sticky:在跨越特定阈值前表现为relative,之后表现为fixed,常用于吸顶效果。

这里有个高频追问:"absolute的包含块到底怎么确定?"准确说法是:从元素自身往上找,找到第一个position不为static的祖先,这个祖先的padding 盒就是包含块。注意是 padding 盒,不是 content 盒,这个细节很多人不知道。如果一直找到根元素都没有,包含块就是初始包含块。

4.2 relative 不设偏移量的隐藏用途

面试官问"relative不设 top/left 有什么用",其实是在考你对层叠和定位上下文的理解。答案是:它可以作为 absolute 子元素的定位参照,同时可以通过设 z-index 提升层级。很多布局里,父元素设position: relative但不设偏移,纯粹是为了给里面的 absolute 元素当锚点。

还有一个用途是限制 z-index 的作用范围。前面讲层叠上下文时提到,position: relative加z-index会形成层叠上下文,可以用来把子元素的层级"锁"在一个范围内,避免子元素的高 z-index 影响到外部。这个用法在组件化开发里很有价值。

4.3 sticky 失效的常见原因

sticky是这几个值里最容易"看起来没生效"的。我总结了几条常见原因:

  • 没有设置阈值:sticky必须配合top、bottom、left、right中的至少一个,否则它跟relative没区别。
  • 父元素高度不够:sticky元素只能在父元素的高度范围内粘住,父元素太矮,粘一下就到底了。
  • 祖先元素有overflow: hidden/auto/scroll:这是最常见的坑。只要祖先链上有元素的 overflow 不是 visible,sticky就会失效,因为滚动容器变了。
  • 父元素是 flex 布局且没设高度:flex 容器的默认align-items: stretch可能让 sticky 元素被拉伸,影响粘性行为。

排查 sticky 失效,我的经验是先看祖先链的 overflow,再看父元素高度,最后看阈值设置,按这个顺序基本能定位到问题。

5. 选择器与优先级:权重计算背后的规则

CSS 选择器优先级是笔试和面试的常客,给一段 CSS 让你判断哪个样式生效。这类题不难,但规则要记准,尤其是!important、行内样式、伪类这些容易混的点。

5.1 优先级的四元组计算法

我习惯用四元组(a, b, c, d)来算优先级,比"千位百位十位"的说法更不容易出错:

  • a:行内样式,记为 1,否则 0;
  • b:ID 选择器的个数;
  • c:类选择器、属性选择器、伪类的个数;
  • d:元素选择器、伪元素的个数。

比较时从左到右逐位比较,a大的赢,a相同比b,以此类推。注意!important不参与这个计算,它是单独的最高优先级(除了动画和过渡)。

举个例子:#nav .item a:hover的优先级是(0, 1, 2, 1)——1 个 ID,2 个类/伪类(.item和:hover),1 个元素(a)。而div#nav a是(0, 1, 0, 2)。前者 b 相同,c 是 2 大于 0,所以前者赢。

注意:*通配符、组合符(>、+、~、空格)不贡献优先级。:not()本身不贡献,但括号里的选择器要算。这些细节笔试里经常挖坑。

5.2 那些容易算错的选择器

有几个选择器的优先级容易出错,我单独拎出来说:

  • :not(.foo):算.foo的优先级,即一个类。
  • :is(.foo, #bar):取括号里最高的优先级,即一个 ID。
  • :where(.foo):优先级恒为 0,这是它和:is的核心区别,适合写低优先级的样式重置。
  • 属性选择器[type="text"]:算一个类。
  • 伪元素::before:算一个元素。

:where()这个特性在实际项目里很有用,比如写基础样式库时,用:where()包裹可以保证优先级最低,方便使用者覆盖。面试时提到这个,能体现你关注新特性。

5.3 优先级相同怎么办

如果两个选择器优先级完全相同,后出现的生效,这就是"后来居上"原则。这个规则在覆盖第三方样式时经常用到,但要注意 CSS 的加载顺序,有时候样式没生效不是优先级问题,而是加载顺序问题。

还有一种情况是继承。继承来的样式优先级最低,比任何直接选中的样式都低。比如给body设了color: red,子元素自己设了color: blue,子元素显示蓝色,因为直接选中的优先级高于继承。这个点面试也爱问,尤其是问"为什么给 body 设字体颜色,某些元素不生效"——因为那些元素有浏览器默认样式或者被其他规则选中了。

6. 垂直居中与布局方案:从老办法到现代方案

垂直居中是 CSS 面试的经典题,面试官想看的不是你背了几种方法,而是你知不知道每种方法的适用场景和局限。我按"老到新"的顺序梳理,每种都说清楚什么时候用。

6.1 绝对定位加负 margin 的老方案

这是最经典的方案:父元素position: relative,子元素position: absolute; top: 50%; left: 50%; margin-top: -高度一半; margin-left: -宽度一半。原理是把子元素的左上角移到父元素中心,再用负 margin 往回拉一半自身尺寸。

这个方案的局限很明显:必须知道子元素的具体宽高,否则负 margin 没法算。所以它只适合尺寸固定的元素,比如固定大小的图标、弹窗。现在基本被transform方案取代了。

6.2 transform 方案的适用边界

transform: translate(-50%, -50%)解决了不知道尺寸的问题,因为百分比是相对元素自身尺寸算的。写法是父元素position: relative,子元素position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%)。

这个方案兼容性好,用得很广,但有个副作用:transform会形成层叠上下文,前面讲 z-index 时提过。如果子元素里有需要溢出或者高 z-index 的内容,可能会受影响。另外transform在某些场景下会影响文字渲染的清晰度,虽然现代浏览器已经优化得不错了。

6.3 flex 和 grid 的现代方案

现在做垂直居中,首选flex:

.parent { display: flex; align-items: center; justify-content: center; }

两行搞定,不用管子元素尺寸,也没有层叠上下文的副作用。grid更简洁:

.parent { display: grid; place-items: center; }

place-items: center是align-items和justify-items的简写,一行搞定水平和垂直居中。如果只关心垂直方向,align-items: center配合块级子元素就够了。

我把几种方案对比一下:

方案是否需要知道尺寸副作用适用场景
absolute + 负 margin需要无尺寸固定的元素
absolute + transform不需要形成层叠上下文兼容性要求高的场景
flex不需要无现代项目首选
grid不需要无简单居中,代码最少

面试时我的建议是:先答 flex,再补充其他方案和各自局限,这样既展示了你跟得上现代写法,又说明你理解历史方案的取舍。

6.4 单行和多行文本居中的区别

文本居中是个细分场景,面试偶尔会问。单行文本垂直居中,用line-height等于容器高度就行,简单粗暴。多行文本就不行了,得用flex或者table-cell,或者用padding上下对称撑开。这里有个坑:line-height设太大,单行文本会偏下,因为行高是围绕文字基线分布的,不是纯几何居中。所以精确居中还是推荐 flex。

7. 响应式与媒体查询:断点设计的实战考量

响应式布局是前端必备技能,面试里常问"怎么做响应式""媒体查询的断点怎么定"。这部分我结合实际项目经验说,因为纯理论答不出彩。

7.1 媒体查询的写法与优先级

媒体查询的基本写法是@media (min-width: 768px) { ... },表示视口宽度大于等于 768px 时生效。这里有个容易混的点:min-width和max-width的方向。min-width是"至少这么宽",从小到大写,适合移动优先;max-width是"最多这么宽",从大到小写,适合桌面优先。

移动优先的写法是默认样式写小屏,然后用min-width逐级增强:

/* 默认:移动端 */ .container { padding: 10px; } @media (min-width: 768px) { .container { padding: 20px; } } @media (min-width: 1200px) { .container { padding: 30px; } }

这种写法好处是样式覆盖关系清晰,后写的规则自然覆盖前面的,不用纠结优先级。桌面优先则反过来用max-width,从大到小写。两种都行,但团队里要统一,混着写容易出 bug。

7.2 断点到底怎么定

面试官问断点,其实想看你有没有实际经验。我的答案是:断点跟着设计稿和内容走,不要照搬框架的默认值。Bootstrap 那套 576/768/992/1200 是通用参考,但实际项目里,断点应该设在"布局开始变得难看"的地方。

具体做法是:把浏览器窗口从宽到窄慢慢拖,观察布局在哪个宽度开始出问题(文字换行难看、元素挤在一起、出现横向滚动条),那个宽度就是断点。这样定出来的断点是为内容服务的,比拍脑袋定数字靠谱。

另外要提醒的是,断点不要太多。我见过一个项目设了七八个断点,维护起来简直是灾难。一般三到四个断点足够覆盖手机、平板、小屏桌面、大屏桌面。断点越多,测试成本越高,出 bug 的概率也越大。

7.3 视口单位与响应式的配合

除了媒体查询,视口单位(vw、vh、vmin、vmax)也是响应式的常用工具。1vw等于视口宽度的 1%,用它做字号或者间距,能实现平滑缩放。但要注意vw在移动端有个坑:它包含滚动条宽度,可能导致横向溢出。解决办法是用100%或者配合calc()减去滚动条宽度。

vh在移动端更坑,因为移动浏览器的地址栏收起展开会改变视口高度,导致100vh的元素高度跳动。现在有dvh(动态视口高度)可以解决,但兼容性要考虑。面试时提到这些坑,能说明你真的在移动端项目里踩过。

8. 语义化与可访问性:容易被忽视的加分项

HTML 语义化是面试里"送分但少有人答好"的题。很多人觉得语义化就是"用对标签",但说不清为什么要用、用了有什么好处。这部分我结合可访问性讲,因为两者是绑在一起的。

8.1 语义化标签的实际价值

语义化的核心价值有三个:对开发者可读、对搜索引擎友好、对辅助设备友好。前两个大家都知道,第三个是重点。屏幕阅读器依赖语义标签来理解页面结构,你用一堆div堆出来的页面,屏幕阅读器读起来就是一团乱麻,视障用户根本没法用。

具体到标签选择:导航用<nav>,主内容用<main>,独立文章用<article>,侧边栏用<aside>,页脚用<footer>。这些标签不只是"看起来语义化",它们还自带 ARIA 角色,浏览器和辅助设备能直接识别。比如<nav>自带role="navigation",<main>自带role="main"。

有个细节要注意:一个页面只应该有一个<main>,因为它是主内容区,多个会让辅助设备困惑。<article>可以多个,每个代表一篇独立内容。

8.2 表单可访问性的几个必做项

表单是面试里常考的可访问性场景。几个必做项:

  • 每个输入框都要有<label>,用for属性关联id,或者把 input 包在 label 里。这样点击文字也能聚焦输入框,屏幕阅读器也能读出字段含义。
  • 用aria-label给没有可见文字的按钮加描述,比如图标按钮。
  • 错误提示要用aria-describedby关联到输入框,让屏幕阅读器能读到。
  • 必填字段用required属性,不要只靠星号视觉提示。

这些细节面试时说出来,能体现你的工程素养。很多团队做项目根本不考虑可访问性,你能主动提,是加分项。

8.3 图片 alt 的写法

alt属性是面试里的小考点。规则是:有意义的图片写描述,纯装饰图片写空 alt。比如商品图写"红色连衣裙正面图",而背景装饰图写alt=""。空 alt 不是省略 alt,省略 alt 会让屏幕阅读器读出文件名,反而更糟。

还有一点,alt不要写"图片""图像"这种废话,直接描述内容。如果图片是链接,alt要描述链接目标,而不是图片本身。

9. 那些年我踩过的 CSS 坑与面试应对

最后这部分,分享几个我在实际项目和面试里踩过的坑,都是那种"文档里不写、踩过才知道"的经验。

9.1 margin 塌陷的连锁反应

margin 塌陷(合并)不只是相邻兄弟之间,父子之间也会。父元素没有 border、padding、inline 内容时,子元素的margin-top会"穿透"到父元素外面,表现为父元素整体下移。这个坑在写卡片列表时特别常见,明明给子元素设了 margin,结果整个卡片往下跑。

解决办法有三个:给父元素加overflow: hidden(触发 BFC)、加padding-top或border-top、或者用display: flow-root。我一般用最后一个,干净。面试时如果被问到 margin 合并,主动提父子合并这个场景,能体现你踩过坑。

9.2 行内元素的垂直 margin 不生效

span、a这类行内元素,设margin-top和margin-bottom是不生效的,只有左右 margin 有效。原因是行内元素的垂直方向由line-height和vertical-align控制,不参与 margin 计算。要让它生效,得改成inline-block或block。这个点笔试常考,问"为什么给 span 设了 margin-top 没反应"。

9.3 面试被问住时的应对策略

最后说个软技能。面试时遇到不会的 CSS 题,千万别硬编。我的做法是:先说出你知道的部分,再坦诚说不确定的部分,最后给出你的推测方向。比如被问到某个冷门属性,你可以说"这个属性我没在实际项目里用过,但根据命名和 CSS 的一般规则,我猜它是……如果是我,我会去 MDN 查一下确认"。这种回答比胡编强得多,面试官看重的是你的思考方式,不是你背了多少冷知识。

还有个小技巧:遇到开放性问题,主动往你熟悉的领域引。比如问"你怎么做响应式",你可以从媒体查询讲到容器查询(@container),再讲到你项目里怎么用clamp()做流式字号。把话题引到你准备充分的地方,主动权就在你手里。

9.4 容器查询:值得提前了解的新特性

说到容器查询,这是响应式的新方向,面试里偶尔会被问到。媒体查询是相对视口,容器查询是相对父容器。写法是给父元素设container-type: inline-size,然后子元素用@container (min-width: 400px) { ... }。它的价值在于组件级响应式——同一个卡片组件,放在侧边栏窄容器里和放在主内容宽容器里,可以呈现不同布局,而不用关心视口多宽。

这个特性现在主流浏览器都支持了,实际项目里用来做组件库很合适。面试时能提到它,说明你在关注 CSS 的新发展,不是只守着老知识。

9.5 一份可以照着练的复习清单

最后给一份清单,按优先级排,面试前照着过一遍:

优先级知识点掌握标准
高盒模型与 box-sizing能算实际占宽,说清工程选择理由
高BFC 触发条件与三个应用能推导,不靠背
高层叠上下文与 z-index能排查 z-index 失效
高position 五个值说清定位基准和文档流影响
中选择器优先级能算四元组,知道 :where 特性
中垂直居中方案能对比各方案局限
中响应式与断点能说清断点设计思路
低语义化与可访问性知道常用标签和表单要点
低容器查询等新特性了解概念和基本写法

这份清单不是让你全背下来,而是帮你查漏补缺。真正面试时,能把高优先级的几条讲透,配合实际项目里的例子,基本就稳了。CSS 这东西,知识点是死的,但怎么组织、怎么结合实际讲,才是拉开差距的地方。我自己带过几个新人,发现他们最大的问题不是不知道,而是知道得零散,串不起来。希望这篇能把那些散落的知识点帮你串成线。

返回列表