CSS 优化和提高性能的方法有哪些?
加载性能:
css
压缩
, 减小文件体积。css
单一
样式 margin-bottom:bottom; margin-left:left;比 margin:top 0 bottom 0;执行效率高。减少使用
@import
,建议使用link
,因为 link 在页面加载时一起加载,import 是页面加载完成之后再加载。两者都是外部引用 CSS 的方式,它们的区别如下: link 是 XHTML 标签,除了加载 CSS 外,还可以定义 RSS 等其他事务; @import 只能加载 CSS。 link 引用 CSS 时,在页面载入时同时加载; @import 需要页面网页完全载入以后加载。 link 是 XHTML 标签,无兼容问题; @import 是在 CSS2.1 提出的,低版本的浏览器不支持。 link 支持使用 Javascript 控制 DOM 去改变样式; @import 不支持。
选择器性能:
关键
选择器, 减少层级, 最高不超过3层- 尽量使用
class
, 避免使用html标签选择 - 少使用
后代
选择器, 后代选择器开销高
- 避免对
可继承
的属性重复
定义 - 避免使用
通配
规则, 只对需要的元素进行处理`
渲染性能:
- 慎重使用高性能属性:
浮动
、定位
。 - 尽量减少页面
重排
、重绘
。 - 属性值为 0 时,不加
单位
。 - 属性值为浮动小数 0.**,可以
省略
小数点之前的 0。 - 不使用
@import
前缀,它会影响 css 的加载速度
。
可维护性:
- 抽离
css
, 提高可复用性
。 - 样式与内容
分离
, 提高可维护性
。
对 CSS 工程化的理解
CSS 工程化是为了解决以下问题:宏观设计:
CSS代码如何组织、如何拆分、模块结构怎样设计? 编码优化:
怎样写出更好的 CSS ? 构建:
如何处理我的 CSS,才能让它的打包结果最优? 可维护性:
容易变更, 容易接手
以下三个方向都是时下比较流行的、普适性非常好的 CSS 工程化实践:预处理器:
Less、 Sass 等; 后处理器:
PostCSS Webpack loader 等
。
如何用 Webpack 实现对 CSS 的处理:css-loader:
导入 CSS 模块,对 CSS 代码进行编译处理; style-loader:
创建 style 标签,把 CSS 内容写入标签。
在实际使用中,css-loader 的执行顺序一定要安排在 style-loader 的前面
。因为只有完成了编译过程,才可以对 css 代码进行插入;若提前插入了未编译的代码,那么 webpack 是无法理解这坨东西的,它会无情报错。
z-index 属性在什么情况下会失效
通常 z-index
的使用是在有两个重叠
的标签,z-index 值越大就越是在上层。z-index 元素的 position
属性需要是 relative
,absolute
或是 fixed
。
z-index 属性在下列情况下会失效:
- 父元素 position 为
relative
时,子元素的 z-index 失效。解决:父元素 position 改为 absolute 或 static; - 元素没有设置 position 属性为非 static 属性。解决:设置该元素的 position 属性为 relative,absolute 或是 fixed;
- 元素在设置 z-index 的同时还设置了
float
浮动。解决:去除 float,改为display:inline-block
;
常见的 CSS 布局单位
像素px 基本
布局单位 百分比% ,相对于父元素
的百分比
,从而实现响应式的效果。 em 相对于父元素的文本的倍数
。如果父元素未设置 font-size
,则相对于浏览器的默认
字体尺寸(默认 16px)。 rem 相对于根元素 font-size
的倍数。作用:利用 rem 可以实现简单的响应式
布局,可以利用 html 元素中字体的大小与屏幕间的比值来设置 font-size 的值,以此实现当屏幕分辨率变化时让元素也随之变化。
vw: 相对于视窗的宽度,视窗宽度是 100vw; vh: 相对于视窗的高度,视窗高度是 100vh; vmin: vw 和 vh 中的较小值; vmax: vw 和 vh 中的较大值;
TIP
vw
和百分比的区别是: vw
相对于视窗, %
相对于父元素
px、em、rem 的区别及使用场景
三者的区别:
px
是固定的像素,一旦设置了就无法因为适应页面大小而改变。em
和rem
相对于 px 更具有灵活性,他们是相对
长度单位,其长度不是固定的,更适用于响应式布局。- em 是相对于其
父元素
来设置字体大小,这样就会存在一个问题,进行任何元素设置,都有可能需要知道他父元素的大小。而 rem 是相对于根元素
,这样就意味着,只需要在根元素确定一个参考值。
使用场景:
- 对于只需要适配
少部分
移动设备,且分辨率对页面影响不大的,使用px
即可 。 - 对于需要适配
各种
移动设备,使用rem
,例如需要适配 iPhone 和 iPad 等分辨率差别比较挺大的设备。
如何根据设计稿进行移动端适配?
移动端适配主要有两个
维度:
适配不同像素密度,针对不同的像素密度
,使用 CSS 媒体查询
,选择不同精度的图片,以保证图片不会失真
; 适配不同屏幕大小,由于不同的屏幕有着不同的逻辑像素
大小,所以如果直接使用 px
单位,会使得开发的页面在某一款手机上可以准确显示,但是在另一款手机上就会失真
。为了适配不同屏幕的大小,应按照比例来还原设计稿的内容。
为了能让页面的尺寸自适应,可以使用 rem
,em
,vw
,vh
等相对单位
。
响应式设计的概念及基本原理
响应式网站
是指一个网站能够兼容多个终端
。
关于原理: 基本原理是通过媒体查询(@media)查询检测不同的设备屏幕尺寸做处理。
关于兼容: 页面头部必须有 meta
声明的 viewport
。
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
为什么需要清除浮动?清除浮动的方式
浮动的定义: 非 IE 浏览器下,容器不设高度且子元素浮动时,容器高度不能被内容撑开。 此时,内容会溢出到容器外面而影响布局。这种现象被称为浮动(溢出)。
浮动的工作原理:
- 浮动元素脱离文档流,不占据空间(引起“高度塌陷”现象)
- 浮动元素碰到包含它的边框或者其他浮动元素的边框停留
浮动元素可以左右移动,直到遇到另一个浮动元素或者遇到它外边缘的包含框。浮动框不属于文档流中的普通流,当元素浮动之后,不会影响块级元素的布局,只会影响内联元素布局。此时文档流中的普通流就会表现得该浮动框不存在一样的布局模式。当包含框的高度小于浮动框的时候,此时就会出现“高度塌陷”。
浮动元素引起的问题?
- 父元素的高度无法被撑开,影响与父元素同级的元素
- 与浮动元素同级的非浮动元素会跟随其后
- 若浮动的元素不是第一个元素,则该元素之前的元素也要浮动,否则会影响页面的显示结构
使用 clear 属性清除浮动的原理?
使用 clear 属性清除浮动,其语法如下:
clear: none|left|right|both
如果单看字面意思,clear:left 是“清除左浮动”,clear:right 是“清除右浮动”,实际上,这种解释是有问题的,因为浮动一直还在,并没有清除。
官方对 clear 属性解释:“元素盒子的边不能和前面的浮动元素相邻”,对元素设置 clear 属性是为了避免浮动元素对该元素的影响,而不是清除掉浮动。
还需要注意 clear 属性指的是元素盒子的边不能和前面的浮动元素相邻,注意这里“前面的”3 个字,也就是 clear 属性对“后面的”浮动元素是不闻不问的。考虑到 float 属性要么是 left,要么是 right,不可能同时存在,同时由于 clear 属性对“后面的”浮动元素不闻不问,因此,当 clear:left 有效的时候,clear:right 必定无效,也就是此时 clear:left 等同于设置 clear:both;同样地,clear:right 如果有效也是等同于设置 clear:both。由此可见,clear:left 和 clear:right 这两个声明就没有任何使用的价值,至少在 CSS 世界中是如此,直接使用 clear:both 吧。
一般使用伪元素的方式清除浮动:
.clear::after{
content: '';
display: block;
clear: both;
}
clear 属性只有块级元素才有效的,而 ::after 等伪元素默认都是内联水平,这就是借助伪元素清除浮动影响时需要设置 display 属性值的原因。
对 BFC 的理解,如何创建 BFC
先来看两个相关的概念:
- Box: Box 是 CSS 布局的对象和基本单位,⼀个⻚⾯是由很多个 Box 组成的,这个 Box 就是我们所说的盒模型。
- Formatting context:块级上下⽂格式化,它是⻚⾯中的⼀块渲染区域,并且有⼀套渲染规则,它决定了其⼦元素将如何定位,以及和其他元素的关系和相互作⽤。
块格式化上下文(Block Formatting Context,BFC)是 Web 页面的可视化 CSS 渲染的一部分,是布局过程中生成块级盒子的区域,也是浮动元素与其他元素的交互限定区域。
通俗来讲:BFC 是一个独立的布局环境,可以理解为一个容器,在这个容器中按照一定规则进行物品摆放,并且不会影响其它环境中的物品。如果一个元素符合触发 BFC 的条件,则 BFC 中的元素布局不受外部影响。
创建 BFC 的条件:
- 根元素:body;
- 元素设置浮动:float 除 none 以外的值;
- 元素设置绝对定位:position (absolute、fixed);
- display 值为:inline-block、table-cell、table-caption、flex 等;
- overflow 值为:hidden、auto、scroll;
BFC 的特点:
- 垂直方向上,自上而下排列,和文档流的排列方式一致。
- 在 BFC 中上下相邻的两个容器的 margin 会重叠
- 计算 BFC 的高度时,需要计算浮动元素的高度
- BFC 区域不会与浮动的容器发生重叠
- BFC 是独立的容器,容器内部元素不会影响外部元素
- 每个元素的左 margin 值和容器的左 border 相接触
BFC 的作用:
- 解决 margin 的重叠问题:由于 BFC 是一个独立的区域,内部的元素和外部的元素互不影响,将两个元素变为两个 BFC,就解决了 margin 重叠的问题。
- 解决高度塌陷的问题:在对子元素设置浮动后,父元素会发生高度塌陷,也就是父元素的高度变为 0。解决这个问题,只需要把父元素变成一个 BFC。常用的办法是给父元素设置overflow:hidden。
- 创建自适应两栏布局:可以用来创建自适应两栏布局:左边的宽度固定,右边的宽度自适应。
<div class="left"></div>
<div class="right"></div>
.left{
width: 100px;
height: 200px;
background: red;
float: left;
}
.right{
height: 300px;
background: blue;
overflow: hidden;
}
左侧设置float:left,右侧设置overflow: hidden。这样右边就触发了 BFC,BFC 的区域不会与浮动元素发生重叠,所以两侧就不会发生重叠,实现了自适应两栏布局。
什么是 margin 重叠问题?如何解决?
问题描述:
两个块级元素的上外边距和下外边距可能会合并(折叠)为一个外边距,其大小会取其中外边距值大的那个,这种行为就是外边距折叠。需要注意的是,浮动的元素和绝对定位这种脱离文档流的元素的外边距不会折叠。重叠只会出现在垂直方向。
计算原则:
折叠合并后外边距的计算原则如下:
- 如果两者都是正数,取大者
- 如果是一正一负,取正值减去负值的绝对值
- 两个都是负值时,取绝对值大者
解决办法:
对于折叠的情况,主要有两种:兄弟之间重叠
和父子之间重叠
- 兄弟之间重叠
- 底部元素变为行内盒子:display: inline-block
- 底部元素设置浮动:float
- 底部元素的 position 的值为absolute/fixed
- 父子之间重叠
- 父元素加入:overflow: hidden
- 父元素添加透明边框:border:1px solid transparent
- 子元素变为行内盒子:display: inline-block
- 子元素加入浮动属性或定位
元素的层叠顺序
层叠顺序,英文称作 stacking order,表示元素发生层叠时有着特定的垂直显示顺序。下面是盒模型的层叠规则:
对于上图,由上到下分别是:
- 背景和边框:建立当前层叠上下文元素的背景和边框。
- 负的 z-index:当前层叠上下文中,z-index 属性值为负的元素。
- 块级盒:文档流内非行内级非定位后代元素。
- 浮动盒:非定位浮动元素。
- 行内盒:文档流内行内级非定位后代元素。
- z-index:0:层叠级数为 0 的定位元素。
- 正 z-index:z-index 属性值为正的定位元素。
TIP
提示当定位元素 z-index:auto,生成盒在当前层叠上下文中的层级为 0,不会建立新的层叠上下文,除非是根元素。