CSS3动画包括过渡动画和关键帧动画,它们主要通过改变CSS属性值来模拟实现。我将详细介绍Transform、Transitions和Animations 3大功能模块,其中Transform实现对网页对象的变形操作,Transitions实现CSS属性过渡变化,Animations实现CSS样式分步式演示效果。
1、CSS3变形
2012年9月,W3C发布CSS3变形工作草案。这个草案包括CSS3 2D变形和CSS3 3D变形。CSS 2D Transform获得各主流浏览器的支持,CSS 3D Transform支持程度不是很完善。本节重点讲解2D变形,有关3D变形可以参考我的其它帖子。
1.1、设置原点
CSS变形的原点默认为对象的中心点(50% 50%),使用transform-origin属性可以重新设置新的变形原点。语法格式如下所示:
transform-origin:[ <percentage> | <length> | left | center① | right ] [ <percentage> | <length> | top | center② | bottom ]?
取值简单说明如下:
<percentage>
:用百分比指定坐标值,可以为负值。<length>
:用长度值指定坐标值,可以为负值。- left:指定原点的横坐标为left。
- center①:指定原点的横坐标为center。
- right:指定原点的横坐标为right。
- top:指定原点的纵坐标为top。
- center②:指定原点的纵坐标为center。
- bottom:指定原点的纵坐标为bottom。
【示例】通过重置变形原点,可以设计不同的变形效果。以图像的右上角为原点逆时针旋转图像45度:
<style type="text/css">
img { /* 固定两幅图像相同大小和相同显示位置 */
position: absolute;
left: 20px;
top: 10px;
width: 170px;
width: 250px;
}
img.bg { /* 设置第1幅图像作为参考 */
opacity: 0.3;
border: dashed 1px red;
}
img.change { /* 变形第2幅图像 */
border: solid 1px red;
transform-origin: top right; /* 以右上角为原点进行变形*/
transform: rotate(-45deg); /* 逆时针旋转45度*/
}
</style>
<img class="bg" src="images/1.jpg">
<img class="change" src="images/1.jpg">
比较效果如下图所示:
1.2、2D旋转
rotate()函数能够在2D空间内旋转对象,语法格式如下:
rotate(<angle>)
其中,参数angle表示角度值,取值单位可以是:度,如90deg(90度,一圈360度);梯度,如100 grad(相当于90度,360度等于400 grad);弧度,如1.57 rad(约等于90度,360度等于2π);圈,如0.25 turn(等于90度,360度等于1 turn)。
【示例】以上节示例为基础,按默认原点逆时针旋转图像45度:
img.change {
border: solid 1px red;
transform: rotate(-45deg);
}
效果如下图所示:
1.3、2D缩放
scale()函数能够缩放对象大小,语法格式如下:
scale(<number>[, <number>])
该函数包含两个参数值,分别用来定义宽和高的缩放比例。取值简单说明如下:
- 如果取值为正数,则基于指定的宽度和高度将放大或缩小对象。
- 如果取值为负数,则不会缩小元素,而是翻转元素(如文字被反转),然后再缩放元素。
- 如果取值为小于1的小数(如0.5)可以缩小元素。
- 如果第二个参数省略,则第二个参数等于第一个参数值。
【示例】继续以上节示例为基础,按默认原点把图像缩小1/2:
img.change {
border: solid 1px red;
transform: scale(0.5);
}
1.4、2D平移
translate()函数能够平移对象的位置,语法格式如下:
translate(<translation-value>[, <translation-value>])
该函数包含两个参数值,分别用来定义对象在x轴和y轴相对于原点的偏移距离。如果省略参数,则默认值为0。如果取负值,则表示反向偏移,参考原点保持不变。
【示例】设计向右下角方向平移图像,其中x轴偏移150px,y轴偏移50px:
img.change {
border: solid 1px red;
transform: translate(150px, 50px);
}
1.5、2D倾斜
skew()函数能够倾斜显示对象,语法格式如下:
skew(<angle> [, <angle>])
该函数包含两个参数值,分别用来定义对象在x轴和y轴倾斜的角度。如果省略参数,则默认值为0。与rotate()函数不同,rotate()函数只是旋转对象的角度,而不会改变对象的形状;skew()函数会改变对象的形状。
【示例】使用skew()函数变形图像,x轴倾斜30度,y轴倾斜20度:
img.change {
border: solid 1px red;
transform: skew(30deg, 20deg);
}
效果如下图所示:
1.6、2D矩阵
matrix()是一个矩阵函数,它可以同时实现缩放、旋转、平移和倾斜操作,语法格式如下:
matrix(<number>, <number>, <number>, <number>, <number>, <number>)
该函数包含6个值,具体说明如下:
- 第1个参数控制x轴缩放。
- 第2个参数控制x轴倾斜。
- 第3个参数控制y轴倾斜。
- 第4个参数控制y轴缩放。
- 第5个参数控制x轴平移。
- 第6个参数控制y轴平移。
【示例】使用matrix()函数模拟:
img.change {
border: solid 1px red;
transform: matrix(1, 0.6, 0.2, 1, 0, 0);
}
提示:多个变形函数可以在一个声明中同时定义。例如:
div {
transform: translate(80, 80);
transform: rotate(45deg);
transform: scale(1.5, 1.5);}
针对上面样式,可以简化为:
div { transform: translate(80, 80) rotate(45deg) scale(1.5, 1.5);}
2、过渡动画
2013年2月,W3C发布CSS Transitions工作草案,这个草案描述了CSS过渡动画的基本实现方法和属性,目前获得所有浏览器的支持。
2.1、设置过渡属性
transition-property属性定义过渡动画的CSS属性名称,基本语法如下所示:
transition-property:none | all | [ <IDENT> ] [ ‘,’ <IDENT> ]*;
取值简单说明如下:
- none:表示没有元素。
- all:默认值,表示针对所有元素,包括:before和:after伪元素。
- IDENT:指定CSS属性列表。几乎所有色彩、大小或位置等相关的CSS属性,包括许多新添加的CSS3属性都可以应用过渡,如CSS3变换中的放大、缩小、旋转、斜切、渐变等。
【示例】指定动画的属性为背景颜色。这样当鼠标经过盒子时,会自动从红色背景过渡到蓝色背景:
<style type="text/css">
div {
margin: 10px auto; height: 80px;
background: red;
border-radius: 12px;
box-shadow: 2px 2px 2px #999;
}
div:hover {
background-color: blue;
/*指定动画过渡的CSS属性*/
transition-property: background-color;
}
</style>
<div></div>
2.2、设置过渡时间
transition-duration属性定义转换动画的时间长度,基本语法如下所示:
transition-duration:<time> [, <time>]*;
其中,初始值为0,适用于所有元素,以及:before和:after伪元素。在默认情况下,动画过渡时间为0 s,当指定元素动画时,会看不到过渡的过程,而直接看到结果。
【示例】以上节示例为例,设置动画过渡时间为2 s,当鼠标移过对象时,会看到背景色从红色逐渐过渡到蓝色:
div:hover {
background-color: blue;
/*指定动画过渡的CSS属性*/
transition-property: background-color;
/*指定动画过渡的时间*/
transition-duration:2s;
}
2.3、设置延迟过渡时间
transition-delay属性定义开启过渡动画的延迟时间,基本语法如下所示:
transition-delay:<time> [, <time>]*;
其中,初始值为0,适用于所有元素,以及:before和:after伪元素。设置时间可以为正整数、负整数和零。非零的时候必须设置单位是s(秒)或者ms(毫秒);为负数的时候,过渡的动作会从该时间点开始显示,之前的动作被截断;为正数的时候,过渡的动作会延迟触发。
【示例】继续以上节示例为基础进行介绍,设置过渡动画推迟2s后执行,则当鼠标移过对象时,会看不到任何变化,过了2 s之后,才发现背景色从红色逐渐过渡到蓝色。
div:hover {
background-color: blue;
/*指定动画过渡的CSS属性*/
transition-property: background-color;
/*指定动画过渡的时间*/
transition-duration: 2s;
/*指定动画延迟触发 */
transition-delay: 2s;
}
2.4、设置过渡动画类型
transition-timing-function属性定义过渡动画的类型,基本语法如下所示:
transition-timing-function:ease | linear | ease-in | ease-out | ease-in-out | cubicbezier(<number>, <number>, <number>, <number>)
[, ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier(<number>, <number>,<number>, <number>)]*
属性初始值为ease,取值简单说明如下:
- ease:平滑过渡,等同于cubic-bezier(0.25, 0.1, 0.25, 1.0)函数,即立方贝塞尔。
- linear:线性过渡,等同于cubic-bezier(0.0, 0.0, 1.0, 1.0)函数。
- ease-in:由慢到快,等同于cubic-bezier(0.42, 0, 1.0, 1.0)函数。
- ease-out:由快到慢,等同于cubic-bezier(0, 0, 0.58, 1.0)函数。
- ease-in-out:由慢到快再到慢,等同于cubic-bezier(0.42,0, 0.58, 1.0)函数。
- cubic-bezier:特殊的立方贝塞尔曲线效果。
【示例】继续以上节示例为基础进行介绍,设置过渡类型为线性效果,代码如下所示:
div:hover {
background-color: blue;
/*指定动画过渡的CSS属性*/
transition-property: background-color;
/*指定动画过渡的时间*/
transition-duration: 10s;
/*指定动画过渡为线性效果 */
transition-timing-function: linear;
}
2.5、设置过渡触发动作
CSS3过渡动画一般通过动态伪类触发,如下表所示:
也可以通过JavaScript事件触发,包括click、focus、mousemove、mouseover、mouseout等。
1、:hover
最常用的过渡触发方式是使用:hover伪类。
【示例1】设计当鼠标经过div元素时,该元素的背景颜色会在经过1 s的初始延迟后,于2 s内动态地从绿色变为蓝色。
<style type="text/css">
div {
margin: 10px auto;
height: 80px;
border-radius: 12px;
box-shadow: 2px 2px 2px #999;
background-color: red;
transition: background-color 2s ease-in 1s;
}
div:hover { background-color: blue}
</style>
<div></div>
2、:active
:active伪类表示用户单击某个元素并按住鼠标按钮时显示的状态。
【示例2】设计当用户单击div元素时,该元素被激活,这时会触发动画,高度属性从200px过渡到400px。如果按住该元素,保持活动状态,则div元素始终显示400px高度,松开鼠标之后,又会恢复到原来的高度:
<style type="text/css">
div {
margin: 10px auto;
border-radius: 12px;
box-shadow: 2px 2px 2px #999;
background-color: #8AF435;
height: 200px;
transition: width 2s ease-in;
}
div:active {height: 400px;}
</style>
<div></div>
3、: focus
:focus伪类通常会在表单对象接收键盘响应时出现。
【示例3】当输入框获取焦点时,输入框的背景色逐步高亮显示,如下图所示:
<style type="text/css">
label {
display: block;
margin: 6px 2px;
}
input[type="text"], input[type="password"] {
padding: 4px;
border: solid 1px #ddd;
transition: background-color 1s ease-in;
}
input:focus { background-color: #9FFC54;}
</style>
<form id=fm-form action="" method=post>
<fieldset>
<legend>用户登录</legend>
<label for="name">姓名
<input type="text" id="name" name="name" >
</label>
<label for="pass">密码
<input type="password" id="pass" name="pass" >
</label>
</fieldset>
</form>
提示:把:hover伪类与:focus配合使用,能够丰富鼠标用户和键盘用户的体验。
4、:checked
:checked伪类在发生选中状况时触发过渡,取消选中则恢复原来的状态。
【示例4】设计当复选框被选中时缓慢缩进2个字符:
<style type="text/css">
label.name {
display: block;
margin: 6px 2px;
}
input[type="text"], input[type="password"] {
padding: 4px;
border: solid 1px #ddd;
}
input[type="checkbox"] { transition: margin 1s ease;}
input[type="checkbox"]:checked { margin-left: 2em;}
</style>
<form id=fm-form action="" method=post>
<fieldset>
<legend>用户登录</legend>
<label class="name" for="name">姓名
<input type="text" id="name" name="name" >
</label>
<p>技术专长<br>
<label>
<input type="checkbox" name="web" value="html" id="web_0">
HTML</label><br>
<label>
<input type="checkbox" name="web" value="css" id="web_1">
CSS</label><br>
<label>
<input type="checkbox" name="web" value="javascript" id="web_2">
JavaScript</label><br>
</p>
</fieldset>
</form>
演示效果:
5、媒体查询
触发元素状态变化的另一种方法是使用CSS3媒体查询。
【示例5】设计div元素的宽度和高度为49%×200px,如果用户将窗口大小调整到420px或以下,则该元素将过渡为100%×100px。也就是说,当窗口宽度变化经过420px的阈值时,将会触发过渡动画:
<style type="text/css">
div {
float: left; margin: 2px;
width: 49%; height: 200px;
background: #93FB40;
border-radius: 12px;
box-shadow: 2px 2px 2px #999;
transition: width 1s ease, height 1s ease;
}
@media only screen and (max-width : 420px) {
div {
width: 100%;
height: 100px;
}
}
</style>
<div></div>
<div></div>
6、JavaScript事件
【示例6】可以使用纯粹的CSS伪类触发过渡,为了方便用户理解,这里通过jQuery脚本触发过渡:
<script type="text/javascript" src="images/jquery-1.10.2.js"></script>
<script type="text/javascript">
$(function() {
$("#button").click(function() {
$(".box").toggleClass("change");
});
});
</script>
<style type="text/css">
.box {
margin:4px;
background: #93FB40;
border-radius: 12px;
box-shadow: 2px 2px 2px #999;
width: 50%; height: 100px;
transition: width 2s ease, height 2s ease;
}
.change { width: 100%; height: 120px;}
</style>
<input type="button" id="button" value="触发过渡动画" />
<div class="box"></div>
在文档中包含一个box类的盒子和一个按钮,当单击按钮时,jQuery脚本会将盒子的类切换为change,从而触发过渡动画:
上面演示了样式发生变化会导致过渡动画,也可以通过其他方法触发这些更改,包括通过JavaScript脚本动态更改。从执行效率来看,事件通常应当通过JavaScript触发,简单动画或过渡则应使用CSS触发。
3、帧动画
2012年4月,W3C发布CSS Animations工作草案,在这个草案中描述了CSS关键帧动画的基本实现方法和属性。目前主流浏览器都支持CSS帧动画。
3.1、设置关键帧
CSS3使用@keyframes定义关键帧,具体用法如下所示:
@keyframes animationname {
keyframes-selector {
css-styles;
}
}
其中参数说明如下:
- animationname:定义动画的名称。
- keyframes-selector:定义帧的时间位置,也就是动画时长的百分比,合法的值包括:0~100%、from(等价于0)、to(等价于100%)。
- css-styles:表示一个或多个合法的CSS样式属性。
在动画设计过程中,用户能够多次改变CSS样式,以百分比定义样式改变发生的时间,或者通过关键词from和to。为了获得最佳浏览器支持,设计关键帧动画时,应该始终定义0和100%位置帧。最后,为每帧定义动态样式,同时将动画与选择器绑定。
【示例】演示让一个小方盒沿着方形框内壁匀速运动:
<style>
#wrap { /* 定义运动轨迹包含框*/
position:relative; /* 定义定位包含框,避免小盒子跑到外面运动*/
border:solid 1px red;
width:250px; height:250px;
}
#box { /* 定义运动小盒的样式*/
position:absolute;
left:0; top:0;
width: 50px; height: 50px;
background: #93FB40;
border-radius: 8px;
box-shadow: 2px 2px 2px #999;
/*定义帧动画:名称为ball,动画时长5s,动画类型为匀速渐变,动画无限播放*/
animation: ball 5s linear infinite;
}
/*定义关键帧:共包括5帧,分别在总时长为0、25%、50%、75%、100%的位置*/
/*每帧中设置动画属性为left和top,让它们的值匀速渐变,产生运动动画*/
@keyframes ball {
0 {left:0;top:0;}
25% {left:200px;top:0;}
50% {left:200px;top:200px;}
75% {left:0;top:200px;}
100% {left:0;top:0;}
}
</style>
<div id="wrap">
<div id="box"></div>
</div>
3.2、设置动画属性
Animations功能与Transition功能相同,都是通过改变元素的属性值实现动画效果。它们的区别在于:使用Transitions功能时只能通过指定属性的开始值与结束值,然后以在这两个属性值之间进行平滑过渡的方式实现动画效果,因此不能实现比较复杂的动画效果;而Animations功能则通过定义多个关键帧以及定义每个关键帧中元素的属性值实现更为复杂的动画效果。
1.定义动画名称
使用animation-name属性可以定义CSS动画的名称,语法如下所示:
animation-name:none | IDENT [, none | IDENT ]*;
其中,初始值为none,定义一个适用的动画列表。每个名字用来选择动画关键帧,提供动画的属性值。如名称是none,就不会有动画。
2.定义动画时间
使用animation-duration属性可以定义CSS动画的播放时间,语法如下所示。
animation-duration:<time> [, <time>]*;
在默认情况下,该属性值为0,这意味着动画周期为0,即不会有动画。当值为负值时,则被视为0。
3.定义动画类型
使用animation-timing-function属性可以定义CSS动画类型,语法如下所示。
animation-timing-function:ease | linear | ease-in | ease-out | ease-in-out | cubicbezier(<number>, <number>, number>, <number>) [,
ease | linear |ease-in | ease-out | ease-in-out | cubic-bezier(<number>, <number>,<number>, <number>)]*
初始值为ease,取值说明可参考上面介绍的过渡动画类型。
4.定义延迟时间
使用animation-delay属性可以定义CSS动画延迟播放的时间,语法如下所示:
animation-delay:<time> [, <time>]*;
该属性允许一个动画开始执行一段时间后才被应用。当动画延迟时间为0,即默认动画延迟时间,则意味着动画将尽快执行,否则该值指定将延迟执行的时间。
5.定义播放次数
使用animation-delay属性可以定义CSS动画延迟播放的时间,语法如下所示:
animation-delay:<time> [, <time>]*;
该属性允许一个动画开始执行一段时间后才被应用。当动画延迟时间为0,即默认动画延迟时间,则意味着动画将尽快执行,否则该值指定将延迟执行的时间。
6.定义播放方向
使用animation-direction属性定义CSS动画的播放方向,基本语法如下所示。
animation-direction:normal | alternate [, normal | alternate]*;
默认值为normal。当为默认值时,动画的每次循环都向前播放。另一个值是alternate,设置该值则表示第偶数次向前播放,第奇数次向反方向播放。
7.定义播放状态
使用animation-play-state属性定义动画正在运行还是暂停,语法如下所示:
animation-play-state: paused|running;
初始值为running。其中,paused定义动画已暂停,running定义动画正在播放。
提示:可以在JavaScript中使用该属性,这样就能在播放过程中暂停动画。在JavaScript脚本中用法如下。
8.定义播放外状态
使用animation-fill-mode属性定义动画播放外状态,语法如下所示。
animation-fill-mode:none | forwards | backwards | both [ , none | forwards | backwards | both ]*
初始值为none,如果提供多个属性值,以逗号进行分隔。取值说明如下:
- none:不设置对象动画之外的状态。
- forwards:设置对象状态为动画结束时的状态。
- backwards:设置对象状态为动画开始时的状态。
- both:设置对象状态为动画结束或开始的状态。
【示例】设计一个小球,并定义它水平向左运动,动画结束之后,再返回起始点位置:
<style>
/*启动运动的小球,并定义动画结束后返回*/
.ball{
width: 50px; height: 50px;
background: #93FB40;
border-radius: 100%;
box-shadow:2px 2px 2px #999;
animation:ball 1s ease backwards;
}
/*定义小球水平运动关键帧*/
@keyframes ball{
0%{transform:translate(0,0);}
100%{transform:translate(400px);}
}
</style>
<div class="ball"></div>
效果如下图所示: