
前端小魔女
2023/02/23阅读:26主题:蔷薇紫
2023面试真题之CSS篇
❝恐惧就是这样,你直视它、向前一步的时候它就消失了,选择相信自己能克服一切困难,勇敢向前,直面恐惧,就会发现之前的害怕,变成了心里的能量。
❞
大家好,我是「柒八九」。
今天,我们继续「2023前端面试真题」系列。我们来谈谈关于「CSS」的相关知识点。
如果,想了解该系列的文章,可以参考我们已经发布的文章。如下是往期文章。
文章list
你能所学到的知识点
❝❞
盒模型 「推荐阅读指数」⭐️⭐️⭐️⭐️ CSS的display属性有哪些值 「推荐阅读指数」⭐️⭐️⭐️⭐️ position 里面的属性有哪些 「推荐阅读指数」⭐️⭐️⭐️⭐️ flex里面的属性 「推荐阅读指数」⭐️⭐️⭐️⭐️⭐️ flex布局的应用场景 「推荐阅读指数」⭐️⭐️⭐️⭐️ CSS的长度单位有哪些 「推荐阅读指数」⭐️⭐️⭐️⭐️ 水平垂直居中 「推荐阅读指数」⭐️⭐️⭐️⭐️⭐️ 块级格式化上下文 「推荐阅读指数」⭐️⭐️⭐️⭐️⭐️ 层叠规则 「推荐阅读指数」⭐️⭐️⭐️⭐️⭐️ 重绘和重排 「推荐阅读指数」⭐️⭐️⭐️⭐️⭐️ CSS引入方式(4种) 「推荐阅读指数」⭐️⭐️⭐️⭐️ 硬件加速 「推荐阅读指数」⭐️⭐️⭐️⭐️⭐️ 元素超出宽度...处理 「推荐阅读指数」⭐️⭐️⭐️⭐️⭐️ 元素隐藏 「推荐阅读指数」⭐️⭐️⭐️⭐️⭐️ Chrome支持小于12px 的文字 「推荐阅读指数」⭐️⭐️⭐️⭐️
好了,天不早了,干点正事哇。
盒模型
一个盒子由四个部分组成:content
、padding
、border
、margin
-
content
,即实际内容,显示文本和图像-
content
属性大都是用在::before/::after
这两个「伪元素」中
-
-
padding
,即内边距,内容周围的区域-
内边距是「透明」的 -
取值「不能为负」 -
受盒子的 background
属性影响 -
padding
「百分比值」无论是水平还是垂直方向均是「相对于宽度计算」
-
-
boreder
,即边框,围绕元素内容的内边距的一条或多条线,由粗细、样式、颜色三部分组成 -
margin
,即外边距,在元素外创建「额外的空白」,空白通常指不能放其他元素的区域

标准盒模型

-
盒子「总宽度」 =
width
+padding
+border
+margin
; -
盒子「总高度」 =
height
+padding
+border
+margin
也就是,width/height
只是内容宽高,不包含 padding
和 border
值
IE 怪异盒子模型

-
盒子「总宽度」 =
width
+margin
; -
盒子「总高度」 =
height
+margin
;
也就是,width/height
包含了 padding
和 border
值
更改盒模型
CSS 中的 box-sizing
属性定义了「渲染引擎」应该如何计算一个元素的「总宽度和总高度」
box-sizing: content-box|border-box
-
content-box
(「默认值」),元素的width/height
不包含padding
,border
,与标准盒子模型表现一致 -
border-box
元素的width/height
包含padding
,border
,与怪异盒子模型表现一致
CSS的display属性有哪些值
❝CSS
❞display
属性设置元素是否被视为「块」或者「内联元素」以及用于「子元素的布局」,例如流式布局
、网格布局
或弹性布局
。
形式上,display
属性设置元素的「内部」和「外部」的显示类型。
-
外部类型设置元素参与流式布局; -
内部类型设置子元素的布局(子元素的 格式化上下文
)
常见属性值(8个)
-
inline
:默认 -
block
-
inline-block
-
flex
-
grid
-
table
-
list-item
-
「双值」的:只有 Firefox70
支持了这一语法
position 里面的属性有哪些
❝定义和用法:
position
属性规定元素的定位类型。
说明:这个属性定义建立元素布局所用的 「定位机制」 。❞
任何元素都可以定位 「绝对或固定元素会生成一个块级框」,而不论该元素本身是什么类型。 「相对定位元素」会相对于它在正常流中的「默认位置」偏移。
position
有以下可选值:(6个)

