🗂️五、浏览器相关
1、Sass、LESS是什么?大家为什么要使用他们?
(1)是什么
他们是 CSS
预处理器,也是动态样式语言,是 CSS
上的一种抽象层。他们是一种特殊的语法/语言编译成 CSS
。
例如 Less
是一种动态样式语言. 将 CSS
赋予了动态语言的特性,如变量,继承,运算, 函数 . LESS
既可以在客户端上运行 (支持 IE 6+
, Webkit
, Firefox
),也可以在服务端运行 (借助 Node.js
)。
(2)为什么要使用它们?
- 结构清晰,便于扩展。
- 可以方便地屏蔽浏览器私有语法差异。这个不用多说,封装对浏览器语法差异的重复处理,减少无意义的机械劳动。
- 可以轻松实现多重继承。
- 完全兼容
CSS
代码,可以方便地应用到老项目中。LESS
只是在CSS
语法上做了扩展,所以老的CSS
代码也可以与LESS
代码一同编译。
2、stylus,sass,less区别
- 均具有“变量”、“混合”、“嵌套”、“继承”、“颜色混合”五大基本特性。
Sass
和LESS
语法较为严谨,LESS
要求一定要使用大括号{}
,Sass
和Stylus
可以通过缩进表示层次与嵌套关系。Sass
无全局变量的概念,LESS
和Stylus
有类似于其它语言的作用域概念。Sass
是基于Ruby
语言的,而LESS
和Stylus
可以基于NodeJS NPM
下载相应库后进行编译;这也是为什么安装Sass
的时候有时候会报错,需要安装python
脚本。
3、重排和重绘是什么
重绘不一定需要重排,重排必然会导致重绘。
重排:当渲染树的一部分必须更新并且节点的尺寸发生了变化,浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。
通俗来说,即当DOM的变化引发了元素几何属性的变化,比如改变元素的宽高,元素的位置,导致浏览器不得不重新计算元素的几何属性,并重新构建渲染树,这个过程称为“重排”。
重绘:是在一个元素的外观被改变所触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。
通俗来说,即完成重排后,要将重新构建的渲染树渲染到屏幕上,这个过程就是“重绘”。
DOM树:表示页面的结构
渲染树:表示页面的节点如何显示。
一旦渲染树构建完成,就要开始绘制(paint)页面元素了。
4、什么时候会导致重排问题发生?
- 添加、删除、更新
DOM
节点。 - 通过
display: none
隐藏一个DOM
节点 —— 触发重排和重绘。 - 通过
visibility: hidden
隐藏一个DOM
节点 —— 只触发重绘,因为没有几何变化。 - 移动或者给页面中的
DOM
节点添加动画。 - 添加一个样式表,调整样式属性。
- 用户行为,例如调整窗口大小,改变字号,或者滚动。
常见的重排元素 | |||
width | height | padding | margin |
display | border-width | border | top |
position | font-size | float | text-align |
overflow-y | font-weight | overflow | left |
font-family | line-height | vertical-align | right |
clear | white-space | bottom | min-height |
5、如何减少重排对性能的影响?
- 尽可能限制重排的影响范围,尽可能在低层级的DOM节点上,如下述例子中,如果你要改变p的样式,class就不要加在div上,通过父元素去影响子元素不好。
<body> <div class="hello"> <h4>hello</h4> <p><strong>Name:</strong>BDing</p> <h5>male</h5> <ol> <li>coding</li> <li>loving</li> </ol> </div> </body> 复制代码
- 当
p
节点上发生reflow
重排时,hello
和body
也会重新渲染,甚至h5和ol都会收到影响。 - 避免设置大量的
style
属性,因为通过设置style
属性改变结点样式的话,每一次设置都会触发一次reflow
,所以最好是使用class
属性。 - 实现元素的动画,它的position属性,最好是设为
absoulte
或fixed
,这样不会影响其他元素的布局动画实现的速度的选择。比如实现一个动画,以1
个像素为单位移动这样最平滑,但是reflow就会过于频繁,大量消耗CPU
资源,如果以3
个像素为单位移动则会好很多。 - 不要使用
table
布局,因为table
中某个元素旦触发了reflow
,那么整个table
的元素都会触发reflow
。那么在不得已使用table
的场合,可以设置table-layout:auto
;或者是table-layout:fixed
;这样可以让table
一行一行的渲染,这种做法也是为了限制reflow的影响范围。 - 如果
CSS
里面有计算表达式,每次都会重新计算一遍,出发一次reflow
。
📏六、性能优化相关
1、link 与 @import 的区别
link
是 HTML
方式, @import
是 CSS
方式。
link
最大限度支持并行下载, @import
过多嵌套导致串行下载,出现 FOUC
(文档样式短暂失效) 。
link
可以通过 rel="alternate stylesheet"
指定候选样式。
浏览器对 link
支持早于 @import
,可以使用 @import
对老浏览器隐藏样式。
@import
必须在样式规则之前,可以在其引入的 css
文件中再引用其他文件。
总体来说: link
优于 @import
, link
优先级也更高。
📐七、布局相关
1、说下css的IFC
IFC
是行内格式上下文,有以下特点:
- 内部的
Box
会水平放置; - 水平的间距由
margin
,padding
,border
决定。
2、说下css的BFC
(1)BFC是什么
BFC
(Block Formatting Context) 是块级格式上下文,是 Web
页面中盒模型布局的 CSS
渲染模式,指一个独立的渲染区域或者说是一个隔离的独立容器。
(2)形成 BFC 的五种条件(创建规则)
- 根元素(
html
就是一个bfc
) - 浮动元素(
float
不取值为none
) - 绝对定位元素(
position
取值为absolute
或fixed
) - display 取值为
inline-block
、table-cell
、table-caption
、flex
、inline-flex
之一的元素 overflow
不取值为visible
的元素(hidden
,auto
,scroll
)
(3)BFC 的特性
- 内部的
Box
会在垂直方向上一个接一个的放置。 - 垂直方向上的距离由
margin
决定 bfc
的区域不会与float
的元素区域重叠。- 计算
bfc
的高度时,浮动元素也参与计算 bfc
就是页面上的一个独立容器,容器里面的子元素不会影响外面元素。
(4)BFC的作用
- 可以包含浮动元素
- 不被浮动元素覆盖
- 阻止父子元素的
margin
折叠
3、BFC会与float元素相互覆盖吗?为什么?举例说明
不会,因为 BFC
是页面中一个独立的隔离容器,其内部的元素不会与外部的元素相互影响,比如两个 div
,上面的 div
设置了 float
,那么如果下面的元素不是 BFC
,也没有设置 float
,会形成对上面的元素进行包裹内容的情况,如果设置了下面元素为 overflow:hidden
;属性那么就能够实现经典的两列布局,左边内容固定宽度,右边因为是 BFC
所以会进行自适应。
4、行内元素float:left后是否变为块级元素?
行内元素设置成浮动之后变得更加像是 inline-block
(行内块级元素,设置 成这个属性的元素会同时拥有行内和块级的特性,最明显的不同是它的默认宽度不是 100%
),这时候给行内元素设置 padding-top
和 padding-bottom
或者 width
、 height
都是有效果的
5、两个div上下排列,都设margin,有什么现象?
- 都正取大
- 一正一负相加
问:为什么会有这种现象?你能解释一下吗?
- 是由块级格式上下文决定的,
BFC
,元素在BFC
中会进行上下排列,然后垂直距离由margin
决定,并且会发生重叠,具体表现为同正取最大的,同负取绝对值最大的,一正一负,相加; BFC
是页面中一个独立的隔离容器,内部的子元素不会影响到外部的元素。
6、 清除浮动有哪些方法?
(1)后果
不清除浮动会发生高度塌陷:浮动元素父元素高度自适应(父元素不写高度时,子元素写了浮动后,父元素会发生高度塌陷)
(2)方法
clear
清除浮动(添加空div
法)在浮动元素下方添加空div
,并给该元素写css
样式:{clear:both;height:0;overflow:hidden;}
;- 给浮动元素父级设置高度;
- 父级同时浮动(需要给父级同级元素添加浮动);
- 父级设置成
inline-block
,其margin: 0 auto
居中方式失效; - 给父级添加
overflow:hidden
清除浮动方法; - 万能清除法
after
伪类清浮动(现在主流方法,推荐使用),代码如下:
.float_div:after { content: "."; clear: both; display: block; height: 0; overflow: hidden; visibility: hidden; } .float_div { zoom: 1 } 复制代码
7、讲一讲flex属性
了解 flex
布局吗,讲讲 flex
的 css
属性及其含义, flex:1
代表什么, flex-basis
什么含义?
- 弹性盒布局,
CSS3
的新属性,用于方便布局,比如垂直居中 flex
属性是flex-grow
、flex-shrink
和flex-basis
的简写
8、了解box-sizing吗?说下 css 的盒子模型
(1)css盒模型
CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括: 外边距(margin) 、 边框 (border) 、 内边距(padding) 、 实际内容(content) 四个属性。 CSS盒模型:标准模型 + IE模型
标准盒子模型:宽度=内容的宽度(content)+ border + padding
低版本IE盒子模型:宽度=内容宽度(content+border+padding),如何设置成 IE 盒子模型:
box-sizing: border-box; 复制代码
(2) IE 盒子模型和 W3C 盒子模型
- W3C盒模型: 内容(content)、填充( padding )、边界( margin )、 边框( border );
- box-sizing: content-box
- width = content width;
- IE盒子模型: IE 的content 部分把 border 和 padding 计算了进去;
- box-sizing: border-box
- width = border + padding + content width
(3)box-sizing属性
box-sizing
属性可以被用来调整这些表现:
content-box
是默认值。如果你设置一个元素的宽为100px
,那么这个元素的内容区会有100px
宽,并且任何边框和内边距的宽度都会被增加到最后绘制出来的元素宽度中。border-box
告诉浏览器:你想要设置的边框和内边距的值是包含在width
内的。也就是说,如果你将一个元素的width
设为100px
,那么这100px
会包含它的border
和padding
,内容区的实际宽度是width减去(border + padding)的值
。大多数情况下,这使得我们更容易地设定一个元素的宽高。
9、说下css3的flexbox
css3
的flexbox
,即弹性盒布局模型。它是一个用于页面布局的全新CSS3
功能,Flexbox
可以把列表放在同一个方向(从上到下排列,从左到右),并让列表能延伸到占用可用的空间。- 较为复杂的布局还可以通过嵌套一个伸缩容器(
flex container
)来实现。 - 采用
Flex
布局的元素,称为Flex
容器(flex container
),简称"容器"。 - 它的所有子元素自动成为容器成员,称为
Flex
项目(flex item
),简称"项目"。 - 常规布局是基于块和内联流方向,而
Flex
布局是基于flex-flow
流可以很方便的用来做局中,能对不同屏幕大小自适应。 - 在布局上有了比以前更加灵活的空间。
10、说下 css 的水平垂直居中
(1)水平居中方法
- 元素为行内元素,设置父元素
text-align:center
- 如果元素宽度固定,可以设置左右
margin
为auto
; - 如果元素为绝对定位,设置父元素
position
为relative
,元素设left:0;right:0;margin:auto
; - 使用
flex-box
布局,指定justify-content
属性为center
display
设置为tabel-ceil
(2)垂直居中方法
- 将显示方式设置为表格,
display:table-cell
,同时设置vertial-align:middle
- 使用
flex
布局,设置为align-item:center
- 绝对定位中设置
bottom:0,top:0
,并设置margin:auto
- 绝对定位中固定高度时设置
top:50%
,margin-top
值为高度一半的负值 - 文本垂直居中设置
line-height
为height
值
11、用css2和css3分别写一下垂直居中和水平居中
(1)css2方法
水平居中:
- div + margin: auto;
- span + text-align。
垂直居中:
- 使用
position
然后left/top
和margin
的方式垂直居中(已知宽高和未知宽高); - 使用 position + margin;
- 使用 display: table-cell。
(2)css3方法
水平居中:
- flex布局
垂直居中:
- flex布局
(3)代码实现
Ⅰ. 已知宽高,进行水平垂直居中
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>已知宽高,进行水平垂直居中</title> <style> .outer { position: relative; width: 400px; height: 600px; background: yellow; } .inner { position: absolute; width: 200px; height: 300px; background: gray; left: 50%; top: 50%; margin: -150px 0 0 -100px; } </style> </head> <body> <div class="outer"> <div class="inner"></div> </div> </body> </html> 复制代码
Ⅱ. 宽高未知,比如内联元素,进行水平垂直居中
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>宽高未知,比如内联元素,进行水平垂直居中</title> <style> .outer { position: relative; width: 400px; height: 600px; background: yellow; } .inner { position: absolute; background: gray; left: 50%; top: 50%; /* translate,指往x轴平移和往y平移; x轴:正数表示往右平移,负数表示往左平移 y轴:正数表示往下平移,负数表示往上平移 */ transform: translate(-50%, -50%); } </style> </head> <body> <div class="outer"><span class="inner">我想居中显示</span></div> </body> </html> 复制代码
Ⅲ. 绝对定位的div水平垂直居中
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>使用绝对定位的div进行水平垂直居中</title> <style> .outer { width: 400px; height: 600px; background-color: yellow; position: relative; } .inner { position: absolute; background: gray; left: 0; right: 0; bottom: 0; top: 0; width: 200px; height: 300px; margin: auto; } </style> </head> <body> <div class="outer"> <div class="inner">我想居中显示</div> </div> </body> </html> 复制代码
Ⅳ. 图片和其他元素使用 display: table-cell; 进行垂直居中
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>使用tabel-cell进行水平垂直居中</title> <style> .outer { width: 400px; height: 600px; background-color: yellow; /* 让其变为单元格元素 */ display: table-cell; /* 文本的垂直居中方式 */ vertical-align: middle; } .inner { background: gray; width: 200px; height: 300px; /* 当对行内元素设置margin和padding时,只有水平方向有效果,垂直方向没有效果 */ /* 水平居中方式 */ margin: 0 auto; } </style> </head> <body> <div class="outer"> <div class="inner">我想居中显示</div> </div> </body> </html> 复制代码
Ⅴ. 使用flex布局进行水平垂直居中
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>css3实现垂直和水平居中</title> </head> <style> .outer { width: 400px; height: 400px; display: flex; justify-content: center; align-items: center; background-color: yellow; } .inner { width: 200px; height: 200px; display: flex; justify-content: center; align-items: center; background-color: gray; } </style> <body> <div class="outer"> <div class="inner">居中显示</div> </div> </body> </html> 复制代码
12、CSS实现自适应正方形、等宽高比矩形
(1)方法
- padding撑高
- 伪元素设置
margin-top:100%
撑高
(2)代码实现
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>CSS实现自适应正方形、等宽高比矩形</title> </head> <style> /* 第一种方法:padding撑高画正方形 */ .outer1 { width: 400px; height: 600px; background-color: beige; } .inner1 { width: 100%; padding-bottom: 100%; background-color: green; } /* 第二种方法:伪元素设置margin-top */ .inner2 { width: 100px; overflow: hidden; background-color: cadetblue; } .inner2::after { content: ''; margin-top: 100%; /* 块状,让其可以设置宽高才能正常显示 */ display: block; } </style> <body> <!-- 第一种方法:padding撑高画正方形 --> <div class="outer1"> <div class="inner1"></div> </div> <!-- 第二种方法:伪元素设置margin-top --> <div class="inner2"></div> </body> </html> 复制代码
13、如何实现两栏布局
(1)两栏布局是什么
所谓两栏布局,就是左边定宽,右边自适应。
(2)方法
bfc
和float
flex
position
(3)代码实现
Ⅰ. bfc和float实现两栏布局
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>bfc和float实现两栏布局</title> </head> <style> div { height: 500px; } .aside { width: 200px; float: left; background-color: yellow; } .main { /* overflow:hidden 触发一个bfc */ overflow: hidden; background-color: gray; } </style> <body> <div class="aside"></div> <div class="main"></div> </body> </html> 复制代码
Ⅱ. flex实现两栏布局
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>flex实现两栏布局</title> </head> <style> div { height: 100%; } .container { display: flex; } .left { flex: 0 0 200px; /* flex-grow/flex-shrink/flex-basis */ background-color: yellow; } .right { /* 当container_width > sum(flex_basis)时,flex-shrink值不会生效,各item根据flex-grow按比例分配剩余的空间 当container_width < sum(flex_basis)时,flex-grow值不会生效,各item以flex-basis为基础值,根据flex-shrink按比例缩小 */ flex: 1 1; background-color: grey; } </style> <body> <div class="container"> <div class="left">left</div> <div class="right">right</div> </div> </body> </html> 复制代码
Ⅲ. position实现两栏布局
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>position实现两栏布局</title> </head> <style> .container { display: flex; position: relative; } .left { position: absolute; width: 300px; background-color: yellow; } .right { width: 100%; margin-left: 300px; background-color: gray; } </style> <body> <div class="container"> <div class="left">hello</div> <div class="right">hi</div> </div> </body> </html> 复制代码
14、如何实现三栏布局
(1)三栏布局是什么
所谓三栏布局,就是左右定宽,右边自适应。
(2)方法
- 圣杯布局
- 双飞翼布局
flex
布局position
布局float
布局
(3)代码实现
Ⅰ. 圣杯布局
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>实现三栏布局之圣杯布局</title> </head> <style> .container { padding: 0 300px 0 200px; } .center { float: left; background-color: yellow; width: 100%; } .left { float: left; width: 200px; background-color: green; margin-left: -100%; position: relative; left: -200px; } .right { float: left; width: 300px; margin-left: -300px; background-color: grey; position: relative; right: -300px; } </style> <body> <div class="container"> <div class="center">中间区域</div> <div class="left">左侧区域</div> <div class="right">右侧区域</div> </div> </body> </html> 复制代码
Ⅱ. 双飞翼布局
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>实现两栏布局</title> </head> <style> .container { width: 100%; float: left; background-color: green; } .center { margin-left: 200px; margin-right: 300px; } .left { width: 200px; float: left; background-color: yellow; margin-left: -100%; } .right { width: 300px; float: left; background-color: grey; margin-left: -300px; } </style> <body> <!-- 与圣杯模式相似,只是中间盒子增加一个内容盒子,用内容盒子设置左右margin,留给左右盒子,避免内容被遮挡。(不需要定位了) 1:中间盒子宽度width:100%;独占一行 2:三个盒子设置float: left; 3:使用margin-left属性将左右两边的盒子拉回与中间盒子同一行 .left{ margin-left: -100%};向左走一个父盒子的宽度 .right{ margin-left: 负的自身宽度} 4: 中间主盒子里面的内容盒子设置左右margin,避免被遮挡内容 --> <div class="container"> <div class="center">center</div> </div> <div class="left">left</div> <div class="right">right</div> </body> </html> 复制代码
Ⅲ. flex布局
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>flex实现三栏布局</title> </head> <style> .container { display: flex; } .center { flex: 1 1; /* order 用于设置弹性盒对象元素的顺序 */ order: 2; background-color: yellow; } .left { flex: 0 0 200px; order: 1; background-color: green; } .right { flex: 0 0 300px; order: 3; background-color: gray; } </style> <body> <div class="container"> <div class="center">center</div> <div class="left">left</div> <div class="right">right</div> </div> </body> </html> 复制代码
Ⅳ. position布局
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>position实现两栏布局</title> </head> <style> div { height: 500px; } .container { position: relative; } .left { width: 200px; background-color: green; position: absolute; left: 0; top: 0; } .right { width: 200px; background-color: yellow; position: absolute; right: 0; top: 0; } .middle { background-color: grey; margin-left: 200px; margin-right: 200px; } </style> <body> <div class="container"> <div class="left">left</div> <div class="middle">middle</div> <div class="right">right</div> </div> </body> </html> 复制代码
Ⅴ. float布局
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>float实现三栏布局</title> </head> <style> div { height: 500px; } .left { float: left; width: 200px; background-color: green; } .right { float: right; width: 200px; background-color: yellow; } .middle { background-color: grey; /* 触发一个bfc */ overflow: hidden; } </style> <body> <div class="container"> <div class="left">left</div> <div class="right">right</div> <div class="middle">middle</div> </div> </body> </html> 复制代码
💡八、结束语
对于 css
的面试来说, position
、 css
选择器优先级以及手写各种布局是久经不衰的话题。所以在复习的过程中,要理解清楚各个知识点所涉及到的内容,这样,在面试中就不难被面试官问倒啦!
到这里,关于 css
的常考面试题讲解就结束啦!希望对大家有帮助~