【CSS】动画性能优化

60fps 与设备刷新率

目前大多数设备的屏幕刷新率为60fps(Frame per Second),即每秒60帧。因此,如果在页面中有一个动画或渐变效果,或者用户正在滚动页面,那么浏览器渲染动画或页面的每一帧的速率也需要跟设备屏幕的刷新率保持一致,即每一帧要在16毫秒(1S/60 = 16.66ms)之内完成。如果无法完成,由于帧率的下降会导致内容在屏幕上抖动。此现象通常称为卡顿,会对用户体验产生负面影响。

浏览器渲染

在讲性能之前,我们需要先对浏览器渲染页面有一个基础的理解。

css 图层

浏览器在渲染一个页面时,会将页面分为很多个图层,图层有大有小,每个图层上有一个或多个节点。需要注意的是,如果图层中某个元素需要重绘,那么整个图层都需要重绘(关于重绘下面会讲到)。

渲染过程

简单来说,浏览器的渲染过程其实就是将页面转换成像素显示到屏幕上,大致有如下几个步骤:

渲染过程流程图
  • JavaScript操作: 一般来说,我们会使用 JavaScript 来实现一些交互操作。比如用往页面里添加一些元素,切换显示隐藏等。
  • style 样式计算: 该过程根据 css 选择器,获取每个元素匹配的 css 样式并计算其最终应用样式。
  • Layout 布局:该过程计算元素要占据的空间大小及其在屏幕的位置。网页的布局模式意味着一个元素可能影响其他元素,例如 元素的宽度一般会影响其子元素的宽度以及树中各处的节点,因此对于浏览器来说,布局是经常发生的。
  • Paint 绘制:本质上就是填充像素的过程。包括绘制文字、颜色、图像、边框和阴影等。也就是绘制元素所有的可视效果。
  • Composite 渲染层合并:在每个层上完成绘制过程之后,浏览器会将所有层按照合理的顺序合并成一个图层,然后显示在屏幕上如果我们需要提高动画的性能,需要做的就是减少浏览器在动画运行时所需要做的工作。当 css 在进行动画时,其不同属性值引起的改变,重新渲染可能会有三种执行路径:
    1. layout -> paint -> composite
    2. paint -> composite
    3. composite 很明显,最短路径的 C 动画性能是最高的,所以我们在使用动画的时候就得考虑使用什么属性,以尽量减少执行路径。

动画属性

css 的属性大致分为三类:布局类(layout),绘制类(paint),合成类(composite)。

重排(reflow)

由元素的布局类属性改变所触发的行为过程,我们称为 reflow,也叫做 relayout(重新布局)。当某个节点 reflow 时会重新计算节点的尺寸和位置,还可能会引起其它节点的 reflow。

该系列属性的改变,会执行路径 A 进行重新渲染,所以性能是最差的。(这充分说明,重排会引起重绘)

触发重排的属性

  • 盒子模型相关属性会触发重布局:

    • width
    • height
    • padding
    • margin
    • display
    • border-width
    • border
    • min-height
  • 定位属性及浮动也会触发重布局:

    • top
    • bottom
    • left
    • right
    • position
    • float
    • clear
  • 改变节点内部文字结构也会触发重布局:

    • text-align
    • overflow-y
    • font-weight
    • overflow
    • font-family
    • line-height
    • vertival-align
    • white-space
    • font-size

重绘(repaint)

由绘制类属性改变触发节点重新绘制其可视效果的过程,我们称为 repaint。

该系列属性的改变,会执行路径 B,所以性能一般。

修改时只触发重绘的属性有:

  • color
  • border-style
  • border-radius
  • visibility
  • text-decoration
  • background
  • background-image
  • background-position
  • background-repeat
  • background-size
  • outline-color
  • outline
  • outline-style
  • outline-width
  • box-shadow

上面的属性由于不会修改节点的大小和位置,因此不会触发重排,其只是改变了节点内部的渲染效果,所以只会进行重绘以下的步骤。

composite

目前只有两个属性属于 composite 类:

  • transform
  • opactiy

优化技巧

减少动画元素

减少动画元素是动画性能优化中首先需要完成的。通过审查页面动画 DOM 元素结构,去除不必要的动画元素,减少元素的数量,相应地会减少布页面局和绘制的时间。