❝CSS 有三种基本的定位机制:「普通流」、「浮动」和「绝对定位」。
❞
flex里面的属性
容器的属性 (6个)
-
flex-direction
-
决定「主轴的方向」(即项目的排列方向) -
row
(「默认值」):主轴为水平方向,起点在左端。 -
row-reverse
:主轴为水平方向,起点在右端。 -
column
:主轴为垂直方向,起点在上沿。 -
column-reverse
:主轴为垂直方向,起点在下沿。
-
-
flex-wrap
-
flex-wrap
属性定义,如果一条轴线排不下,如何换行 -
nowrap
:(「默认」):不换行。 -
wrap
:换行,第一行在上方。 -
wrap-reverse
:换行,第一行在下方
-
-
flex-flow
-
flex-flow
属性是flex-direction
属性和flex-wrap
属性的「简写形式」,默认值为row nowrap
。
-
-
justify-content
-
justify-content
属性定义了项目在主轴上的对齐方式。 -
flex-start
(「默认值」):左对齐 -
flex-end
:右对齐 -
center
: 居中 -
space-between
:「两端对齐」,项目之间的间隔都相等。 -
space-around
:每个项目两侧的间隔相等。所以,「项目之间的间隔比项目与边框的间隔大一倍」。
-
-
align-items
-
align-items
属性定义项目在交叉轴上如何对齐。 -
stretch
(「默认值」):如果项目未设置高度或设为auto
,将「占满整个容器的高度」。 -
flex-start
:交叉轴的起点对齐。 -
flex-end
:交叉轴的终点对齐。 -
center
:交叉轴的中点对齐。 -
baseline
: 项目的第一行文字的基线对齐。
-
-
align-content
-
align-content
属性定义了「多根轴线的对齐方式」。 -
如果项目只有一根轴线,该属性不起作用。
-
项目的属性(6个)
-
order
-
order
属性定义项目的排列顺序。 -
「数值越小,排列越靠前,默认为0」。
-
-
flex-grow
-
flex-grow
属性定义项目的「放大比例」 -
默认为0,即如果存在剩余空间,也不放大 -
如果所有项目的 flex-grow
属性都为1,则它们将等分剩余空间(如果有的话)
-
-
flex-shrink
-
flex-shrink
属性定义了项目的「缩小比例」, -
默认为1,即如果空间不足,该项目将缩小。 -
如果所有项目的 flex-shrink
属性都为1,当空间不足时,都将「等比例缩小」
-
-
flex-basis
-
flex-basis
属性定义了在「分配多余空间之前」,项目占据的主轴空间。 -
浏览器根据这个属性,计算主轴是否有多余空间。 -
它的默认值为auto,即项目的本来大小。
-
-
flex
-
flex
属性是flex-grow
,flex-shrink
和flex-basis
的简写,「默认值为0 1 auto」。「后两个属性可选」。 -
「 flex: 1
=flex: 1 1 0%
」 -
flex: auto
=flex: 1 1 auto
-
-
align-self
flex:1
vs flex:auto
❝❞
flex:1
和flex:auto
的区别,可以归结于flex-basis:0
和flex-basis:auto
的区别
当设置为0时(「绝对弹性元素」),此时相当于告诉flex-grow
和flex-shrink
在伸缩的时候不需要考虑我的尺寸
当设置为auto
时(「相对弹性元素」),此时则需要在伸缩时将元素尺寸纳入考虑
flex布局的应用场景
-
网格布局
-
Grid- display:flex
-
Grid-Cell - flex: 1
;flex:1
使得各个子元素可以「等比伸缩」,flex: 1 = flex: 1 1 0%
-
-
百分比布局
-
-
col2 - flex: 0 0 50%
; -
col3 - flex: 0 0 33.3%;
-
-
-
圣杯布局
-
页面「从上到下」,分成三个部分:头部( header
),躯干(body
),尾部(footer
)。其中「躯干」又水平分成三栏,「从左到右」为:导航、主栏、副栏 -
-
container
-display: flex
; -flex-direction: column;
-min-height: 100vh
; -
header/footer
-flex: 0 0 100px;
-
body
-display: flex;
-flex:1
-
content
-flex: 1;
-
ads/av
-flex: 0 0 100px;
-
nav
-order: -1;
-
-
-
「侧边固定宽度」
-
侧边固定宽度,右边自适应 -
-
aside1
-flex: 0 0 20%;
-
body1
-flex:1
-
-
「流式布局」
-
每行的项目数固定,会自动分行 -
-
container2
-display: flex;
-flex-flow: row wrap;
-
-
CSS的长度单位有哪些
-
「相对长度」
-
相对长度单位指的是这个单位没有一个固定的值,它的值受到其它元素属性(例如「浏览器窗口」的大小、「父级元素」的大小)的影响,在响应式布局方面相对长度单位非常适用 -
-
-
「绝对长度」
-
绝对长度单位表示一个「真实的物理尺寸」,它的大小是固定的,不会因为其它元素尺寸的变化而变化 -
-
水平垂直居中
-
宽&高固定 -
absolute
+ 负margin
-
absolute
+margin auto
-
absolute
+calc
-
-
宽&高不固定 -
absolute
+transform: translate(-50%, -50%);
-
flex布局 -
grid 布局
-
宽&高固定
absolute
+ 负 margin
.parent {
+ position: relative;
}
.child {
width: 300px;
height: 100px;
padding: 20px;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ margin: -70px 0 0 -170px;
}

