- 2024前端年末备战面试题——HTML篇
- 2024前端年末备战面试题——浏览器篇
- 2024前端年末备战面试题——网络篇
- 2024前端年末备战面试题——JavaScript篇
- 2024前端年末备战面试题——框架篇(Vue)
- 2024前端年末备战面试题——构建工具与git
CSS篇
本文是本人根据MDN上的解答或者网上一些其他朋友的文章以及自己的理解,整理归纳出来的一篇CSS方面的面试题,其中不免有许多漏掉的问题或是答案,发现错误的或者是有什么问题需要补充的朋友们,可以在评论区留言,大家虚心交流,一起进步。
1. CSS盒模型
- CSS盒模型分为两种,分别是
W3C标准盒模型,一种是IE怪异盒模型。 - 盒模型由
内容(content box)、内边距(padding box)、边框(border box)、外边距(margin box)组成。
区别
W3C盒模型下,盒模型的总宽度和总高度是由外边距(margin)+边框(border)+内边距(padding)+内容(content)组成的,但是我们设置的元素宽高(css属性)仅仅是设置内容(content)的宽高。
IE盒模型下,盒模型的总宽度和总高度是由外边距(margin)+内容(content)组成的,这是因为我们设置的元素宽高(css属性)里面包含了内容(content)+内边距(padding)+边框(border)的宽高。
2. 如何改变盒模型
我们可以通过CSS的box-sizing属性去改变盒模型,默认值为content-box(W3C盒模型),我们可以将其设置为border-box(IE盒模型)。
3. CSS3有哪些新特性
1. 边框
- 新增了
border-radius圆角,可以通过该属性给元素四周或某一个角设置圆角。 - 新增了
border-shadow阴影,可以通过该属性给元素周围添加阴影。 - 新增了
border-image图片边框,可以通过该属性指定一张图片作为元素的边框。
2. 背景
- 新增了
background-clip,规定背景的绘制区域,有三个值border-box、padding-box、content-box,设置不同的值,可以让背景充满不同的盒区域。 - 新增了
background-origin,规定背景图片的定位区域。 - 新增了
background-size,规定背景图片的尺寸。
3. 渐变
- 定义了
线性渐变(Linear Gradients),可以向下、向上、向左、向右、对角进行颜色渐变。 - 定义了
径向渐变(Radial Gradients),由中心定义,向四周进行渐变。并且可以设置形状。
4. 文本效果
- 新增了
hanging-punctuation,规定标点字符是否位于线框之外。 - 新增了
punctuation-trim,规定是否对标点字符进行修剪。 - 新增了
text-align-last,设置如何对齐最后一行,或者紧挨着强制换行符之前的那一行。 - 新增了
text-emphasis,向元素的文本应用重点标记以及重点标记的前景色。 - 新增了
text-justify,规定当text-align设置为justify时所使用的对齐方法。 - 新增了
text-outline,规定文本的轮廓。 - 新增了
text-overflow,规定了文本溢出的情况处理方式。 - 新增了
text-shadow,规定了文字阴影。 - 新增了
text-wrap,规定了文本换行规则。 - 新增了
word-break,规定了非中日韩文本的换行规则。 - 新增了
word-wrap,允许对长的不可分割的单词进行分割并且换行到下一行。
5. 字体
css3中可以使用@font-face定义本地字体包。
6. 2D转换
- 新增了
transform,适用于2d或3d转换的元素。 - 新增了
transform-origin,可以更改转换元素的位置。 transform有几种方法,分别是matrix(n,n,n,n,n,n)(2D转换,使用6个值的矩阵)、translate(X | Y)(x,y)(定义2D转换,沿X或Y轴进行平移、scale(X | Y)(x,y)(定义2D转换,使X方向或Y方向进行缩放相应的倍数)、rotate(angle)(定义2D转换,进行旋转)、skew(X | Y)(x-angle,y-angle)(定义2D转换,沿X或Y轴倾斜转换)
7. 3D转换
- 新增了
transform-style,规定被嵌套元素如何在3D空间中展示。 - 新增了
perspective,规定了3D元素的透视效果。 - 新增了
perspective-origin,规定了3D元素的底部位置。 - 新增了
backface-visibility,定义元素在不面对屏幕时是否可见。 transform的方法和2D转换的差不多,只是除了skew方法以外,其它方法多了一个Z轴。
8. 动画
- 新增
@keyframes创建动画,定义动画时可以定义动画在不同阶段的状态,然后在需要使用动画的地方使用animation关键字,绑定动画名称,给出执行动画的时间。
9. 弹性盒子(Flex)
- 弹性盒子由
弹性容器(Flex container)和弹性子元素(Flex item)组成。 - 通过将容器设置为
display: flex | inline-flex;来让该容器变成弹性容器。 - 弹性容器中有两个轴
主轴和交叉轴,默认水平方向为主轴,所以默认情况下,弹性容器内的弹性子元素,都是在水平方向排列。 - 使用
flex-direction属性,可以改变弹性容器的主轴方向,默认值为row,可选值有row-reverse、column、column-reverse。 justify-content属性规定了弹性子元素在弹性容器轴的对齐方式,有五个值flex-start(从头对齐)、flex-end(从尾部对齐)、center(居中对齐)、space-between(左右两端对齐)、space-around(均分对齐)。align-items属性规定了弹性子元素在弹性容器交叉轴的对齐方式,同样也有五个值flex-start(交叉轴头部对齐)、flex-end(交叉轴尾部对齐)、center(居中对齐)、baseline(基线对齐)、stretch(默认对齐方式,拉伸)。align-content属性类似于align-items, 但它不是设置弹性子元素的对齐,而是设置各个行的对齐。值和justify-content一样。order属性用来定义弹性子元素的排列顺序,可以为负值,值越小的就会排在越前边。align-self属性用来定义当前弹性子元素自己在交叉轴的对齐方式。值和align-items一样。flex属性用于指定弹性子元素如何分配空间。flex: auto(1 1 auto) | initial(0 1 auto) | none(0 0 auto) | inherit(继承父元素) | [flex-grow](定义弹性盒子元素的扩展比率) || [flex-shrink](定义弹性盒子元素的收缩比率) || [flex-basis](定义弹性盒子元素的默认基准值)。- 当
flex属性的值只有一个时,必须是一个[flex-grow]的有效值,简写会拓展为[flex-grow] 1 0,或者是一个[flex-basis]的有效值,那么简写会拓展为1 1 [flex-basis],或者是none或者全局关键字之一。 - 当
flex属性的值有两个时,第一个值必须是[flex-grow]的一个有效值,第二个可以是[flex-shrink]或者[flex-basis]两个其中一个的有效值。 [flex-grow]的关键值为一个数字。[flex-shrink]的关键值为一个数字。[flex-basis]的关键值为元素的长度,合法值有auto、inherit、后面跟%,px,em的字符串、其他任何长度单位的数字。当我们设置auto时,会看当前元素有没有设置width,如果有,就会将width的值做为flex-basis的值,如果没有,就会用元素实际的长度做为flex-basis的值。
10. 媒体查询(后续补充)
11. 网格布局(后续补充)
4. 谈一谈BFC,以及它如何创建?它的作用是什么?
块级格式化上下文(Block Formatting Context)简称"BFC",通俗来讲,BFC就是一块独立的渲染区域,它规定了处于BFC内部的块级元素如何布局。
特点:
- 属于同一个BFC的
相邻块级元素垂直排列; 相邻的两个块级元素的边距由margin决定;相邻的两个块级元素的margin会进行重叠,最终结果为二者的较大值(比如元素a的margin-bottom: 30px;元素b的margin-top: 20px;那么它们的边距就是30px);- BFC的区域
不会与浮动元素重叠; - BFC的高度在计算时,内部的
浮动元素也参与计算; - BFC
内部元素不会影响外边的元素,外边的也不会影响内部的元素。
如何创建(开启)BFC?
- 文档的
根元素(<html>); - 浮动元素(float
不为none的元素); - position的值为
absolute或者fixed的元素; - 行内块级元素(
display:inline-block的元素); - overflow
不为visible或者cilp的块级元素; - display值为
flow-root的元素; - 弹性元素的
子元素(如果他们本身不是弹性、网格、表格容器的话); - 网格元素的
子元素(如果他们本身不是弹性、网格、表格容器的话);
它的作用是什么:
防止外边距重叠,如果两个元素的边距重叠,我们可以将其中一个元素创建一个新的BFC,就和另一个元素形成了两个不同的BFC,外边距就不会重叠了。解决高度塌陷,如果一个父容器内有一个浮动元素和一个普通元素,如果我们父容器没有设置高度,那么它的高度只会被普通元素撑开,如果普通元素高度小于浮动元素,浮动元素就会溢出。如果我们在当前父容器内创建BFC,浮动元素也会参与父容器高度的计算。排除外部浮动,比如我们当前同一个BFC中有两个相邻的块级元素,一个浮动元素和一个普通元素,浮动元素会覆盖普通元素,我们可以利用BFC的特性,给非浮动元素创建一个新的BFC,就不会和浮动元素进行重叠了。
5. 谈一下CSS的选择器以及CSS的优先级
选择器
id选择器,#开头,后面跟上元素的id;类选择器,.开头,后面跟上元素的类名;标签选择器,标签名;相邻选择器,第一个选择器+第二个选择器(h1+h2);子代选择器,父元素选择器>子元素选择器(.father>.son);后代选择器,父元素选择器+空格+后代选择器(.father p);后续相邻相抵选择器,第一个选择器~第一个元素之后的选择器(.first~p(在first之后,并且和first同级的所有p标签));属性选择器,标签名+标签的属性(比如div[class=^a],就代表所有类名以a开头的div元素);伪类选择器,比如:last-child、:is()、:not()、:first-child、:nth-child(n)、:nth-of-type(n)等等;伪元素选择器,::after、::before等;通配符选择器,*
优先级
!important的优先级最高,无视权重;- 其次是
内联样式,权重1000; - 其次是
id选择器,权重100; - 再然后是
类选择器、伪类选择器、属性选择器,权重10; - 再然后是
标签选择器、伪元素选择器,权重1; - 再然后是
通配符选择器,权重0;
上面是CSS选择器的优先级,当选择器一样时,就要
根据权重来计算优先级,权重一样时,哪个属性在后面,就会覆盖前面的属性。如果使用11个类选择器,会覆盖1个id选择器吗?答案是不会的,只有同级别的选择器才会去比较权重,不能跨选择器去比较权重,也就是说,id选择器的样式永远优先于类选择器。
6. CSS中的calc是什么,一般什么情况下会使用?
calc是一个CSS函数,用于动态计算元素的长度值。
比如我们想将一个元素的宽度设置为父元素的1/3,我们可以直接使用width: calc(100% / 3)。
7. 浮动元素会有什么影响?如何清除浮动?
影响:
高度塌陷,如果父元素没有设置高度的话,浮动元素不会撑开父元素,就会造成高度塌陷。影响非浮动的兄弟元素,如果兄弟元素是非浮动块级元素,该兄弟元素会忽略浮动元素,从而占据浮动元素的位置,并且浮动元素会盖在兄弟元素之上,但是兄弟元素内部的文本内容或者行内元素会环绕在浮动元素周围。如果兄弟元素是非浮动行内元素,那么兄弟元素就会环绕在浮动元素周围。影响浮动的兄弟元素,如果兄弟元素也是浮动元素,并且浮动的方向和该元素一致,那么就会紧跟在该元素后面,如果浮动方向不一样,那么互不影响。
清除浮动
- 利用CSS属性
clear来清除浮动,clear的值可以为left(清除左侧元素的浮动)、right(清除右侧元素的浮动)、both(清除所有方向的浮动)。 - 利用BFC清除浮动,一旦我们的父容器
创建了BFC,那么就会清除内部的浮动。
8. 如何利用CSS隐藏一个元素,它们各有什么优缺点?
- 可以利用
display: none;来隐藏元素,使用该方法时,该元素不会被渲染,元素不占用空间,但是每次展示或者隐藏时,会引起回流和重绘,影响页面性能。 - 可以使用
visibility: hidden;来隐藏元素,使用该方法时,该元素会被渲染到dom树,只是被隐藏,但是还会占据页面空间,只会引发重绘,不会引起回流。 - 使用
opacity:0;来隐藏元素,该方法只是将元素的透明的设置为0,元素同样会被渲染,也会占据页面空间,同时,如果该元素绑定了事件,点击该元素区域,依然会触发事件。
9. 请你说一下什么是回流和重绘,它们有什么区别?
重绘就是元素只是修改了一些不影响元素布局的内容,因此浏览器对内容更新时,不需要重新计算布局,减少了许多流程。
回流就是当我们修改或者访问一些元素layout的内容之后,浏览器就需要重新进行布局、分层、绘制、分块、光栅化等等一系列操作,如果我们频繁的导致页面回流,就会引起页面的卡顿。
10. 说一说CSS中不同长度单位的区别,比如px、em、rem、vw、vh
px是一个绝对单位,1px代表了1个像素的物理大小,不会受外部的影响;em是相对于当前文本字体大小的单位,比如当前区域字体大小为12px,那么1em = 12px,如果当前区域内字体大小继承自父元素,那么1em=父元素字体大小;rem是相对于根节点字体大小的单位,如果我们当前html文档的根节点字体大小为12px,那么1rem = 12px;vw是相对于当前视口宽度的单位,视口宽度被均分为100份,比如20vw,含义就是当前视口宽度的20%;vh是相对于当前视口高度的单位,与vw一样,不过它是相对于视口高度的。
11. 移动端的1px问题,为什么有时候1px看起来会比设计稿的要粗呢?
在高清屏出现之前,CSS里的px(逻辑像素)和手机物理像素是保持一致的,比如手机分辨率是375*750,那就代表手机横向有375个像素点,纵向有750个像素点,我们前端代码写多少像素就是多少像素。
随着屏幕分辨率的越来越高,有的手机尺寸没变,但是分辨率已经是之前的2倍甚至3倍,这时候就有了设备像素比dpr(devicePixelRatio)的概念,不同手机有不同的设备像素比,比如iPhone6的设备像素比就是2,那么当我们前端编写的代码为1px时,手机就会根据dpr,自动算出物理像素,也就是2px,也就是说我们代码中的1px到了真机就变成了2px。所以就造成了看起来偏粗的问题。
那如果我们直接写成0.5px呢?首先,在某些机型上这样做是没问题的,但是我们的PC端浏览器支持的最小像素为1px,某些旧版本浏览器还会把0.5px当作0px来渲染,就会造成各种各样的样式问题。
12. 那么请问如何实现一个0.5px的线
我们可以通过实现一个1px的线,然后通过CSS的2D转换进行缩放,就变成了0.5px。
<style>
.line {
width: 100%;
height: 1px;
background: #333;
transform: scaleY(0.5);
}
</style>
<div class="line"></div>
13. chrome浏览器支持最小字体为12px,如果我们需要一个10像素的字体怎么办呢?
和实现0.5px的线原理相同,我们可以通过CSS的2D转换将整个元素进行缩放相应的倍率,达到10px的效果。
<style>
.small {
width: 200%;
height: 200%;
font-size: 20px;
transform: scale(0.5);
transform-origin: 0 0;
}
</style>
<body>
<div class="small">我是10像素</div>
</body>
14. link标签和@import引入CSS的区别
link作为HTML标签,可以放在HTML文件任何位置,而@import只能放在除了@charset以外其他CSS的前面。link的兼容性更好,@import属于CSS2.1以后的规则,只在IE5以后才被支持。link作为HTML标签,可以使用js动态插入,@import则比较麻烦,只能通过js先插入一个style标签,然后在里面添加@import。link会最大限度的支持并行下载,但是@import如果嵌套过多时,就会导致串行加载,出现FOUC。- 都会
阻塞页面渲染,但是link标签会在HTML解析时同步解析,而@import则是在页面加载完毕之后才解析。
FOUC:用户定义样式表加载之前浏览器使用默认样式显示文档,用户样式加载渲染之后再重新显示文档,造成页面闪烁,在网速较慢或过多使用@import时出现,影响用户体验。
15. ::before和:before、:after、::after有什么区别?
没有什么区别,只是在CSS3中,为了更好的区分伪元素和伪类,才将伪元素都变成了冒号的写法。
16. position的值都有哪些,有什么区别?
position的值有static(默认)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)、sticky(粘性定位)。
static默认定位
在默认情况下,该元素使用正常的布局行为,与其他普通元素一样。
relative相对定位
在相对定位的情况下,该元素相对自身进行定位,在不改变left、top、right、bottom任何一个值的情况下,该元素位置保持不变,改变某一个方向的值,该元素会向反方向进行平移,原来的地方保持空白,依然占据文档流。
absolute绝对定位
在绝对定位的情况下,该元素相对于上一个不为static的元素进行定位,并且脱离标准文档流,文档流不为该元素预留空间,原来的位置被其他元素顶替。
fixed固定定位
在固定定位的情况下,该元素默认相对于视口的位置进行定位,并且脱离标准文档流,页面滚动时,该元素不会跟随页面滚动。当元素祖先的transform、perspective、filter、backdrop-filter属性非none时,该元素就会变成相对于该祖先进行定位。
sticky粘性定位
在粘性定位的情况下,该元素会先以relative的状态进行定位,当页面进行滚动,并且该元素到达阈值位置时,改变成fixed状态相对于最近一个拥有滚动机制的祖先进行定位(这个意思就是说,比如整个页面和当前元素的父元素都可以滚动,当我们滚动的是页面的时候,这个元素就会相对于页面进行定位,可能会出现sticky失效的情况)。
17. position: fixed;和position: sticky; 失效问题
当position: fixed;时,当元素祖先的transform、perspective、filter、backdrop-filter属性非none时,该元素就会变成相对于该祖先进行定位,就可能会造成fixed失效。
当position: sticky;时,如果发现sticky失效,我们应该检查该元素的父元素的overflow是否设置为hidden | scroll | auto;,如果设置了这些属性,而且除了父元素之外,还有其他元素可以滚动,如果用户操作其他元素的滚动,那么该元素就会相对于最近的滚动的元素进行sticky定位,就有可能会造成sticky失效。
18. overflow都有哪些值,分别有什么特点?
overflow属性决定了盒子内容溢出时的展示方式。
overflow的值有visible、hidden、scroll、auto、clip。
1. visible
visible是overflow属性的默认值,内容溢出时,不会被裁剪,不会为元素创建BFC。
2. hidden
hidden会对盒子内容超出盒子内边距(padding)以外的内容进行裁剪,不提供滚动条,不允许用户滚动,但是可以通过设置元素的scrollTop等来进行滚动,因此当前盒子依旧是一个滚动容器。
3. clip
clip的行为类似于hidden,只不过他也不可以通过编程方式进行滚动,设置了clip的盒子,已经不是一个滚动容器了,并且它不会为元素创建BFC。
4. scroll
scroll会使容器显示出来滚动条,即使没有内容溢出,滚动条依然会展示,有内容溢出时,用户可以手动滚动该区域。
auto默认状态下,如果没有内容溢出,行为就会类似visible(但是会创建新的BFC),如果有内容溢出就会类似scroll。
19. display的值都有哪些?分别代表了什么?
主要有以下几种:
1. block
会将该元素显示为块级元素,元素前后会带有换行符,可以设置宽高。
2. inline
为display的默认值,会将该元素显示为行内元素,元素前后没有换行符,设置宽高无效。
3. inline-block
会将该元素显示为行内块元素,元素不会独占一行,但是可以设置宽高。
4. list-item
会将该元素显示为列表元素(类似li)。
5. table
会将元素显示为块级表格(类似table)。
6. inline-table
会将元素显示为行内表格
7. flow-root
会将元素作为块级元素,并且创建一个新的BFC。
8. inherit
会将元素的display值继承自父元素。
9. none
会将元素隐藏。
10. flex
会将元素变为弹性盒子布局。
11. grid
会将元素变为网格盒子布局。
20. inline-block的元素为什么会和其他元素有间隙?如何解决?为什么img标签的display: inline;,但是可以设置宽高呢?
inline-block元素之间产生间隙,一种可能是因为我们代码中不小心添加进去了空格导致的,还有一种原因就是HTML把block元素前后的换行符转换成了空白字符,导致出现了间隙,我们可以通过设置font-size: 0;或者微调边距等方式解决该问题。
img标签之所以可以设置宽高,是因为它属于可替换元素,像我们的video、audio、iframe等标签都属于可替换元素。它们最终的展示效果不是由CSS控制的,可替换元素拥有内置宽高,他们可以设置width和height。他们的性质同设置了display:inline-block的元素一致。可参考MDN
21. 文本溢出怎么处理?
单行文本溢出显示省略号
<style>
.out {
width: 100px;
overflow: hidden;
text-overflow: ellipsis; /* 文字溢出显示省略号 */
white-space: nowrap; /* 强制文字不换行 */
}
</style>
<body>
<div class="out">
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈啊哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
</div>
</body>
多行文本溢出显示省略号(该方法仅可在-webkit内核浏览器中使用)
<style>
.out {
width: 100px;
display: -webkit-box;
-webkit-line-clamp: 2; /* 规定文字最多可以多少行 */
-webkit-box-orient: vertical; /* 规定内容应该被水平或垂直排列,目前是垂直排列 */
text-overflow: ellipsis;
overflow: hidden;
}
</style>
<body>
<div class="out">
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈啊哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈 哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
</div>
</body>
非-webkit内核浏览器多行文本溢出显示省略号处理
可以通过伪元素+定位或者伪元素+定位+浮动的方式进行实现。
22. CSS预处理器有什么好处
- 可以利用
嵌套的方式来编写CSS代码,层级更加直观; - 可以将
公共样式抽取成变量,方便复用;(CSS3也支持变量了) - 可以使用
mixin(混入),将一些CSS代码片段抽取出来,其它页面可以直接一行就能实现多行的功能。比如我们可以把实现0.5px的方法、水平/垂直居中的方法抽取成公共方法;
23. less和sass有什么区别
语法不同,因为这是两种不同的CSS预处理器,它们的一些语法是不一样的;功能不同,比如sass支持条件语句和循环语句,而less就不支持;less是在客户端进行的处理,而sass基于Node-Sass或者Dart-Sass(之前是Ruby),是在服务端进行的处理。
总的来说,sass的功能比less的更加强大,但是less相比于sass来说,也更加的轻量化,尤其是我们在用包管理器安装sass相关的插件时,经常会因为版本问题,产生很多奇奇怪怪的报错信息,极大的影响了我们的心智和时间。
24. 在vue中,我们给每一个组件的style设置scoped就可以达到隔离样式,它的原理是什么?
其实他是通过postcss-loader实现的,当我们给style标签加了scoped属性时,比如通过webpack编译代码时,会将我们当前页面的每个dom元素都添加一个[data-v-xxxxxx]的属性,CSS的选择器都变成属性选择器,比如我们之前的类名是.a,那么经过转换之后就变成了.a[data-v-xxxxxx],以保证和其它页面的类名保持不同,就不会造成样式冲突了。
25. 在项目中如何实现动画呢?
- 使用
transition,它的第一个参数可以指定我们CSS属性的名称,第一次渲染或者指定的CSS属性改变时,会触发过渡动画效果,它只有两个状态开始和结束,执行完毕之后就不会再次执行了,除非指定的CSS属性再次发生变化。 - 使用CSS3的
animation和@keyframes,我们可以通过@keyframes设置动画的关键帧以及动画名称,关键帧可以用from -> to或者百分比来表示,然后在需要使用动画的地方使用animation,指定要执行的动画名称、执行时间等信息,它可以指定动画结束之后是否循环执行,相比于transition来说,animation更加灵活。 - 使用
js动画,其实就是通过定时器,每一段时间改变一次元素的CSS属性,以达到动画的效果。
26. 如何优化动画性能?
- 尽量
减少使用js动画,因为频繁的通过js改变元素的属性,如果改动了宽高、边距等影响布局的属性,就会频繁的引起页面的回流,导致页面卡顿。 - 多使用
requestAnimationFrame,该方法会把每一帧中所有的DOM操作合并起来,在一次重绘或回流中执行完毕,并且该函数还会返回我们动画执行的状态,如果返回true,说明我们的动画在当前帧已经执行了,如果为false,说明当前帧没有执行,我们可以把动画放到下一帧去执行。 - 如果有元素需要
平移的操作,使用transform里面的translate属性代替left、right的操作,因为left和right的改变,会引起浏览器的重新计算布局,导致回流,而transform不在渲染进行完成,不会影响页面的渲染,效率会更高。
27. 动画执行的最小时间是多少?
这个和我们显示器的刷新率有关,比如我们的显示器是60HZ,那么理论上浏览器每秒钟会重绘60次,因此最平滑的动画效果理论上应该是1000ms/60,大约是16.7ms。
28. 实现双栏布局
1. 浮动或者定位
左元素固定宽度的情况下使用左浮动,或者相对于父元素进行绝对定位,右元素的margin-left设置为浮动元素的宽度。
2. calc+inline-block
左元素或右元素固定宽度的情况下,且两个元素都为行内块级元素,对其中宽度不固定的元素使用calc(100% - 固定宽度)计算出宽度。
3. flex布局(最常用)
<style>
.out {
display: flex;
}
.left {
width: 200px;
height: 200px;
background: aquamarine;
}
.right {
flex: 1;
background: skyblue;
}
</style>
<body>
<div class="out">
<div class="left"></div>
<div class="right"></div>
</div>
</body>
29. 实现三栏布局
1. calc方式
三个子元素设置display: inline-block;,两个元素固定宽度时,另一个使用calc计算宽度。
2. flex布局
两个元素固定宽度时,父元素设置display: flex;,另一个元素设置flex: 1;。
3. 定位
两个元素固定宽度时,中间和右边的元素相对于父级元素进行绝对定位,中间元素的left设置为左边元素的宽度,右边元素的right设置为0。
4. 圣杯布局(float)
圣杯布局左右区域宽高固定,中间宽度自适应,使用float+margin+position,并且优先渲染中间区域。
-
因为要
优先渲染中间区域,因此我们编写HTML代码时应该把中间区域放在最前面,然后调整左右区域的位置。 -
我们让中间区域宽度
占据100%,左右元素宽度固定,父元素使用padding预留出左右元素的位置。 -
让三个元素都进行
左浮动,这时因为中间区域占据了父元素的100%,左右元素会被挤到下一行,将left的margin-left设置为-100%,它就会跑到父元素最左边内边距的右边,然后再通过relative相对定位,相对于自身向左平移自身的宽度,就到达了最左边。right的margin-left设置为负的自身宽度,这时候它会跑到父元素最右边内边距的左边,然后通过relative,让他向右平移自己的宽度,就移动到了右边。<style> .out { width: 100%; height: 600px; padding: 0 200px; } .center { background: blue; width: 100%; height: 100%; float: left; } .left { width: 200px; height: 100%; background: red; float: left; margin-left: -100%; position: relative; left: -200px; } .right { width: 200px; height: 100%; background: green; float: left; margin-left: -200px; position: relative; left: 200px; } </style> <body> <div class="out"> <div class="center"></div> <div class="left"></div> <div class="right"></div> </div> </body>
5. 双飞翼布局(float)
-
双飞翼布局是圣杯布局的改进版,去掉了圣杯布局中的position操作。 -
将
中间容器包裹一层元素,通过设置中间容器的margin来给左右元素腾位置,而不再通过父元素的padding给左右容器腾位置。这样左元素设置margin-left: -100%的时候,就会直接跑到页面最左边了。<style> .out { width: 100%; height: 600px; } .center-wrap { float: left; width: 100%; height: 100%; } .center { margin: 0 200px; height: 100%; background: blue; } .left { width: 200px; height: 100%; background: red; float: left; margin-left: -100%; } .right { width: 200px; height: 100%; background: green; float: left; margin-left: -200px; } </style> <body> <div class="out"> <div class="center-wrap"> <div class="center"></div> </div> <div class="left"></div> <div class="right"></div> </div> </body>
30. 实现居中布局
1. 利用弹性布局
<style>
.out {
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.inner {
width: 200px;
height: 200px;
background: aquamarine;
}
</style>
<body>
<div class="out">
<div class="inner"></div>
</div>
</body>
2. 在知道内层盒子宽高时,利用绝对定位
<style>
.out {
width: 100vw;
height: 100vh;
position: relative;
}
.inner {
width: 200px;
height: 200px;
background: aquamarine;
position: absolute;
top: 50%;
left: 50%;
margin-left: -100px;
margin-top: -100px;
}
</style>
<body>
<div class="out">
<div class="inner"></div>
</div>
</body>
3. 在不知道盒子内层宽高时,利用绝对定位
<style>
.out {
width: 100vw;
height: 100vh;
position: relative;
}
.inner {
width: 200px;
height: 200px;
background: aquamarine;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
<body>
<div class="out">
<div class="inner"></div>
</div>
</body>
31. 层叠上下文
首先看一下MDN上对层叠上下文的解释:
我们假定用户正面向(浏览器)视窗或网页,而 HTML 元素沿着其相对于用户的一条虚构的 z 轴排开,层叠上下文就是对这些 HTML 元素的一个三维构想。众 HTML 元素基于其元素属性按照优先级顺序占据这个空间。
意思就是说,假设我们把当前的页面当作是一个z轴,不同的元素可能在当前页面上的层级不同,而这种不同的层级,就形成了所谓的层叠上下文。
z-index
某些元素的渲染顺序是可以由一个z-index的CSS属性控制,而这个属性就可以让他们形成一个层叠上下文。
如何才能形成层叠上下文
-
根元素(
<html>); -
position的值为absolute或者relative,并且z-index的值不为auto的元素; -
position的值为fixed或者sticky的元素; -
flex容器的子元素,且z-index !== auto; -
grid容器的子元素,且z-index !== auto; -
opacity的值小于1的元素;
层叠等级
层叠等级规定了在同一层叠上下文中,各个内部元素或内部其他层叠上下文在当前层叠上下文Z轴排列的顺序。
不同层叠等级的元素在层叠上下文中由上到下的排列顺序如下:
- z-index>0的元素
- z-index: auto;/z-index: 0的元素
- inline/inline-block盒子
- float浮动元素
- block块级元素
- z-index<0的元素
- 当前层叠上下文的backgroung以及border
有何特点
- 层叠上下文中
可以包含其他的层叠上下文; - 设置的
z-index只在当前层叠上下文中有用,比如我们有a,b,c三个元素,它们在同一父元素中,比如a,b在当前层叠上下文的z-index为2,而c为1,这时c又开辟了一个新的层叠上下文,然后它的子元素也设置了z-index,并且设置了一个更大的值,但是c和它的子元素永远会排在a和b的后面,因为它的子元素的层级只在当前形成的层叠上下文中有效; 没有设置z-index的元素,它的层级会由当前所在层叠上下文的等级来决定。