尽量使用 fixed、absolute 定位

对于动画元素,尽量使用用 fixed、absolute 定位方式,避免影响到其他节点重排。

尽量只改变 transform 和 opacity

能用 transform、opacity 优先使用,其属性的改变不会发生重排和重绘。如位移操作的,可以使用translate 来实现,渐隐渐现效果可以使用 opacity 属性来实现。

恰当开启硬件加速效果

对动画元素应用

transform: translate3d(0, 0, 0);
/* transform: translateZ(0); */
will-change: transform;

等来开启硬件加速。通常开启硬件加速可以让动画变得更加流畅。但这里需注意,在不需要的时候需去掉避免过多的内存消耗。

WEB前端-CSS篇

CSS3 新增属性

1. 选择器(Selectors)

CSS3 新增了许多强大的选择器,可以更精确地匹配元素。

选择器 示例 描述
属性选择器 input[type="text"] 匹配具有特定属性的元素
结构伪类 :nth-child(n) 匹配第 n 个子元素
:first-of-type 匹配同类型的第一个元素
:last-child 匹配最后一个子元素
:not(selector) 排除匹配的元素
UI 伪类 :checked 匹配被选中的表单元素(如复选框)
:disabled 匹配禁用的表单元素
:enabled 匹配可用的表单元素
目标伪类 :target 匹配当前 URL 的锚点目标元素

2. 盒模型(Box Model)

CSS3 提供了更灵活的盒模型控制方式。

属性 描述
box-sizing: border-box 使 width 和 height 包含 padding 和 border
resize 允许用户调整元素大小(both、horizontal、vertical)
outline-offset 设置轮廓(outline)与边框的偏移距离

3. 背景与边框(Background & Border)

CSS3 增强了背景和边框的样式控制。

背景(Background)

属性 描述
background-size 控制背景图片大小(cover、contain、100% 100%)
background-clip 定义背景绘制区域(border-box、padding-box、content-box)
background-origin 定义背景定位的基准区域
background-attachment: local 背景随内容滚动
background: url(img1.png), url(img2.png); 多背景

边框(Border)

