CSS3添加了几个动画效果的属性,通过设置这些属性,可以做出一些简单的动画效果而不需要再去借助JavaScript。
CSS3动画的属性主要分为三类:transform、transition以及animation。
基本内容
- 动画的基本概念
- 补间动画
- 逐帧动画
- Transform
- 2D变换
- 3D变换
- Tranform过渡控制
- 可动画的属性
- Transition
- 基本属性
- 为不同属性指定过渡时长
- 变换多个动画属性
- 时长的简写
- 强制开启GPU硬件加速
- 消除Tansition动画闪屏和文字变虚
- Animation动画
- 基本属性
- 关键帧序列
- 运动方向
- 重复次数
- 播放与暂停
- 起始状态控制
- Transition 与 Animation 动画的触发
- 监听动画结束的事件
- 确保 transitioned 事件触发
- 强制重绘触发动画
- 会引起界面重绘的属性
- Transition动画应用示例
- Animation动画应用示例
动画的基本概念
补间动画
过滤动画 具有连贯性的动画,从一个关键帧到另一个关键帧的过滤,Transition 动画属于此类动画
逐帧动画
使用steps过渡的动画,在时间帧上逐帧绘制帧内容,由于是一帧一帧的画,所以逐帧动画具有非常大的灵活性,几乎可以表现任何想表现的内容。与电影相似,适用于表现细腻的动画,如人物动作,3D动画等。
缺点是:制作难度大,需要大量素材,导致最终文件的体积很大。
Transform过渡
位移Translate、旋转Rotate、倾斜Skew、缩放Scale 及矩阵变形Matrix
2D变换
- 位移:translate(12px, 50%); 单位可指定 px % em rem
- 缩放:scale(x, y)
- 斜切:skew(0deg, 0deg)
- 旋转:rotate(0deg)
- 矩阵:matrix(0, 0, 0, 0, 0, 0)
3D变换
- 位移:
translateX() / translateY() / translateZ() /translate3d()
- 缩放:
scaleX() / scaleZ() / scaleY() / scale3d(2.5, 1.2, 0.3);
- 斜切:
skewX() / skewY()
- 旋转:
rotate3d(1, 2.0, 3.0, 10deg);
- 矩阵:
matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
触发3D变形的属性
.parent { |
MDN backface-visibility perspective perspective-origin
在子元素上触发3D空间
transform: perspective(600); |
一本书平放在面前,看着书感受一下透视感,perspective属性值就是眼睛和书之间的距离,距离越远,数值越大,透视感越小;距离越近,数值越小,透视感越强。
简单易懂的教程示例:CSS3 3D教程
Transform 过渡控制
transform-origin / transform-style
定义过渡原点
transform-origin ( transform-origin-x 、transform-origin-y、transform-origin-z )
默认为元素的中心原点
transform-origin: left top; 左上角 |
定义子元素的是扁平化还是三维展示
transform-style: flat | preserve-3d
transform-style: preserve-3d; 用于触发子元素三维展示 |
可动画的属性
border / color / backgorund / height、width / left、right、top、bottom / padding / margin / opacity / font-size / box-shadow / text-shadow / transform |
这里列举了 一些常见的可动画的属性,详情请查看 MDN 可动画的属性列表
Transition
定义过渡动画效果
基本属性
- transition-property 需要进行过渡属性(只有指定的属性才进行过滤动画) 或者 全部可动画的属性 all
- transition-delay 延迟时间
- transition-duration 进行过渡的时间
- transition-timing-function 指定动画函数
简写
transition: <property> <duration> <timing-function> <delay>
;
为不同属性指定过渡时长
transition-property: opacity, left, top, height; |
时长的简写
如果有部分属性没有指定时长,则重复前面的时长
transition-property: opacity, left, top, height; |
! 为了过渡的流畅性,一般需要指定动画的属性,可以有以下几种指定方式
transition: margin-left 4s; |
变换多个动画属性
.box { |
强制开启GPU硬件加速
.box { transition: tanslate3d(0,0,0)或 tansition: translateZ(0) } |
消除Tansition动画闪屏和文字变虚
.box{ transform-style: preserve-3d; backface-visibility:hidden; } |
注意
避免使用会引起重排的属性做动画,如:letf / margin / padding / width / height
等会引起大量重排重绘的属性
Animation动画
可以将从一个CSS样式配置转换到另一个CSS样式配置
动画包括两个部分: 描述动画的样式规则和用于指定动画开始、结束以及中间点样式的关键帧。
优点:简单,性能良好,浏览器可以自动优化
基本属性
动画的实际表现是由 @keyframes
规则实现
animation-name
动画的名称(由@keyframes定义)animation-delay
动画延时animation-direction
定义动画完成后,是从初始状态还是从最终状态重复动画animation-duration
动画时长animation-iteration-count
动画重复次数animation-play-state
播放或暂停动画animation-timing-function
设置动画关键帧之间的运动函数animation-fill-mode
指定动画前后如何为元素应用样式
关键帧序列 keyframes
使用@keyframes
定义动画序列关键帧
简单的动画可以使用 from/to
来定义 开始和结束关键帧
p { |
复杂的动画可以使用 百分比 更精确的控制
.tada { |
运动方向 animation-direction
animation-direction: normal | alternate | alternate-reverse | reverse
normal
: 正向运动alternate
: 先正向再反向再正再反循环反复alternate-reverse
: 先反向再正向再反再正循环反复reverse
: 反向运动
重复次数 animation-iteration-count
animation-iteration-count:infinite | <single-animation-iteration-count>
infinite
: 循环执行single-animation-iteration-count
:循环的周期数值(可以是小数)
播放暂停 animation-play-state
animation-play-state:running | paused [ , running | paused ]*
running
:运动paused
:暂停
起始状态控制 animation-fill-mode
animation-fill-mode: none | forwards | backwards | both
设置元素动画之后的状态
none
:不应用状态forwards
: 应用动画结束帧的状态(结束帧与动画运动次数和方向有关)backwards
: 应用动画起始帧的状态 (与动画运动方向有关)both
: 应用首帧与结束帧(同时应用 forwards 与 backwrads)
Transition 与 Animation 动画的触发
可以通过伪类 (:link、:visited、:hover、:active、:focus、:checked、:enabled、:disabled)
和 事件触发
如果直接给元素设置 transform
,用户将直接看到元素的最终状态,而不会有动画
通过切换元素设定好的动画类可以很方便的控制 Transiton
或Animation
动画
Transiton动画 有入场和出场动画,比如一个元素在 :hover
状态时触发 transiton
动画,在鼠标离开后,动画自动反向播放回到 transition
之前的状态
Transition 通过伪类、事件或一个 Class
切换,可以很方便的实现入场和出场动画, 而 Animation
动画则要通过不同的 Class
来控制入场和出场
监听动画结束的事件
- Transition动画监听
transitionend
事件 - Animation动画监听
animationend
事件
简单粗暴的方法: 监听所有可能支持的事件
var transitionEndEventNames = { |
只监听受支持的事件
通过检测 body.style
中是否有相关属性来获取受支持的属性名称
var transEndEventNames = { |
注意
- 当属性值没有发生变化或没有绘制行为发生,transitionend 事件不会被触发
- 如果有多个属性进行transtion动画,则会触发多次 transitierend 事件
确保 transitioned 事件触发
结合jQuery 确保 transitioned
事件能被触发
$.fn.emulateTransitionEnd = function(duration) { |
使用$(this).one('webkitTransitionEnd', callback);
$(this).emulateTransitionEnd(options.duration + 50);
$(this).css(properties);
原理:同时给 元素 绑定两个 webkitTransitionEnd
事件和一个 setTimeout
,如果 webkitTransitionEnd
能正确触发,则 called
为 true
,setTimeout
中回调内的代码则不执行
强制重绘触发动画
给一个 display:none
元素添加 Transition
动画时,先要将 display
设置为block
,同时应用 Transition
动画,但是两套css执行的时间间隔太近,浏览器会尝试优化css属性的变化,直接表现为transition最终的状态,无法显示动画效果,为了避免这种情况,可以在将 display
设置为 block
时,同时强制浏览器对css进行重绘,触发 transition
动画(一般获取一次元素的offsetHeight
属性即可)。
会引起界面重绘的属性
- offsetTop, offsetLeft, offsetWidth, offsetHeight
- scrollTop/Left/Width/Height
- clientTop/Left/Width/Height
- width,height
- 请求了getComputedStyle()
当请求上面的一些属性的时候,浏览器为了给你最精确的值,需要flush队列,因为队列中可能会有影响到这些值的操作。
结合 jQuery
添加一个强制重绘的方法:
$.fn.redraw = function(){ |
使用
$('.element').css({left: '10px'}) |
这种方法在大多数浏览器都有效,但在个别 Andorid默认浏览器上偶尔还是会失效。这时就只能使用定时器或者增加class了。