CSS动画基础知识
CSS动画就是通过CSS (Cascading Style Sheet,层叠样式表)代码搭建的网页动画。它允许设计师和开发人员通过编辑网站的CSS代码来添加页面动画,从而轻松取代传统动画图片或flash动画的设计方式。
transition(过渡)和animation(动画)是CSS3中的两种动画属性。
transition强调过渡,是元素的一个或多个属性发生变化时产生的过渡效果,同一个元素通过两个不同的途径获取样式,而第二个途径当某种改变发生(例如hover)时才能获取样式,这样就会产生过渡动画。
animation强调流程与控制,对元素的一个或多个属性的变化进行控制,可以有多个关键帧(animation 和@ keyframes结合使用)。
1.transition 属性
transition 属性是一个简写属性,用于设置四个过渡属性:
transition-property、transition-duration、transition-timing-function、transition-delay。
(1)transition-duration属性。
transition-duration 属性规定完成过渡效果需要花费的时间(以秒或毫秒计)。其格式为:
transition-duration: time;
属性值time规定完成过渡效果需要花费的时间(以秒或毫秒计)。默认值是 0,意味着不会有效果。
若想得到动画效果,需要指定transition-duration属性,否则持续时间为0,transition不会有任何效果。
(2)transition-delay 属性。
transition-delay 属性规定过渡效果何时开始。其格式为:
transition-delay: time;
属性值time规定在过渡效果开始之前需要等待的时间,以秒或毫秒计。
(3)transition-property属性。
transition-property属性指定CSS属性的nametransition效果(transition效果时将会启动指定的CSS属性的变化)。其格式为:
transition-property: none |all | property;
其中,属性值none表示没有属性会获得过渡效果;属性值all表示所有属性都将获得过渡效果;property 定义应用过渡效果的 CSS 属性名称列表,列表以逗号分隔。
(4)transition-timing-function 属性。
transition-timing-function属性指定切换效果的速度。此属性允许一个过渡效果,以改变其持续时间的速度。其格式为:
transition-timing-function: linear|ease|ease-in|ease-out|ease-in-out|cubic-bezier(n,n,n,n);
各属性值的功能描述如下:
linear 规定以相同速度开始至结束的过渡效果(等于 cubic-bezier(0,0,1,1))。
ease 规定慢速开始,然后变快,然后慢速结束的过渡效果(等于cubic-bezier(0.25,0.1,0.25,1))。
ease-in 规定以慢速开始的过渡效果(等于 cubic-bezier(0.42,0,1,1))。
ease-out 规定以慢速结束的过渡效果(等于 cubic-bezier(0,0,0.58,1))。
ease-in-out 规定以慢速开始和结束的过渡效果(等于 cubic-bezier(0.42,0,0.58,1))。
cubic-bezier(n,n,n,n) 在cubic-bezier 函数中定义自己的值。可能的值是 0 至 1 之间的数值。
例1 transition 属性的简单应用。
先看一个简单的例子,体会transition 属性的应用。
在页面中放置一个类名为container的层作为效果展示容器,在该层中再定义一个类名为move-box的层作为应用过渡效果的对象,HTML代码描述如下:
<div class="container">
<div class="move-box">
</div>
</div>
为两个层定义CSS样式如下:
.container
{
width: 300px;
height: 200px;
border: 4px solid rgba(255, 0, 0, 0.9);
}
.move-box
{
left:0;
width: 50px;
height: 50px;
position: relative;
background: rgb(0,0,255);
}
这样,在页面中会显示如图1所示的图形。
图1 两个层在页面中的显示
为.containe层添加鼠标悬停样式规则,设置move-box层的left属性值为250px,这样当鼠标悬停在图1所示的红色矩形框中,蓝色正方形会移动到红色矩形框的最右端。
.container:hover .move-box
{
left:250px;
}
但这个移动是瞬时完成的,没有任何过渡效果,更谈不上动画了。为此,需要为这个移动的变化设置transition属性。增加样式规则如下:
.container .move-box
{
transition-duration: 2s;
}
此时,可以得到如图2所示的蓝色小正方形移动的动画效果。当鼠标悬停在红色矩形框中时,蓝色小正方形从左向右移动;当鼠标移离时,蓝色小正方形从右向左移动。
图2 蓝色小正方形移动:双向过渡效果
完整的HTML代码如下。
<!DOCTYPE html> <html> <head> <title>transition 属性的简单应用</title> <style> .container { width: 300px; height: 200px; border: 4px solid rgba(255, 0, 0, 0.9); } .move-box { left:0; width: 50px; height: 50px; position: relative; background: rgb(0,0,255); } .container .move-box { transition-duration: 2s; } .container:hover .move-box { left:250px; } </style> </head> <body> <div class="container"> <div class="move-box"> </div> </div> </body> </html>
在这个例子中,在.container .move-box 中设置了过渡动画完成的时间为2秒钟(transition-duration: 2s;),这样在left属性变化时会产生过渡动画效果,而这种效果的产生有两种途径:一种是鼠标在container上悬停, move-box的样式从默认样式到.container:hover的样式,left属性发生了变化,触发了过渡效果; 一种是鼠标移离container层,move-box的样式从.container:hover的样式回到默认样式,left也变化了,因此也产生了过渡效果。这两个方向上的过渡都是平滑不突兀的。
若将.container .move-box样式定义中的transition-duration: 2s;移到.container:hover .move-box中,并删除.container .move-box样式定义,如下:
.container:hover .move-box
{
left:250px;
transition-duration: 2s;
}
此时,过渡动画是单一方向上的,当鼠标在container上悬停时, move-box的样式从默认样式到.container:hover的样式,left属性发生了变化,触发了过渡效果; 当鼠标移离container层,move-box的样式从.container:hover的样式回到默认样式,left也变化了,但此时不是过渡动画的方式,而是直接回到默认,看上去比较突兀和生硬。效果如图3所示。
图3 蓝色小正方形移动:单一方向上有过渡效果
例1中的过渡动画效果是通过改变动画元素的left属性,从而使得元素的位置发生改变而得到的。为了对选定元素进行更多的变换,可以应用transform属性。
transform属性应用于元素的2D或3D转换。这个属性允许将元素旋转、缩放、移动、倾斜等。其基本使用格式为:
transform: none|transform-functions;
其中,属性值none表示不进行转换;属性值transform-functions表示所采用的转换函数,可应用的转换函数和功能描述如下:
matrix(n,n,n,n,n,n) 定义 2D 转换,使用六个值的矩阵。
matrix3d(n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n) 定义 3D 转换,使用16个值的4x4矩阵。
translate(x,y) 定义 2D 平移转换。
translate3d(x,y,z) 定义 3D 平移转换。
translateX(x) 定义X 轴平移转换
translateY(y) 定义Y 轴平移转换
translateZ(z) 定义 Z 轴3D 平移转换
scale(x[,y]) 定义 2D 缩放转换。
scale3d(x,y,z) 定义 3D 缩放转换。
scaleX(x) 通过设置 X 轴的值来定义缩放转换。
scaleY(y) 通过设置 Y 轴的值来定义缩放转换。
scaleZ(z) 通过设置 Z 轴的值来定义 3D 缩放转换。
rotate(angle) 定义 2D 旋转,在参数中规定角度。
rotate3d(x,y,z,angle) 定义 3D 旋转。
rotateX(angle) 定义沿着 X 轴的 3D 旋转。
rotateY(angle) 定义沿着 Y 轴的 3D 旋转。
rotateZ(angle) 定义沿着 Z 轴的 3D 旋转。
skew(x-angle,y-angle) 定义沿着 X 和 Y 轴的 2D 倾斜转换。
skewX(angle) 定义沿着 X 轴的 2D 倾斜转换。
skewY(angle) 定义沿着 Y 轴的 2D 倾斜转换。
perspective(n) 为 3D 转换元素定义透视视图。
例如,transform: translate(50px,100px);表示元素从左边移动50个像素,并从顶部移动100像素。
将例1中.container:hover .move-box的定义修改为:
.container:hover .move-box
{
transform: translate(250px,0);
}
或
.container:hover .move-box
{
transform: translateX(250px);
}
同样可以实现如图2所示的页面效果。但transform属性的设置更灵活。
例如,将例1中.container:hover .move-box的定义修改为:
.container:hover .move-box
{
transform: translate(250px,150px);
}
则可得到如图4所示的动画效果。此时,蓝色小正方形在水平和垂直方向上都发生了平移。
图4 蓝色小正方形沿对角线平移
再如,将例1中.container:hover .move-box的定义修改为:
.container:hover .move-box
{
transform: rotate(45deg) translateX(200px);
}
则可得到如图5所示的动画效果。
图5 蓝色小正方形旋转并平移
例2 图片的平移、缩放和旋转变换。
在页面中放置一个类名为container的层作为效果展示容器,在该层中再定义一个9个子层,每个子层中放置一幅图片,为图片添加鼠标悬停变换效果,当鼠标悬停在某幅图片上时,该图片或平移、或缩放、或旋转。编写完整的HTML代码如下。
<!DOCTYPE html> <html> <head> <title>图片的平移、缩放和旋转变换</title> <style> *{ margin: 0; padding: 0; } .container { border: 3px solid rgba(255, 0, 255, 0.9); width: 1000px; height: 600px; display: flex; margin-left: 200px; flex-direction: row; flex-wrap: wrap; justify-content: space-around; align-content: space-around; } .container>div { width: 300px; height: 150px; transition-duration: 2s; } .container>div>img { width: 100%; height: 100%; } .container>div:nth-child(1):hover { transform: translate(665px,200px); } .container>div:nth-child(2):hover { transform: rotateX(60deg); } .container>div:nth-child(3):hover { transform: rotateY(60deg); } .container>div:nth-child(4):hover { transform: rotateX(360deg); } .container>div:nth-child(5):hover { transform: scale(2); } .container>div:nth-child(6):hover { transform: rotateY(360deg); } .container>div:nth-child(7):hover { transform: rotateZ(360deg); } .container>div:nth-child(8):hover { transform: rotateZ(180deg); } .container>div:nth-child(9):hover { transform: skew(30deg); } </style> </head> <body> <div class="container"> <div><img src="mlh.jpg" alt=""/></div> <div><img src="mls.jpg" alt=""/></div> <div><img src="mltc.png" alt=""/></div> <div><img src="mlyws.png" alt=""/></div> <div><img src="hhl.jpg" alt=""/></div> <div><img src="mlcy.png" alt=""/></div> <div><img src="mlmgy.png" alt=""/></div> <div><img src="mljlg.png" alt=""/></div> <div><img src="mlqlz.png" alt=""/></div> </div> </body> </html>
在浏览器中打开保存上述HTML代码的html文件,在浏览器中呈现出如图6所示的变换效果(部分示例)。
图6 图片旋转
transition的优点在于简单易用,但是它有几个很大的局限。
(1)transition需要事件触发,所以没法在网页加载时自动发生。例1和例2都是采用伪选择器hover,在鼠标悬停时产生动画效果。
(2)transition是一次性的,不能重复发生,除非一再触发。
(3)transition只能定义开始状态和结束状态,不能定义中间状态,也就是说只有两个状态。例如,例1中的蓝色小正方形只能沿一条指定的路线移动。若想让蓝色小正方形沿着上下左右边界转圈移动,transition属性就没法做到。
CSS Animation就是为了解决这些问题而提出的。
2.animation 属性
animation 属性是六个动画属性的简写属性,这6个属性是animation-name、animation-duration、animation-timing-function、animation-delay、animation-iteration-count和animation-direction。
(1)animation-name属性。
animation-name 属性为 @keyframes 动画规定名称。其格式为:
animation-name: keyframename|none;
其中,属性值keyframename规定需要绑定到选择器的keyframe的名称。属性值none规定无动画效果(可用于覆盖来自级联的动画)。
(2)animation-duration属性。
animation-duration 属性定义动画完成一个周期所需要的时间,以秒或毫秒计。其格式为: animation-duration: time;
(3)animation-timing-function属性。
animation-timing-function属性规定动画的速度曲线。速度曲线用于,使变化更为平滑。其格式为:
animation-timing-function: linear|ease|ease-in|ease-out|ease-in-out|cubic-bezier(n,n,n,n);
各属性值的功能描述如下:
linear 动画从头到尾的速度是相同的。
ease 默认。动画以低速开始,然后加快,在结束前变慢。
ease-in 动画以低速开始。
ease-out 动画以低速结束。
ease-in-out 动画以低速开始和结束。
cubic-bezier(n,n,n,n) 在 cubic-bezier 函数中定义自己的值。可能的值是从 0 到 1 的数值。
(4)animation-delay属性。
animation-delay 属性定义动画什么时候开始。其格式为:
animation-delay: time;
属性值time单位可以是秒(s)或毫秒(ms)。并且time允许负值,-2s 使动画马上开始,但跳过 2 秒进入动画。
(5)animation-iteration-count属性。
animation-iteration-count 属性定义动画的播放次数。其格式为:
animation-iteration-count: n|infinite;
其中,属性值n定义动画播放次数的数值;属性值infinite规定动画应该无限次播放。
(6)animation-direction属性。
animation-direction属性规定是否应该轮流反向播放动画。其格式为:
animation-direction: normal|reverse|alternate|alternate-reverse;
其中,属性值normal表示以正常的方式播放动画;reverse 以相反方向播放动画;alternate 播放动画时,每奇数时间(1,3,5…)正常播放,每偶数时间(2,4,6…)反方向播放; alternate-reverse播放动画时,每奇数时间(1,3,5…)反方向播放,每偶数时间(2,4,6…)正常播放。
例3 沿着容器边框转圈移动的蓝色小正方形。
修改例1中的效果,使得蓝色小正方形可以沿着上边框、右边框、下边框和左边框循环转圈。编写HTML文件如下。
<!DOCTYPE html> <html> <head> <title>沿边框四周移动的小正方形</title> <style> .container { width: 300px; height: 200px; border: 4px solid rgba(255, 0, 0, 0.9); } .move-box { left:0; top:0; width: 50px; height: 50px; position: relative; background: rgb(0,0,255); animation:myfirst 5s infinite; } @keyframes myfirst { 0% { left:0px; top:0px;} 25% { left:250px; top:0px;} 50% { left:250px; top:150px;} 75% { left:0px; top:150px; } 100% { left:0px; top:0px;} } </style> </head> <body> <div class="container"> <div class="move-box"> </div> </div> </body> </html>
在浏览器中打开保存上述HTML代码的html文件,在浏览器中呈现出如图7所示的动画效果。
图7 沿四周循环转圈的小正方形
如在上面CSS定义的“animation:myfirst 5s infinite;”语句后,再加上一条语句“animation-direction:alternate;” ,则得到如图8所示的动画效果,与图7的不同之处在于,偶数运动周期时,小正方形的移动方向沿着“左边框-->下边框-->右边框-->上边框”。
图8 沿四周循环转圈的小正方形
需要说明的是:Internet Explorer 10、Firefox 以及 Opera 等支持 animation 属性,Safari 和 Chrome 支持替代的 -webkit-animation 属性,而Internet Explorer 9 以及更早的版本不支持 animation 属性。因此,从浏览器兼容性的角度出发,在例3的HTML文件的CSS定义中可加上如下定义:
@-webkit-keyframes myfirst
{
0% { left:0px; top:0px;}
25% { left:250px; top:0px;}
50% { left:250px; top:150px;}
75% { left:0px; top:150px; }
100% { left:0px; top:0px;}
}
例4 图片的缩放、旋转和倾斜动画。
在页面中放置一个类名为container的层作为效果展示容器,在该层中再定义一个4个子层,每个子层中放置一幅图片,为每幅图片添加动画效果,第1幅图片缩小后放大,第2幅图片绕X轴翻转,第3幅图片沿Z轴旋转,第4幅图片倾斜。编写完整的HTML代码如下。
<!DOCTYPE html> <html> <head> <title>图片的缩放、旋转和倾斜变换</title> <style> *{ margin: 0; padding: 0; } .container { border: 3px solid rgba(255, 0, 255, 0.9); width: 850px; height: 550px; display: flex; margin: 0 auto; flex-direction: row; flex-wrap: wrap; justify-content: space-around; align-content: space-around; } .container>div { width: 400px; height:250px; } .container>div>img { width: 100%; height: 100%; } .container>div:nth-child(1) { animation:myAnim1 3s infinite; } @keyframes myAnim1 { 0% { transform: none;} 50% { transform: scale(0);} 100% { transform: scale(1);} } .container>div:nth-child(2) { animation:myAnim2 3s infinite; } @keyframes myAnim2 { 0% { transform: none;} 100% { transform: rotateX(360deg);} } .container>div:nth-child(3) { animation:myAnim3 3s infinite; } @keyframes myAnim3 { from { transform: none;} to { transform: rotateZ(360deg);} } .container>div:nth-child(4) { animation:myAnim4 3s infinite; } @keyframes myAnim4 { 0% { transform: none;} 33% { transform: skew(15deg,15deg);} 67% { transform: skew(-15deg,-15deg);} 100% { transform: skew(0deg,0deg);} } </style> </head> <body> <div class="container"> <div><img src="mlh.jpg" alt=""/></div> <div><img src="hhl.jpg" alt=""/></div> <div><img src="mlcy.png" alt=""/></div> <div><img src="mltc.png" alt=""/></div> </div> </body> </html>
在浏览器中打开保存上述HTML代码的html文件,在浏览器中呈现出如图9所示的动画效果。
图9 图片的缩放、旋转和倾斜动画
例5 旋转的文字。
在页面中放置一个类名为container的层作为效果展示容器,在该层中再定义一个3个子层,每个子层中放置一个汉字,为每个汉字所在的层添加动画效果,第1个汉字水平翻转,第2个汉字绕中心旋转,第3个汉字垂直翻转。编写完整的HTML代码如下。
<!DOCTYPE html> <html> <head> <title>欢乐颂</title> <style> .container { margin: 0 auto; width: 650px; height: 250px; display: flex; flex-direction: row; flex-wrap: wrap; border: 4px solid rgba(255, 0, 0, 0.9); } .container>div { width:200px; height:200px; margin:20px auto; text-align: center; font:800 100px/200px "隶书"; border-radius: 50%; transform-origin:center 50%; } .container>div:nth-child(1) { background:#f00; animation: anim1 2s infinite linear; } @keyframes anim1 { from { transform: rotate(0);} to { transform: rotateX(360deg);} } .container>div:nth-child(2) { background:#0f0; animation: anim2 2s infinite linear; } @keyframes anim2 { from { transform: rotate(0);} to { transform: rotate(360deg);} } .container>div:nth-child(3) { background:#00f; animation: anim3 2s infinite linear; } @keyframes anim3 { from { transform: rotate(0);} to { transform: rotateY(360deg);} } </style> </head> <body> <div class="container"> <div>欢</div><div>乐</div><div>颂</div> </div> </body> </html>
在浏览器中打开保存上述HTML代码的html文件,在浏览器中呈现出如图10所示的动画效果。
图10 汉字的旋转
例6 旋转的风车。
预先准备好一张风车的图片,在页面中放置一个类名为container的层作为效果展示容器,将风车图片作为该层的背景图片。鼠标悬停在层上时,风车旋转,鼠标移离,风车停止旋转。编写完整的HTML代码如下。
<!DOCTYPE html> <html> <head> <title>旋转的风车</title> <style> .container { margin: 0 auto; background-image: url(a1.png); width: 300px; height: 300px; background-position: center center; background-repeat: no-repeat; background-size: cover; border-radius: 50%; vertical-align: middle; border: 4px solid rgba(255, 0, 0, 0.9); } .container:hover { animation: anim 2s linear infinite; } @keyframes anim { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } </style> </head> <body> <div class="container"></div> </body> </html>
在浏览器中打开保存上述HTML代码的html文件,在浏览器中呈现出如图11所示的动画效果。
图11 旋转的风车
例7 方和圆。
实现方形变换为圆形,编写HTML代码如下。
<!DOCTYPE html> <html> <head> <title>方和圆</title> <style> .container { margin: 0 auto; width: 350px; height: 250px; border: 4px solid rgba(255, 0, 0, 0.9); } .container>div { width:100px; height:100px; position: relative; left:0; top:75px; animation: anim1 4s infinite; } @keyframes anim1 { from { background:#f00; transform:translate(0,0); } to { background:#00f; transform:translate(250px,0); border-radius: 50%; } } </style> </head> <body> <div class="container"> <div></div> </div> </body> </html>
在浏览器中打开保存上述HTML代码的html文件,在浏览器中呈现出如图12所示的动画效果。
图12 方和圆的变换