属性 描述
border-radius 圆角边框(border-radius: 10px;)
box-shadow 盒子阴影(box-shadow: 5px 5px 10px #888;)
border-image 使用图片作为边框(border-image: url(border.png) 30 round;)

4. 渐变(Gradients)

CSS3 支持线性渐变和径向渐变。

类型 示例 描述
线性渐变 background: linear-gradient(to right, red, blue); 从左到右渐变
径向渐变 background: radial-gradient(circle, red, yellow); 从中心向外渐变
重复渐变 background: repeating-linear-gradient(45deg, red, red 10px, blue 10px, blue 20px); 重复渐变

5. 过渡(Transitions)

CSS3 过渡允许属性在一定时间内平滑变化。

属性 描述
transition-property 指定过渡的属性(如 width、opacity)
transition-duration 过渡持续时间(如 1s)
transition-timing-function 过渡速度曲线(ease、linear、cubic-bezier())
transition-delay 过渡延迟时间
简写 transition: width 1s ease 0.5s;

6. 动画(Animations)

CSS3 动画比过渡更强大,支持关键帧控制。

属性 描述
@keyframes 定义动画关键帧
animation-name 指定动画名称
animation-duration 动画持续时间
animation-timing-function 动画速度曲线
animation-delay 动画延迟时间
animation-iteration-count 动画播放次数(infinite 表示无限循环)
animation-direction 动画方向(normal、reverse、alternate)
animation-fill-mode 动画结束后保持状态(forwards、backwards)
简写 animation: move 2s ease infinite;

示例:

@keyframes move {
  0% { transform: translateX(0); }
  100% { transform: translateX(100px); }
}
div {
  animation: move 2s ease infinite;
}

7. 变形(Transforms)

CSS3 变形允许对元素进行 2D/3D 变换。

2D 变形:

属性 描述
transform: translate(x, y) 移动元素
transform: rotate(45deg) 旋转元素
transform: scale(1.5) 缩放元素
transform: skew(30deg) 倾斜元素
组合变换 transform: rotate(45deg) scale(1.2);

3D 变形:

属性 描述
transform: translate3d(x, y, z) 3D 移动
transform: rotateX(45deg) 绕 X 轴旋转
transform: perspective(500px) 设置 3D 透视距离

8. 弹性布局(Flexbox)

CSS3 Flexbox 提供更灵活的布局方式。

属性 描述
display: flex 启用 Flex 布局
flex-direction 主轴方向(row、column)
justify-content 主轴对齐方式(center、space-between)
align-items 交叉轴对齐方式(center、stretch)
flex-wrap 是否换行(wrap、nowrap)
flex-grow 定义项目的放大比例
flex-shrink 定义项目的缩小比例
flex-basis 定义项目的初始大小

9. 网格布局(Grid)

CSS3 Grid 提供二维布局系统。

属性 描述
display: grid 启用 Grid 布局
grid-template-columns 定义列宽(如 1fr 2fr)
grid-template-rows 定义行高
grid-gap 定义行列间距
grid-column / grid-row 定义项目占据的网格区域
<!DOCTYPE html>
<html>
<head>

<style>
        .grid-container {
            display: grid;
            grid-template-columns: 100px 200px auto; /* 三列:固定100px,固定200px,剩余空间 */
            gap: 10px;
            background-color: #2196F3;
            padding: 10px;
        }

        .grid-item {
            background-color: rgba(255, 255, 255, 0.8);
            border: 1px solid rgba(0, 0, 0, 0.8);
            padding: 20px;
            font-size: 30px;
            text-align: center;
        }
    </style>
</head>
<body>
    <div class="grid-container">
        <div class="grid-item">1</div>
        <div class="grid-item">2</div>
        <div class="grid-item">3</div>  
        <div class="grid-item">4</div>
        <div class="grid-item">5</div>
        <div class="grid-item">6</div>  
        <div class="grid-item">7</div>
        <div class="grid-item">8</div>
        <div class="grid-item">9</div>  
    </div>
</body>
</html>

10. 媒体查询(Media Queries)

CSS3 媒体查询允许针对不同设备应用不同样式。

/* 屏幕宽度小于 600px 时生效 */
@media (max-width: 600px) {
  body { background: lightblue; }
}

BEM 命名规范

BEM(Block-Element-Modifier)是一种流行的 CSS 命名方法论,旨在提高代码可读性、可维护性和可复用性。其核心思想是通过模块化的方式组织 CSS 类名,避免样式冲突。

1. BEM 基本结构

BEM 将界面拆分为三个部分: 部分 描述 示例
Block 独立的、可复用的组件(如按钮、卡片、导航栏)。 .btn、.card
Element 属于 Block 的子元素,不能单独使用(如按钮的图标、卡片的标题)。 .btn__icon、.card__title
Modifier 表示 Block 或 Element 的状态或变体(如禁用按钮、大号卡片)。 .btn--disabled、.card--large

2. 命名规则

(1) Block(块)
  • 使用单一单词或短横线连接(-)的命名方式。
  • 代表一个独立的组件,不依赖其他元素。
.header { ... }       /* 页眉 */
.menu { ... }         /* 菜单 */
.search-box { ... }   /* 搜索框 */
(2) Element(元素)
  • 格式:Block名称__Element名称(双下划线 __ 连接)。
  • 表示属于 Block 的一部分,不能脱离 Block 使用。
.menu__item { ... }          /* 菜单项 */
.search-box__input { ... }   /* 搜索框的输入框 */
.card__title { ... }         /* 卡片的标题 */
(3) Modifier(修饰符)
  • 格式:Block--Modifier 或 Block__Element--Modifier(双短横线 -- 连接)。
  • 表示 Block 或 Element 的不同状态或样式变体。
.button--primary { ... }     /* 主要按钮 */
.button--disabled { ... }    /* 禁用按钮 */
.menu__item--active { ... }  /* 当前选中的菜单项 */

3. 实际代码示例

HTML 结构

<!-- Block: card -->
<div class="card card--highlight">
  <!-- Element: card 的子元素 -->
  <h2 class="card__title">标题</h2>
  <p class="card__content">内容...</p>
  <!-- 带 Modifier 的 Element -->
  <button class="card__button card__button--large">点击</button>
</div>

CSS 样式

/* Block */
.card { 
  border: 1px solid #ccc;
  padding: 16px;
}

/* Modifier: 高亮卡片 */
.card--highlight {
  background: #f5f5f5;
}

/* Element: 卡片标题 */
.card__title {
  font-size: 18px;
  color: #333;
}

/* Element: 卡片按钮 */
.card__button {
  padding: 8px 16px;
}

/* Modifier: 大号按钮 */
.card__button--large {
  padding: 12px 24px;
}

【CSS】常用样式

CSS Hack

书写顺序:Chrome -> FF -> IE8 -> IE7 -> IE6

* 版本
_ IE6以下
\9 IE6+
* IE7 以下
*+ IE7
\0 IE8+ 和 Opera

Media Queries

<link rel="stylesheet" href="big.css" media="screen and (min-width: 641px)">
<link rel="stylesheet" href="small.css" media="screen and (max-width: 640px)">
<link rel="stylesheet" href="style.css" media="screen and (min-width:640px) and (max-width:900px)">

Flex水平垂直居中

{
  display: flex;
  align-item: center;
  justify-content: center;
}

屏幕自动居中

{
  position: absolute;
  top: 50%;
  left: 50%;
  width: 320px;
  transform: translate(-50%, -50%);
}

单行文本溢出

{
  text-overflow: ellipsis;
  white-space: nowrap;
    overflow: hidden;
}

多行文本溢出

{
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}

ios平滑滚动效果

{
  -webkit-overflow-scrolling: touch;
}

清除浮动

:after {
  display: block;
  clear: both;
  content: " ";
}

字体&规范

  • OOCSS、SMACSS、BEM

  • 移动端字体

    {
    font-family: Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", sans-self;
    }
  • PC端字体

    {
    font-family: Tahoma, Arial, "Helvetica Neue", "Hiragino Sans GB", "Microsoft YaHei", Simsun, sans-self;
    }
  • 移动 & PC 字体

    {
    font-family: Tahoma,Arial,Roboto,"Droid Sans","Helvetica Neue","Microsoft YaHei","Droid Sans Fallback","Heiti SC","Hiragino Sans GB",Simsun,sans-self;
    }

中文两端对齐

{
  text-justify: inter-ideograph;
  text-align: justify;
}

省略文字

{
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}

<pre> 文字适应浏览器宽度

{
  white-space: pre-wrap;
  word-wrap: break-word;
}

自动换行

{
  white-space: normal;
  word-wrap: break-word;
  word-break: normal;
}

三角形

{
  width: 0;
  height: 0;
  border-right: 50px solid transparent;
  border-left: 50px solid transparent;
  border-bottom: 50px solid red;
}

自定义字体

@font-face {
  font-family: 'iconfont';
  src: url('//at.alicdn.com/t/font_657067_0jljwrqiuueo.eot');
  src: url('//at.alicdn.com/t/font_657067_0jljwrqiuueo.eot?#iefix') format('embedded-opentype'),
  url('//at.alicdn.com/t/font_657067_0jljwrqiuueo.woff2') format('woff2'),
  url('//at.alicdn.com/t/font_657067_0jljwrqiuueo.woff') format('woff'),
  url('//at.alicdn.com/t/font_657067_0jljwrqiuueo.ttf') format('truetype'),
  url('//at.alicdn.com/t/font_657067_0jljwrqiuueo.svg#iconfont') format('svg');
}

移动端1px

.box {
  position: relative;
  width: 100%;
  height: 1px;
  margin: 20px 0;
}
.box::after {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 1px;
  content: '';
  background: red;
  transform: scaleY(0.5);
  transform-origin: 0 0;
}

calc 函数

#div {
  position: absolute;
  left: 50px;
  width: calc( 100% / (100px * 2) );
  border: 1px solid black;
}

css 禁止用户选择

body {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

消除 transtration 闪屏

.css {
  -webkit-transform-style: preserve-3d;
  -webkit-backface-visibility: hidden;
  -webkit-perspective: 1000;
}

去掉Chrome中input获得焦点时的颜色边框

input {
  outline: none;
}
已到底部,没有更多内容了
载入中