备战前端面试—CSS篇
CSS 基础
盒模型
考点1:CSS 盒子模型
说说你对盒子模型的理解?
当浏览器解析完 HTML,构建布局树后,渲染引擎根据当前标准之一的 CSS 基础盒模型,将所有元素表示为一个个矩形的盒子。
一个盒子由四个部分组成:content、padding、border、margin。
content:即实际的内容。显示文本和图像。
padding:即内边距,清除内容周围的区域,是透明的,取值不能为负。
border:围绕元素内容内边距的一条或多条线,由粗细、样式、颜色三部分组成。
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|inherit:
- content-box 默认值,元素的 width/height 不包含padding,border,与标准盒子模型表现一致
- border-box 元素的 width/height 包含 padding,border,与怪异盒子模型表现一致
- inherit 指定 box-sizing 属性的值,应该从父元素继承
BFC
考点1:BFC 规则
谈谈你对 BFC 的理解?
BFC(Block Formatting Context)
,即块级格式化上下文。是一块独立的渲染区域,决定了其中的子元素如何定位,以及与外界元素如何相互作用的规则:- 内部的盒子在垂直方向上一个接一个排列。
- 同一BFC内部两个盒子如果都具有margin,这部分空间发生重叠,取其中最大值。
- 每个元素的 margin-box 的左边与包含块的 border-box 左边相接触,浮动元素也是如此。
- BFC 区域不与 float box 重合。
- BFC 内部空间与外部独立。
- 计算 BFC 高度时,浮动子元素也参与计算。
考点2:BFC 触发
怎么触发 BFC?触发条件有哪些?
触发
BFC
的条件包含不限于:- 根元素
- 浮动元素,float:left/right
- overflow 不为 visible
- display 为 inline-block、table、inline-table、flex、inline-flex、grid、inline-grid
- position的值为 absolute 或 fixed
考点3:BFC 应用
BFC 有哪些应用场景?
防止 margin 重叠(塌陷)
<style> .wrap { overflow: hidden;// 新的BFC } p { color: #f55; background: #fcc; width: 200px; line-height: 100px; text-align:center; margin: 100px; } </style> <body> <p>Haha</p > <div class="wrap"> <p>Hehe</p > </div> </body>
自适应多栏布局
<style> body { width: 300px; position: relative; } .aside { width: 100px; height: 150px; float: left; background: #f66; } .main { height: 200px; background: #fcc; overflow: hidden; } </style> <body> <div class="aside"></div> <div class="main"></div> </body>
清除浮动
<style> .par { border: 5px solid #fcc; width: 300px; overflow: hidden; } .child { border: 5px solid #f66; width:100px; height: 100px; float: left; } </style> <body> <div class="par"> <div class="child"></div> <div class="child"></div> </div> </body>
选择器
考点1:选择器分类
有哪些 css 选择器?
id 选择器:
#box
,选择 id 为 box 的元素类选择器:
.class
,选择类名为 class 的元素伪类选择器:
:link :选择未被访问的链接 :visited:选取已被访问的链接 :active:选择活动链接 :hover :鼠标指针浮动在上面的元素 :focus :选择具有焦点的 // CSS3中新增 :first-child:父元素的首个子元素 :first-of-type 表示一组同级元素中其类型的第一个元素 :last-of-type 表示一组同级元素中其类型的最后一个元素 :only-of-type 表示没有同类型兄弟元素的元素 :only-child 表示没有任何兄弟的元素 :nth-child(n) 根据元素在一组同级中的位置匹配元素 :nth-last-of-type(n) 匹配给定类型的元素,基于它们在一组兄弟元素中的位置,从末尾开始计数 :last-child 表示一组兄弟元素中的最后一个元素 :root 设置HTML文档 :empty 指定空的元素 :enabled 选择可用元素 :disabled 选择被禁用元素 :checked 选择选中的元素 :not(selector) 选择与 <selector> 不匹配的所有元素
伪元素选择器:
:first-letter :用于选取指定选择器的首字母 :first-line :选取指定选择器的首行 :before : 选择器在被选元素的内容前面插入内容 :after : 选择器在被选元素的内容后面插入内容
标签选择器:
div
,选择所有标签为 div 的元素后代选择器:
#box div
,选择 id 为 box 的元素内部所有的标签为 div 的元素子选择器:
.one>.one_1
,选择父元素为 .one 的所有 .one_1 的元素兄弟选择器:
.one+.two
,选择紧接在 .one 之后的所有 .two 元素群组选择器:
div,p
,选择标签为 div 和 p 的所有元素属性选择器:
[attribute] 选择带有attribute属性的元素 [attribute=value] 选择所有使用attribute=value的元素 [attribute~=value] 选择attribute属性包含value的元素 [attribute|=value]:选择attribute属性以value开头的元素
考点2:优先级
CSS 选择器的优先级?
总体而言:
!important
> 内联 > ID 选择器 > 类选择器 > 标签选择器具体计算时,优先级是由 A 、B、C、D 的值来决定的,其中它们的值计算规则如下:
- 如果存在内联样式,A = 1,否则 A = 0
- B = ID 选择器出现的次数
- C = 类选择器和属性选择器和伪类选择器出现的次数
- D = 标签选择器和伪元素选择器出现的次数
比较时:
- 从左往右依次比较,较大者优先级高
- 当前位相等,继续移动到下一位比较
- 四位全部相等,后定义的覆盖先定义的
考点3:继承
CSS 中哪些属性可以继承?
关于继承属性,可以分为:
字体属性:
font:组合字体 font-family:规定元素的字体系列 font-weight:设置字体的粗细 font-size:设置字体的尺寸 font-style:定义字体的风格 font-variant:偏大或偏小的字体
文本属性:
text-indent:文本缩进 text-align:文本水平对刘 line-height:行高 word-spacing:增加或减少单词间的空白 letter-spacing:增加或减少字符间的空白 text-transform:控制文本大小写 direction:规定文本的书写方向 color:文本颜色
可见性属性:
visibility
表格布局属性:
caption-side:定位表格标题位置 border-collapse:合并表格边框 border-spacing:设置相邻单元格的边框间的距离 empty-cells:单元格的边框的出现与消失 table-layout:表格的宽度由什么决定
列表属性:
list-style-type:文字前面的小点点样式 list-style-position:小点点位置 list-style:以上的属性可通过这属性集合
光标属性:
cursor:箭头可以变成需要的形状
CSS 中不能继承的属性?
display 属性:元素应该生成的框的类型
文本属性:vertical-align、text-decoration、text-shadow、white-space
盒子模型属性:宽度、高度、内外边距、边框等
背景属性:背景图片、颜色、位置等
定位属性:浮动、清除浮动、定位 position 等
生成内容属性:content、counter-reset、counter-increment
轮廓样式属性:outline-style、outline-width、outline-color、outline
页面样式属性:size、page-break-before、page-break-after
层叠上下文
考点1:层叠上下文概念
什么是层叠上下文?其中的元素在 z 轴上的顺序如何决定?
层叠上下文是 HTML 中一个三维的概念。每个盒模型的位置是三维的,分别是平面画布上的X轴,Y轴以及表示层叠的Z轴。一般情况下,元素在页面上沿X轴Y轴平铺,我们察觉不到它们在Z轴上的层叠关系。而一旦元素发生堆叠,这时就能发现某个元素可能覆盖了另一个元素或者被另一个元素覆盖。
在同一个层叠上下文中,层叠层级(stacking level)描述定义的是该层叠上下文中的层叠上下文元素在 Z 轴上的上下顺序。层叠等级的比较只有在当前层叠上下文元素中才有意义。
考点2:层叠上下文规则
层叠上下文按照什么规则排列?
层叠顺序(stacking order)表示元素发生层叠时候有着特定的垂直显示顺序。
- 每一个层叠顺序规则适用于一个完整的层叠上下文元素。
- 位于最低层级的border/background指的是层叠上下文元素的边框和背景色。
- 比较规则
- 不同层叠上下文的元素,比较他们所在层叠上下文的层级,随所在层叠上下文整体进行排列。
- 同一个层叠上下文中,按照层叠顺序,层叠层级越高的元素在 z 轴越上面。
- 当层叠层级和层叠顺序都相同,在DOM流中处于后面的元素会覆盖前面的元素。
- 为什么定位元素会层叠在普通元素的上面?
其根本原因就在于,元素一旦成为定位元素,其 z-index 就会自动生效,此时其 z-index 就是默认的auto,也就是0级别,根据上面的层叠顺序表,就会覆盖 inline 或 block 或 float 元素。
而不支持 z-index 的层叠上下文元素天然 z-index:auto 级别,也就意味着,层叠上下文元素和定位元素是一个层叠顺序的,于是当他们发生层叠的时候,在DOM流中处于后面的元素会覆盖前面的元素。
布局
布局实战
考点1:居中
元素水平垂直居中的方法有哪些?如果元素不定宽高呢?
根据元素标签的性质,可以分为:
- 内联元素居中布局
- 块级元素居中布局
内联元素居中布局:
水平居中:
text-align: center;
设置父元素 display: flex; justify-content: center;
垂直居中:
需要父元素高度确定
line-height: 父元素的height;
多行文本情况 设置父元素 display: table-cell; vertical-align: middle;
块级元素居中布局:
水平居中:
宽度已知:
margin: 0 auto;
父元素相对定位 position: relative; 子元素绝对定位 position: absolute; margin-left: -1/2 元素width;
宽度未知:
display: table; margin: 0 auto;
display: inline-block; text-align: center;
display: flex; justify-content: center;
父元素相对定位 display: relative; 子元素绝对定位 display: absolute; 移动到中心 left: 50%; 再移动自身宽的一半 transform: translateX(-50%);
垂直居中:
父元素相对定位 display: relative; 子元素绝对定位 display: absolute; margin: auto
父元素 flex display: flex; 子元素 margin: auto
父元素相对定位 display: relative; 子元素绝对定位 display: absolute; 移动到中心 top: 50%; 再移动自身高的一半 transform: translateY(-50%);
考点2:flex布局
说说 flexbox(弹性盒布局模型),以及适用场景?
Flexible Box
简称flex
,意为”弹性布局”,可以简便、完整、响应式地实现各种页面布局。采用Flex布局的元素,称为
flex
容器container
,它的所有子元素自动成为容器成员,称为flex
项目item
。容器中默认存在两条轴,主轴和交叉轴,呈90度关系。
项目默认沿主轴排列,通过
flex-direction
来决定主轴的方向。.container { flex-direction: row | row-reverse | column | column-reverse; }
通过
flex-wrap
决定容器内项目是否可换行。.container { flex-wrap: nowrap | wrap | wrap-reverse; }
justify-content
定义了项目在主轴上的对齐方式。.box { justify-content: flex-start | flex-end | center | space-between | space-around; }
align-items
定义项目在交叉轴上如何对齐。.box { align-items: flex-start | flex-end | center | baseline | stretch; }
align-content
定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。.box { align-content: flex-start | flex-end | center | space-between | space-around | stretch; }
order
定义项目的排列顺序。数值越小,排列越靠前,默认为 0。.item { order: <integer>; }
flex-grow
和flex-shrink
分别定义了项目的放大缩小比例。.item { flex-grow: <number>; flex-shrink: <number>; /* default 1 */ }
应用场景:
在移动端、小程序的开发,都建议使用
flex
进行布局
考点3:grid 布局
介绍一下grid网格布局
Grid
布局即网格布局,是一个二维的布局方式,由纵横相交的两组网格线形成的框架性布局结构,能够同时处理行与列。grid-template-columns
属性设置列宽,grid-template-rows
属性设置行高。.wrapper { display: grid; /* 声明了三列,宽度分别为 200px 200px 200px */ grid-template-columns: 200px 200px 200px;通过使用repeat()函数,可以简写重复的值 grid-gap: 5px; /* 声明了两行,行高分别为 50px 50px */ grid-template-rows: 50px 50px; }
grid-row-gap
属性、grid-column-gap
属性分别设置行间距和列间距。grid-gap
属性是两者的简写形式。grid-template-areas
属性用于定义区域,一个区域由一个或者多个单元格组成。.container { display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; grid-template-areas: 'a b c' 'd e f' 'g h i'; } /*如果某些区域不需要利用,则使用"点"(.)表示 */
划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。
顺序就是由
grid-auto-flow
决定,默认为行,代表”先行后列”,即先填满第一行,再开始放入第二行。justify-items
属性设置单元格内容的水平位置(左中右),align-items
属性设置单元格的垂直位置(上中下)。.container { justify-items: start | end | center | stretch; align-items: start | end | center | stretch; }
justify-content
属性是整个内容区域在容器里面的水平位置(左中右),align-content
属性是整个内容区域的垂直位置(上中下)。.container { justify-content: start | end | center | stretch | space-around | space-between | space-evenly; align-content: start | end | center | stretch | space-around | space-between | space-evenly; }
grid-auto-rows
与grid-auto-columns
专门用于指定隐式网格的宽高。grid-column-start
属性、grid-column-end
属性、grid-row-start
属性以及grid-row-end
属性指定网格项目所在的四个边框,分别定位在哪根网格线,从而指定项目的位置。- grid-column-start 属性:左边框所在的垂直网格线
- grid-column-end 属性:右边框所在的垂直网格线
- grid-row-start 属性:上边框所在的水平网格线
- grid-row-end 属性:下边框所在的水平网格线
grid-area
属性指定项目放在哪一个区域。.item-1 { grid-area: e; }
justify-self
属性设置单元格内容的水平位置(左中右),跟justify-items
属性的用法完全一致,但只作用于单个项目。align-self
属性设置单元格内容的垂直位置(上中下),跟align-items
属性的用法完全一致,也是只作用于单个项目。.item { justify-self: start | end | center | stretch; align-self: start | end | center | stretch; }
响应式布局
考点1:单位
说说em/px/rem/vh/vw区别?
传统开发中,我们只会用到
px、%、em
这几个单位,且拥有良好的兼容性。从 CSS3 开始,浏览器对计量单位的支持又提升到了新的境界,新增了
rem
、vh
、vw
、vm
等一些新的计量单位。利用这些新单位可以帮助我们开发良好的响应式界面,适应多种不同分辨率的终端设备。
在 CSS 中,单位可分为相对单位和绝对单位:
CSS单位 相对长度单位 em、ex、ch、rem、vw、vh、vmin、vmax、% 绝对长度单位 cm、mm、in、px、pt、pc - px:表示像素的单位。每个像素点大小等同。
- em:相对长度单位。相对于当前对象内文本的字体尺寸,如果未设置为浏览器默认字体尺寸(1em = 16px)。为了简化
font-size
的换算,我们需要在css
中的body
选择器中声明font-size
=62.5%
,这就使 em 值变为16px*62.5% = 10px
。特点:em 的值并不是固定的,em 会继承父级元素的字体大小。 - rem:相对单位,相对的只是HTML根元素
font-size
的值。 - vw/vh ,就是根据窗口的宽度,分成100等份,100vw就表示满宽,50vw就表示一半宽。(vw 始终是针对窗口的宽),同理,vh 则为窗口的高度。
%
,相对于父元素的宽高。
考点2:响应式设计
什么是响应式设计?响应式设计的基本原理是什么?如何做?
响应式网站设计(Responsive Web design)是一种网络页面设计布局,页面的设计与开发应当根据用户行为以及设备环境(系统平台、屏幕尺寸、屏幕定向等)进行相应的响应和调整。
原理:
响应式设计的基本原理是通过媒体查询检测不同的设备屏幕尺寸做处理,为了处理移动端,页面头部必须有
meta
声明viewport
。实现方式:
媒体查询
设置不同类型的媒体条件,并根据对应的条件,给相应符合条件的媒体调用相对应的样式表。
@media screen (min-width: 375px) and (max-width: 600px) { body { font-size: 18px; } }
百分比流式布局
通过百分比单位 “
%
“ 来实现响应式的效果。比如当浏览器的宽度或者高度发生变化时,通过百分比单位,可以使得浏览器中的组件的宽和高随着浏览器的变化而变化,从而实现响应式的效果。但每个属性都使用百分比,会造成布局的复杂度,所以不建议使用百分比来实现响应式。
vh/vw
vw
表示相对于视图窗口的宽度,vh
表示相对于视图窗口高度。 任意层级元素,在使用vw
单位的情况下,1vw
都等于视图宽度的百分之一。与百分比布局类似,同样不推荐。rem
rem
是相对于根元素html
的font-size
属性,默认情况下浏览器字体大小为16px
,此时1rem = 16px
。
可以利用媒体查询,针对不同设备分辨率改变font-size
的值:@media screen and (max-width: 414px) { html { font-size: 18px } } @media screen and (max-width: 375px) { html { font-size: 16px } } @media screen and (max-width: 320px) { html { font-size: 12px } }
除此之外,我们还可以利用主流
UI
框架,如:element ui
、antd
提供的栅格布局实现响应式。
其他
图片资源
考点1:图片格式
常见的图片的格式?各有什么特点?
图片可分为位图和矢量图。
位图就是用像素点拼起来的图也叫点阵图,平时我们用到的
png
、jpg
等图片就是位图。矢量图,也叫做向量图。矢量图并不纪录画面上每一点的信息,而是纪录了元素形状及颜色的算法,常见的就是
svg
格式。而图片的压缩类型可分为无压缩、有损压缩、无损压缩。
无压缩的图片格式不对图片数据进行压缩处理,能准确地呈现原图片。例如
BMP
格式的图片。有损压缩指在压缩文件大小的过程中,损失了一部分图片的信息,也即降低了图片的质量(即图片被压糊了),并且这种损失是不可逆的。常见的有损压缩手段是按照一定的算法将临近的像素点进行合并,压缩算法不会对图片所有的数据进行编码压缩,而是在压缩的时候,去除了人眼无法识别的图片细节。因此有损压缩可以在同等图片质量的情况下大幅降低图片的体积。例如
jpg
格式的图片使用的就是有损压缩。无损压缩在压缩图片的过程中,图片的质量没有任何损耗。我们任何时候都可以从无损压缩过的图片中恢复出原来的信息。压缩算法对图片的所有的数据进行编码压缩,能在保证图片的质量的同时降低图片的体积。例如
png
、gif
使用的就是无损压缩。类型 动画 压缩类型 透明度 优点 GIF 支持 无损压缩 支持 支持 256 颜色,文件体积小 JPG/JPEG 不支持 有损压缩 不支持 采用有损压缩,压缩后体积更小 PNG 不支持 无损压缩 支持 支持8位、24位、32位彻底消除锯齿边缘 APNG 支持 无损压缩 支持 支持png的所有优点,支持动画 WEBP 不支持 有损压缩/无损压缩 支持 集成了所有图片的优点,文件体积最小 SVG 支持 有损压缩/无损压缩 支持 是纯粹的 XML,尺寸更小,可压缩性更强
考点2:图片加载优化
说说常用的图片优化方法?
使用雪碧图(基本废弃):
优点:把诸多小图片合成一张大图,利用
backround-position
属性值来确定图片呈现的位置,可以有效的较少请求个数,而且,而不影响开发体验,使用构建插件可以做到对开发者透明。适用于页面图片多且丰富的场景。缺点:生成的图片体积较大,减少请求个数同时也增加了图片大小,不合理拆分将不利于并行加载。在SPA 应用盛行的现在已基本废弃。
使用 base64 格式:
优点:将图片转换为 base64 编码字符串 inline 到页面或 css 中。base64 可以随着 HTML 的下载同时下载到本地减少 https 请求。
缺点:如果图片较大,图片的色彩层次比较丰富,则不适合使用这种方式,因为该图片经过 base64 编码后的字符串非常大,会明显增大 HTML 页面的大小,从而影响加载速度。
使用 CDN 图片:
优点:CDN 即内容分发网络,能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。CDN 节点解决了跨运营商和跨地域访问的问题,访问延时大大降低。
缺点:对SEO优化是有很大影响,且成本较高。
图片懒加载:
优点:减少资源的加载,页面启动只加载首屏的图片,这样能明显减少服务器的压力和流量,也能够减小浏览器的负担。同时防止并发加载的资源过多而阻塞 js 的加载,影响整个网站的启动,影响用户体验。
缺点:浏览器兼容问题。
图片预加载:
优点:在一些需要展示大量图片的网站,将图片提前加载到本地缓存中,从而提升用户体验。
缺点:牺牲服务器换取性能。
渐进式图片:
优点:在高画质图像加载完之前会先显示低画质版本。与骨架屏技术类似,对于用户体验更加友好。
缺点:消耗 CPU 和内存(几乎可忽略)。
杂项
考点1:常用 CSS 操作
css中,有哪些方式可以隐藏页面元素?区别?
通过
css
实现隐藏元素方法有如下:display:none visibility:hidden opacity:0 height:0,width:0 position:absolute
- display:none,最常用,设置后元素将从文档中消失,不占据空间。会导致浏览器回流重绘。元素自身的绑定事件不会触发,也不会有过渡效果。
- visibility:hidden,隐藏元素,元素在 DOM 结构中仍存在,占据空间。子元素可复原。仅触发重绘。元素自身的绑定事件不会触发。
- opacity:0,设置元素透明度为 0,在视觉上是隐藏的。占据空间。子元素不可复原。仅触发重绘。元素自身的绑定事件可触发。被其遮蔽的元素不能触发绑定事件。
- height、width属性为 0,将元素的
margin
,border
,padding
,height
和width
等影响元素盒模型的属性设置成 0,如果元素内有子元素或内容,还应该设置其overflow:hidden
来隐藏其子元素。不占据空间,会触发回流重绘。元素自身的绑定事件不会触发。 - position:absolute,将元素移出可视区域,不影响页面布局。
rgba() 和 opacity 实现效果上的区别?
rgba() 和 opacity 都能实现透明效果,但最大的不同是 opacity 作用于元素,以及元素内的所有内容的透明度,而 rgba() 只作用于元素的颜色或其背景色。
link 与 @import 的区别?
从属关系区别:
@import
是 CSS 提供的语法规则,只有导入样式表的作用;link
是 HTML 提供的标签,不仅可以加载 CSS 文件,还可以定义 RSS、rel 连接属性等。加载顺序区别:加载页面时,
link
标签引入的 CSS 被同时加载;@import
引入的 CSS 将在页面加载完毕后被加载。兼容性区别:
@import
是 CSS2.1 才有的语法,故只可在 IE5+ 才能识别;link
标签作为 HTML 元素,不存在兼容性问题。DOM可控性区别:可以通过 JS 操作 DOM ,插入
link
标签来改变样式;由于DOM方法是基于文档的,无法使用@import
的方式插入样式。
后记
未完待续。
- Post link: https://blog.sticla.top/2021/08/16/front-end-interview-review-css/
- Copyright Notice: All articles in this blog are licensed under unless otherwise stated.
GitHub Issues