-
初始位置为方块1的位置 -
当设置 left、top
为50%的时候,内部子元素为方块2的位置 -
设置 margin
为负数时,使内部子元素到方块3的位置,即中间位置
absolute
+ margin auto

absolute
+ calc

宽&高不固定
absolute
+ transform: translate(-50%, -50%);
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
flex布局
.parent {
display: flex;
justify-content: center;
align-items: center;
}
grid布局
.parent {
display:grid;
}
.parent .child{
margin:auto;
}
块级格式化上下文
块级格式化上下文(「BFC」),它是页面中的一块渲染区域,并且有一套属于自己的「渲染规则」:(6个)
-
内部的盒子会在「垂直方向」一个接一个的放置 -
对于「同一个」 BFC
的俩个相邻的盒子的margin会发生重叠,与方向无关。 -
「每个元素的左外边距与包含块的左边界相接触」(页面布局方向从左到右),即使浮动元素也是如此 -
BFC
的区域不会与float
的元素区域重叠 -
计算BFC的高度时,浮动子元素也参与计算 -
BFC
就是页面上的一个「隔离的独立容器」,容器里面的子元素不会影响到外面的元素,反之亦然
触发条件 (5个)RFODP
-
「根元素」,即 HTML
元素 -
「浮动元素」: float
值为left、right
-
overflow
值不为visible
,为auto
、scroll
、hidden
-
display
的值为inline-block、table、inline-table、flex、inline-flex、grid、inline-grid
-
position
的值为absolute
或fixed
应用场景
-
防止 margin
重叠-
将位于同一个BFC的元素,分割到不同的BFC中
-
-
高度塌陷 -
「计算BFC的高度时,浮动子元素也参与计算」 -
子元素浮动 -
父元素 overflow: hidden;
构建BFC
-
-
多栏自适应 -
BFC的区域不会与 float
的元素区域重叠 -
aside
-float:left
-
main
-margin-left:aside-width
-overflow: hidden
构建BFC
-
层叠规则
所谓层叠规则,指的是当网页中的元素发生层叠时的表现规则。
❝❞
z-index
:z-index
属性只有和「定位元素」(position
不为static
的元素)在一起的时候才有作用。
CSS3
中,z-index
已经并非只对定位元素有效,flex
盒子的「子元素」也可以设置z-index
属性。
层叠上下文的特性
-
层叠上下文的层叠水平要「比普通元素高」 -
层叠上下文可以阻断元素的混合模式 -
「层叠上下文可以嵌套,内部层叠上下文及其所有元素均受制于外部的层叠上下文」 -
每个层叠上下文和兄弟元素独立 -
当进行层叠变化或渲染的时候,只需要考虑后代元素
-
-
每个层叠上下文是自成体系的,当元素发生层叠的时候,整个元素被认为是在父层叠上下文的层叠顺序中
层叠上下文的创建(3类)
由一些CSS属性创建
-
「天生派」 -
页面根元素天生具有层叠上下文 -
根层叠上下文
-
-
「正统派」 -
z-index
值为数值的定位元素的传统层叠上下文
-
-
「扩招派」 -
其他CSS3属性
-
根层叠上下文
指的是页面根元素,页面中「所有的元素」一定处于至少一个层叠结界中
定位元素与传统层叠上下文
对于position
值为relative/absolute
的定位元素,当z-index
值不是auto
的时候,会创建层叠上下文。
CSS3属性(8个)FOTMFIWS
-
元素为 flex
布局元素(父元素display:flex|inline-flex
),同时z-index
值「不是auto」 - 「flex布局」 -
元素的 opactity
值不是1 - 透明度 -
元素的 transform
值不是none
- 转换 -
元素 mix-blend-mode
值不是normal
- 混合模式 -
元素的 filter
值不是none
- 滤镜 -
元素的 isolation
值是isolate
- 隔离 -
元素的 will-change
属性值为上面②~⑥的任意一个(如will-change:opacity
) -
元素的 -webkit-overflow-scrolling
设为touch
重绘和重排
页面渲染的流程, 简单来说,「初次渲染」时会经过以下「6步」:
❝❞
构建DOM树; 样式计算; 「布局定位」; 图层分层; 「图层绘制」; 「合成显示」;
在「CSS属性改变」时,重渲染会分为「回流」、「重绘」和「直接合成」三种情况,分别对应从「布局定位」/「图层绘制」/「合成显示」开始,再走一遍上面的流程。
元素的CSS具体发生什么改变,则决定属于上面哪种情况:
-
回流(又叫重排):元素「位置、大小」发生变化导致其他节点联动,需要重新计算布局; -
重绘:修改了一些不影响布局的「属性」,比如颜色; -
直接合成:「合成层」的 transform、opacity
修改,只需要将多个图层「再次合并」,而后「生成位图」,最终展示到屏幕上;
触发时机
回流触发时机
回流这一阶段主要是计算节点的位置和几何信息,那么当页面布局和几何信息发生变化的时候,就需要回流。
-
添加或删除「可见的DOM元素」 -
元素的「位置」发生变化 -
元素的「尺寸」发生变化(包括外边距、内边框、边框大小、高度和宽度等) -
内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代 -
页面一开始渲染的时候(这避免不了) -
浏览器的「窗口尺寸变化」(因为回流是根据视口的大小来计算元素的位置和大小的) -
获取一些特定属性的值 -
offsetTop、offsetLeft、 offsetWidth、offsetHeight
-
scrollTop、scrollLeft、scrollWidth、scrollHeight
-
clientTop、clientLeft、clientWidth、clientHeight
-
这些属性有一个共性,就是需要通过「即时计算」得到。因此浏览器为了获取这些值,也会进行回流。
-
重绘触发时机
❝触发回流一定会触发重绘
❞
除此之外还有一些其他引起重绘行为:
-
「颜色」的修改 -
「文本方向」的修改 -
「阴影」的修改
浏览器优化机制
由于每次重排都会造成额外的计算消耗,因此大多数浏览器都会「通过队列存储重排操作并批量执行来优化重排过程」。浏览器会将修改操作放入到队列里,直到过了一段时间或者操作达到了一个阈值,才清空队列。
当你获取布局信息的操作的时候,会「强制队列刷新」,例如offsetTop
等方法都会返回最新的数据。
因此浏览器不得不清空队列,触发回流重绘来返回正确的值
减少回流
-
对于那些复杂的动画,对其设置 position: fixed/absolute
,尽可能地使元素脱离文档流,从而减少对其他元素的影响 -
使用css3「硬件加速」,可以让 transform
、opacity
、filters
这些动画不会引起回流重绘 -
在使用 JavaScript
「动态插入多个节点」时, 可以使用DocumentFragment
.创建后一次插入. -
通过设置元素属性 display: none
,将其从页面上去掉,然后再进行后续操作,这些后续操作也不会触发回流与重绘,这个过程称为离线操作
CSS引入方式(4种)
-
内联方式
-
<div style="background: red"></div>
-
-
嵌入方式
-
在 HTML
头部中的<style>
标签下书写CSS
代码
-
-
链接方式
-
使用 HTML
头部的<head>
标签引入外部的CSS
文件。 -
<link rel="stylesheet" type="text/css" href="style.css">
-
-
导入方式
-
使用 CSS
规则引入外部CSS
文件
-
比较链接方式和导入方式
链接方式(用 link
)和导入方式(用 @import
)都是引入外部的 CSS
文件的方式
-
link
属于HTML
,通过<link>
标签中的href
属性来引入外部文件,而@import
属于CSS
,所以导入语句应写在CSS
中,要注意的是「导入语句应写在样式表的开头」,否则无法正确导入外部文件; -
@import
是CSS2.1
才出现的概念,所以如果浏览器版本较低,无法正确导入外部样式文件;
❝当
❞HTML
文件被加载时,link
引用的文件会「同时被加载」,而@import
引用的文件则会等页面全部下载完毕再被加载;
硬件加速
浏览器中的层分为两种:「渲染层」和「合成层」。
渲染层
渲染层的概念跟层叠上下文密切相关。简单来说,拥有z-index
属性的定位元素会生成一个层叠上下文,一个生成层叠上下文的元素就生成了一个渲染层。
层叠上下文的创建(3类)
由一些CSS属性创建
-
天生派 -
页面根元素天生具有层叠上下文 -
根层叠上下文
-
-
正统派 -
z-index
值为数值的定位元素的传统层叠上下文
-
-
扩招派 (CSS3属性) -
元素为 flex
布局元素(父元素display:flex|inline-flex
),同时z-index
值「不是auto」 - 「flex布局」 -
元素的 opactity
值不是1 - 透明度 -
元素的 transform
值不是none
- 转换 -
元素 mix-blend-mode
值不是normal
- 混合模式 -
元素的 filter
值不是none
- 滤镜 -
元素的 isolation
值是isolate
- 隔离 -
元素的 will-change
属性值为上面②~⑥的任意一个(如will-change:opacity
) -
元素的 -webkit-overflow-scrolling
设为touch
-
合成层
只有一些特殊的渲染层才会被提升为合成层,通常来说有这些情况:
-
transform:3D
变换:translate3d
,translateZ
; -
will-change:opacity | transform | filter
-
对 opacity
|transform
|fliter
应用了过渡和动画(transition/animation
) -
video、canvas、iframe
硬件加速
浏览器为什么要分层呢?答案是「硬件加速」。就是给HTML元素加上某些CSS属性,比如3D变换,将其提升成一个合成层,「独立渲染」。
之所以叫硬件加速,就是因为「合成层会交给GPU(显卡)去处理」,在硬件层面上开外挂,比在主线程(CPU)上效率更高。
利用硬件加速,可以把需要重排/重绘的元素单独拎出来,减少绘制的面积。
避免重排/重绘,直接进行合成,合成层的transform
和 opacity
的修改都是直接进入合成阶段的;
-
可以使用 transform:translate
代替left/top
修改元素的位置; -
使用 transform:scale
代替宽度、高度的修改;
元素超出宽度...处理
单行 (AKA: TWO)
-
text-overflow:ellipsis
:当文本溢出时,显示省略符号来代表被修剪的文本 -
white-space:nowrap
:设置文本不换行 -
overflow:hidden
:当子元素内容超过容器宽度高度限制的时候,裁剪的边界是border box
的内边缘
p{
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
width:400px;
}
多行
-
基于高度截断(伪元素 + 定位) -
基于行数截断()
基于高度截断
关键点 height + line-height + ::after + 子绝父相
核心的css代码结构如下:
.text {
position: relative;
line-height: 20px;
height: 40px;
overflow: hidden;
}
.text::after {
content: "...";
position: absolute;
bottom: 0;
right: 0;
padding: 0 20px 0 10px;
}
基于行数截断
关键点:box + line-clamp + box-orient
+ overflow
-
display: -webkit-box
:将对象作为弹性伸缩盒子模型显示 -
-webkit-line-clamp: n
:和①结合使用,用来限制在一个块元素显示的文本的行数(n
) -
-webkit-box-orient: vertical
:和①结合使用 ,设置或检索伸缩盒对象的子元素的排列方式 -
overflow: hidden
p {
width: 300px;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
元素隐藏
可按照隐藏元素「是否占据空间」分为「两大类」(6 + 3)
-
「元素不可见,不占空间」( 3absolute
+1relative
+1script
+1display
)-
<script>
-
display:none
-
absolute
+visibility:hidden
-
absolute
+clip:rect(0,0,0,0)
-
absolute
+opacity:0
-
relative
+left
负值
-
-
「元素不可见,占据空间」(3个) -
visibility
:hidden
-
relative
+z-index
负值 -
opacity:0
-
元素不可见,不占空间
<script>
<script type="text/html">
<img src="1.jpg">
</script>
display:none
其他特点:辅助设备无法访问,「资源加载,DOM可访问」
对一个元素而言,如果display
计算值是none,则该元素以及所有后代元素都隐藏
.hidden {
display:none;
}
absolute + visibility
.hidden{
position:absolute;
visibility:hidden;
}
absolute + clip
.hidden{
position:absolute;
clip:rect(0,0,0,0);
}
absolute + opacity
.hidden{
position:absolute;
opacity:0;
}
relative
+负值
.hidden{
position:relative;
left:-999em;
}
元素不可见,占据空间
visibility:hidden
visibility
的继承性
-
父元素设置 visibility:hidden
,子元素也看不见 -
但是,如果子元素设置了 visibility:visible
,则子元素又会显示出来
.hidden{
visibility:hidden;
}
relative + z-index
.hidden{
position:relative;
z-index:-1;
}
opacity:0
.hidden{
opacity:0;
filter:Alpha(opacity=0)
}
总结
最常用的还是display:none
和visibility:hidden
,其他的方式只能认为是奇招,它们的真正用途并不是用于隐藏元素,所以并不推荐使用它们。
关于display: none
、visibility: hidden
、opacity: 0
的区别,如下表所示:

Chrome支持小于12px 的文字
Chrome
「中文版浏览器会默认设定页面的最小字号是12px」,英文版没有限制
原由 Chrome
团队认为汉字小于12px就会增加识别难度
-
中文版浏览器 「与网页语言无关」,取决于用户在Chrome的设置里(
chrome://settings/languages
)把哪种语言设置为默认显示语言 -
系统级最小字号 浏览器默认设定页面的最小字号,用户可以前往
chrome://settings/fonts
根据需求更改
解决方案(3种)
-
zoom
-
transform:scale()
-
-webkit-text-size-adjust:none
zoom
zoom
可以改变页面上元素的尺寸,属于真实尺寸。
其支持的值类型有:
-
zoom:50%
,表示缩小到原来的一半 -
zoom:0.5
,表示缩小到原来的一半
.span10{
font-size: 12px;
display: inline-block;
zoom: 0.8;
}
transform:scale()
用transform:scale()
这个属性进行放缩
使用scale
属性「只对可以定义宽高的元素生效」,所以,需要将指定元素转为行内块元素
.span10{
font-size: 12px;
display: inline-block;
transform:scale(0.8);
}
text-size-adjust
该属性用来设定文字大小是否根据设备(浏览器)来「自动调整显示大小」
属性值:
-
auto
:「默认」,字体大小会根据设备/浏览器来自动调整; -
percentage
:字体显示的大小 -
none
:字体大小不会自动调整
「存在兼容性问题,chrome
受版本限制,safari
可以」。
后记
「分享是一种态度」。
「全文完,既然看到这里了,如果觉得不错,随手点个赞和“在看”吧。」

作者介绍

前端小魔女
微信公众号:前端柒八九