概览
面试一句话总结:CSS 基础面试中最常考的“三座大山”是:盒模型、选择器优先级 和 BFC(块级格式化上下文)。而在手写题中,Flex 居中和两栏/三栏布局则是必考项。
盒模型 (Box Model)
浏览器在页面上排布元素时,会将每个元素表示为一个矩形的盒子。盒模型由内到外分为:content (内容) -> padding (内边距) -> border (边框) -> margin (外边距)。
面试高频考点:标准盒模型 vs IE 盒模型(怪异盒模型)
- 标准盒模型 (
box-sizing: content-box):元素的width和height只包含 content。实际占据空间的宽度 = width + padding + border + margin。 - IE 盒模型 (
box-sizing: border-box):元素的width和height包含了 content + padding + border。这是目前前端开发最推荐的配置,因为它能保证你设置的 width 就是元素肉眼可见的真实宽度,不会被 padding 撑大。
常见 CSS 单位解析
在面试中,往往会考察你对不同尺寸单位的理解和应用场景:
px(像素):绝对单位。页面按精确像素展示,但在移动端可能会因为屏幕 dpr 不同导致物理像素显示差异。em:相对单位。相对于父元素的字体大小。如果父元素font-size: 16px,则1em = 16px。常用于首行缩进(text-indent: 2em)。rem:相对单位。相对于根元素 (<html>) 的字体大小。移动端适配的经典方案,能保证全局统一缩放。vw/vh:视口单位。1vw等于视口宽度的1%。目前移动端适配最推荐的现代标准方案。%(百分比):相对单位。通常相对于父元素的相应属性(注意:margin-top和padding-top的百分比也是相对于父元素的宽度,而不是高度!这是一个极高频的面试坑点)。
选择器与优先级 (Specificity)
CSS 的样式覆盖规则是基于优先级的。面试官经常会出几道题让你算最终生效的颜色。
权重计算规则(从高到低):
!important:拥有最高优先级(属于神仙打架,业务中尽量少用)。- 内联样式 (Inline style):权重 1000。
- ID 选择器 (
#id):权重 100。 - 类、伪类、属性选择器 (
.class,:hover,[type="text"]):权重 10。 - 标签、伪元素选择器 (
div,::before):权重 1。 - 通配符、子选择器、相邻选择器等 (
*,>,+):权重 0。
(注:权重的数字只是一种比喻,实际上低级别的选择器就算写 10 个,也永远无法超过 1 个高级别的选择器。)
层叠上下文 (Stacking Context)
为什么有时候设置了 z-index: 9999 还是被别的元素盖住了?这就是层叠上下文搞的鬼。
层叠上下文是 HTML 元素的三维概念,它规定了元素在 Z 轴上的层叠顺序。
触发条件(如何产生一个新的层叠上下文):
- 根元素 HTML(默认产生)。
position: absolute或relative且z-index值不为auto的元素。position: fixed或sticky的元素。- CSS3 新属性:如
transform、opacity(小于1)、filter等只要不为默认值的元素,哪怕没有 z-index,也会自动创建一个新的层叠上下文!
核心原则:如果在同一个层叠上下文中,z-index 大的在上面;如果不在同一个层叠上下文中,谁的父元素的层叠等级高,谁就在上面(拼爹原则)。
BFC (块级格式化上下文)
块级格式化上下文,它是一个独立的渲染区域,让处于 BFC 内部的元素和外部的元素相互隔离,使内外元素的定位不会相互影响。body、根元素 html 都符合 BFC
特性:
- 在页面上是一个独立的容器,外面的元素和里面的元素互不影响
- BFC 元素不会和浮动的元素重叠
- 计算 BFC 元素的高度时,里面浮动元素的高度也会参与计算
触发 BFC 特性的条件:
- float:除 none 以外的值
- position:(absolute、fixed)
- display: inline-block、table-cells、flex
- overflow:除了 visible 以外的值 (hidden、auto、scroll)
常用:display: inline-block 或 overflow:hidden。但是 overflow: visible 这一个条件并不适用于 body 元素,具体原因可参考这个问题下的采纳回答:重提 CSS 中外边距折叠问题
应用:
- 父子 margin 塌陷和 margin 垂直合并
- 清除内部浮动
- 实现两栏适应布局
定位
position
- static。默认,元素会在普通文档流上
- relative。相对自身位置定位
- absolute。以最近的非 static 父级元素作为参考进行定位。元素会脱离普通文档流
- fixed。以浏览器窗口作为参考进行定位,当父元素使用了 transform,会以父元素定位
- sticky。粘性定位 relative + fixed
浮动 float
- 元素会脱离普通文档流,会有文字环绕
display
可以控制元素状态和布局,常见 block/none/inline/inline-block/flex/grid/...
常见布局 (面试高频手写题)
1. 水平垂直居中
这是前端面试最经典的 CSS 手写题,必须掌握以下三种主流方案:
方案一:Flex 布局 (现代首选,最推荐)
.parent {
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
}
方案二:绝对定位 + transform (适用于未知宽高的子元素)
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
方案三:绝对定位 + margin: auto (适用于已知宽高的子元素)
.parent {
position: relative;
}
.child {
width: 100px;
height: 100px;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
2. 双栏布局 / 左定宽右自适应
Flex 方案:
.container {
display: flex;
}
.left {
width: 200px;
}
.right {
flex: 1;
} /* 占据剩余全部空间 */
3. 圣杯布局 & 双飞翼布局
(这两者都是解决:左右两边定宽,中间自适应,且中间内容优先渲染。但在现代 Flex 普及后,这两种布局在业务中已较少手写,多作为考察基础原理的八股文。)
- 圣杯布局:父元素设置 padding 留出左右空间,左右两边使用
float+ 负margin+position: relative移动到两侧。 - 双飞翼布局:中间内容再套一层子
div设置 margin 留出左右空间,左右两边同样使用float+ 负margin移动。
参考
Flex
flex 布局默认特性:
- 把所有子项变成水平排列
- 默认不自动换行
- 让子项与其内容等宽,并把所有子项的高度变为最高子项的高度
flex 是 flex-grow, flex-shrink 和 flex-basis 的简写,默认值为 0 1 auto,意思是项目默认有剩余空间也不放大(0),但空间不足会缩小(1)
子元素设置 flex: 1 等同于:flex: 1 1 0%
flex-basic 和 width 的区别
参考 https://renjianzhide.com/archives/flex-basis-width
一些问题
清除浮动
- 父元素设置为 BFC,清除内部浮动;或者父元素设置定高
- 追加伪元素
.clearfix::after {
content: "";
display: block;
height: 0;
clear: both;
}
几种隐藏元素的对比
display: none。会发生回流,不会占据空间,不能点击;子孙结点会消失visibility: hidden。继续占据空间,不能点击;子孙结点会消失,但是可以通过设置让子孙结点显示;读屏器会读取opacity: 0。继续占据空间,可以点击;子孙结点会消失