Skip to content

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 属性需要是 relativeabsolute 或是 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 是固定的像素,一旦设置了就无法因为适应页面大小而改变。
  • emrem 相对于 px 更具有灵活性,他们是相对长度单位,其长度不是固定的,更适用于响应式布局。
  • em 是相对于其父元素来设置字体大小,这样就会存在一个问题,进行任何元素设置,都有可能需要知道他父元素的大小。而 rem 是相对于根元素,这样就意味着,只需要在根元素确定一个参考值。

使用场景:

  • 对于只需要适配少部分移动设备,且分辨率对页面影响不大的,使用 px 即可 。
  • 对于需要适配各种移动设备,使用 rem,例如需要适配 iPhone 和 iPad 等分辨率差别比较挺大的设备。

如何根据设计稿进行移动端适配?

移动端适配主要有两个维度:

适配不同像素密度,针对不同的像素密度,使用 CSS 媒体查询,选择不同精度的图片,以保证图片不会失真适配不同屏幕大小,由于不同的屏幕有着不同的逻辑像素大小,所以如果直接使用 px 单位,会使得开发的页面在某一款手机上可以准确显示,但是在另一款手机上就会失真。为了适配不同屏幕的大小,应按照比例来还原设计稿的内容。

为了能让页面的尺寸自适应,可以使用 rememvwvh相对单位

响应式设计的概念及基本原理

响应式网站是指一个网站能够兼容多个终端

关于原理: 基本原理是通过媒体查询(@media)查询检测不同的设备屏幕尺寸做处理。

关于兼容: 页面头部必须有 meta 声明的 viewport

html
<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 属性清除浮动,其语法如下:

css
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 吧。

一般使用伪元素的方式清除浮动:

css
.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。
  • 创建自适应两栏布局:可以用来创建自适应两栏布局:左边的宽度固定,右边的宽度自适应。
html
<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 重叠问题?如何解决?

问题描述:

两个块级元素的上外边距和下外边距可能会合并(折叠)为一个外边距,其大小会取其中外边距值大的那个,这种行为就是外边距折叠。需要注意的是,浮动的元素和绝对定位这种脱离文档流的元素的外边距不会折叠。重叠只会出现在垂直方向。

计算原则:

折叠合并后外边距的计算原则如下:

  • 如果两者都是正数,取大者
  • 如果是一正一负,取正值减去负值的绝对值
  • 两个都是负值时,取绝对值大者

解决办法:

对于折叠的情况,主要有两种:兄弟之间重叠父子之间重叠

  1. 兄弟之间重叠
  • 底部元素变为行内盒子:display: inline-block
  • 底部元素设置浮动:float
  • 底部元素的 position 的值为absolute/fixed
  1. 父子之间重叠
  • 父元素加入:overflow: hidden
  • 父元素添加透明边框:border:1px solid transparent
  • 子元素变为行内盒子:display: inline-block
  • 子元素加入浮动属性或定位

元素的层叠顺序

层叠顺序,英文称作 stacking order,表示元素发生层叠时有着特定的垂直显示顺序。下面是盒模型的层叠规则:

img

对于上图,由上到下分别是:

  1. 背景和边框:建立当前层叠上下文元素的背景和边框。
  2. 负的 z-index:当前层叠上下文中,z-index 属性值为负的元素。
  3. 块级盒:文档流内非行内级非定位后代元素。
  4. 浮动盒:非定位浮动元素。
  5. 行内盒:文档流内行内级非定位后代元素。
  6. z-index:0:层叠级数为 0 的定位元素。
  7. 正 z-index:z-index 属性值为正的定位元素。

TIP

提示当定位元素 z-index:auto,生成盒在当前层叠上下文中的层级为 0,不会建立新的层叠上下文,除非是根元素。