黄子涵

第 23 章 过渡、动画和变换

HTML文档应用简单特殊效果的方式:过渡、动画和变换。这三种特性都是在CSS3中新添加的。

为HTML元素应用某种效果的想法并不新鲜,大多数比较完善JavaScript库至少包含几种目前已经融入CSS3的效果。通过JavaScript操作CSS3的优势是性能。许多新功能涉及随着时间改变CSS属性的值,这类操作可以直接由浏览器引擎处理,还能节省开销。尽管如此,这些效果(即使是最基本的效果)会耗费大量处理能力,尤其是在一些复杂的Web页面上。

不能频繁使用这些效果的另外一个原因是它们会严重分散注意力,且非常恼人。使用这些效果去增强用户要在页面上执行的任务,不管具体任务是什么,而不要把这些效果应用到不属于任务核心的元素上。

使用过渡

过渡效果一般是由浏览器直接改变元素的CSS属性实现的。例如,如果使用:hover选择器, 一旦用户将鼠标悬停在元素之上,浏览器就会应用跟选择器关联的属性。代码清单1给出了一个示例。

代码清单1 直接应用新的属性值

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
        <style>
            @font-face {
                font-style: normal;
                font-weight: normal;
                font-family: '水果冰淇淋';
                src: url('http://192.168.1.102/HTML5权威指南/第22章 设置文本样式/水果冰淇淋.woff');
            }
            p {
                padding: 5px;
                border: medium double black;
                background-color: lightgray;
                font-family: '水果冰淇淋';
                font-size: xx-large;
            }
            #黄子涵 {
                font-size: xx-large;
            }
            #黄子涵:hover {
                font-size: larger;
                border: medium solid white;
                background-color: blue;
                color: white;
                padding: 4px;
            }
        </style>
    </head>
    <body>
        <p>
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            沉默以拥吻抵抗一切的冰与冷,晚意借北风轻轻的飘起长长裙
            多温馨心里风中那笑声 淌泪,尝尽了失意的我将一切都褪去
            再到这风中心中竟仿似伤痕累累,然后再记忆起当晚跟你在这里
            相依相拥中交出的心早已失去<span id="黄子涵">黄子涵</span>失去已破碎不可以再追洒泪
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            多久了,我都没变,爱你这回事,整整六年
            有一个人能去爱,多珍贵。没关系你也不用给我机会
            反正我还有一生可以浪费
        </p>
    </body>
</html>

在这个例子中,我为一个span元素定义了两种样式。一种通用样式(选择器#banana),一种样式只有在用户将鼠标悬停到元素上的时候才应用(#banana:hover选择器)。


提示

这个例子中使用了color属性


当用户将鼠标悬停在span元素上的时候,浏览器就会响应,直接应用新的属性值。变化如下图所示。

image

CSS过渡特性允许我们控制应用新属性值的速度。比如你可以选择逐渐改变示例中span元素 的外观,让鼠标移到单词banana上的效果更和谐。下表列出了能实现类似效果的属性。

过渡属性

属 性 说 明
transition-delay 指定过渡开始之前的延迟时间 <时间>
transition-duration 指定过渡的持续时间 <时间>
transition-property 指定应用过渡的属性 <字符串>
transition-timing-function 指定过渡期间计算中间值的方式
transition 在一条声明中指定所有过渡细节的简写属性

transition-delaytransition-duration属性指定为CSS时间,是一个数字,单位为ms(毫秒)或s(秒)。

transition简写属性的格式如下:

transition: <transition-property> <transition-duration> <transition-timing-function> <transition-delay>

代码清单2展示了如何为示例HTML文档应用过渡。除了IE,所有浏览器都可以使用厂商前缀实现这些属性。在下面的代码清单中我使用了-webkit前缀。


注意

主流浏览器也都没有使用标准属性实现动画特性。跟过渡一样,除了IE,各大浏览器也都使用厂商前缀实现了动画属性。在代码清单2中,我使用了-webkit前缀,也就是说这个例子是针对Safari和Chrome的。如果你想用Firefox和Opera尝试这个例子,很简单,用-moz或者-o替换-webkit即可。这是CSS3新增的另一块内容,希望它能赶紧完全实现。

代码清单2 使用过渡

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
        <style>
            @font-face {
                font-style: normal;
                font-weight: normal;
                font-family: '水果冰淇淋';
                src: url('http://192.168.1.102/HTML5权威指南/第22章 设置文本样式/水果冰淇淋.woff');
            }
            p {
                padding: 5px;
                border: medium double black;
                background-color: lightgray;
                font-family: '水果冰淇淋';
                font-size: xx-large;
            }
            #黄子涵 {
                font-size: x-large;
            }
            #黄子涵:hover {
                font-size: xx-large;
                border: medium solid white;
                background-color: blue;
                color: white;
                padding: 4px;
                -webkit-transition-delay: 100ms;
                -webkit-transition-property: background-color, color, padding, font-size, border;
                -webkit-transition-duration: 5000ms;                
            }
        </style>
    </head>
    <body>
        <p>
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            沉默以拥吻抵抗一切的冰与冷,晚意借北风轻轻的飘起长长裙
            多温馨心里风中那笑声 淌泪,尝尽了失意的我将一切都褪去
            再到这风中心中竟仿似伤痕累累,然后再记忆起当晚跟你在这里
            相依相拥中交出的心早已失去<span id="黄子涵">黄子涵</span>失去已破碎不可以再追洒泪
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            多久了,我都没变,爱你这回事,整整六年
            有一个人能去爱,多珍贵。没关系你也不用给我机会
            反正我还有一生可以浪费
        </p>
    </body>
</html>

在这个例子中,我为样式添加了过渡,是通过#banana:hover选择器应用的。过渡会在用户将鼠标悬停在span元素上100ms之后开始,持续时间为500ms,过渡应用到background-color、color、padding、font-size和border属性。下图展示了这个过渡的渐进过程。

image

注意这个示例中指定多个属性的方式。过渡属性的值用逗号隔开,这样过渡效果才会同时出现。可以为延迟时间和持续时间指定多个值,它代表的意思是不同的属性在不同的时间点开始过渡,且持续时间也不同。

创建反向过渡

过渡只有在应用与其关联的样式时才会生效。示例样式中使用了:hover选择器,这意味着只有用户将鼠标悬停在span元素上才会应用样式。用户一旦将鼠标从span元素上移开,只剩下#banana样式,默认情况下,元素的外观会立刻回到初始状态。

因为这个原因,大多数过渡成对出现:暂时状态的过渡和方向相反的反向过渡。代码清单3展示了如何通过应用另一种过渡样式平滑地返回初始样式。

代码清单3 创建另一种过渡

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
        <style>
            @font-face {
                font-style: normal;
                font-weight: normal;
                font-family: '水果冰淇淋';
                src: url('http://192.168.1.102/HTML5权威指南/第22章 设置文本样式/水果冰淇淋.woff');
            }
            p {
                padding: 5px;
                border: medium double black;
                background-color: lightgray;
                font-family: '水果冰淇淋';
                font-size: xx-large;
            }
            #黄子涵 {
                font-size: x-large;
                border: medium solid black;
                -webkit-transition-delay: 10ms;
                -webkit-transition-duration: 2500ms;
            }
            #黄子涵:hover {
                font-size: xx-large;
                border: medium solid white;
                background-color: blue;
                color: white;
                padding: 4px;
                -webkit-transition-delay: 100ms;
                -webkit-transition-property: background-color, color, padding, font-size, border;
                -webkit-transition-duration: 5000ms;                
            }
        </style>
    </head>
    <body>
        <p>
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            沉默以拥吻抵抗一切的冰与冷,晚意借北风轻轻的飘起长长裙
            多温馨心里风中那笑声 淌泪,尝尽了失意的我将一切都褪去
            再到这风中心中竟仿似伤痕累累,然后再记忆起当晚跟你在这里
            相依相拥中交出的心早已失去<span id="黄子涵">黄子涵</span>失去已破碎不可以再追洒泪
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            多久了,我都没变,爱你这回事,整整六年
            有一个人能去爱,多珍贵。没关系你也不用给我机会
            反正我还有一生可以浪费
        </p>
    </body>
</html>

这个例子中我省略了transition-property属性,这样所有的属性者都会在整个持续时间内逐渐应用过渡。我还指定了初始10ms的延迟,以及250ms的持续时间。添加一个反向过渡后,返回初始状态看上去就没那么突兀了。

image


提示

刚开始布局页面时浏览器不会应用过渡。这意味着HTML文档一开始显示时就会直接应用#banana样式,之后才会通过过渡来应用新样式。


选择中间值的计算方式

使用过渡时,浏览器需要为每个属性计算初始值和最终值之间的中间值。使用transition-timing-function属性指定计算中间值的方式,表示为四个点控制的三次贝塞尔曲线。有五种预设曲线可以选择,由下面的值表示:

  • ease (默认值)
  • linear
  • ease-in
  • ease-out
  • ease-in-out

从下图可以看到这五种曲线,它们展示了中间值随着时间的推移变为最终值的速率。

image

搞清楚这些值最简单的办法就是在自己的HTML文档中试验。还有另外一个值cubic-bezier,可用来指定自定义曲线。不过,我的体会是过渡没那么平滑,缺乏粒度破坏了大多数值,这同时也导致指定自定义曲线基本上毫无意义。希望实现能在最终的标准中得以集中改善。代码清单4展示了 transition-timing-function属性的应用。

代码清单4 使用transition-timing-function属性

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
        <style>
            @font-face {
                font-style: normal;
                font-weight: normal;
                font-family: '水果冰淇淋';
                src: url('http://192.168.1.102/HTML5权威指南/第22章 设置文本样式/水果冰淇淋.woff');
            }
            p {
                padding: 5px;
                border: medium double black;
                background-color: lightgray;
                font-family: '水果冰淇淋';
                font-size: xx-large;
            }
            #黄子涵 {
                font-size: x-large;
                border: medium solid black;
                -webkit-transition-delay: 10ms;
                -webkit-transition-duration: 2500ms;
            }
            #黄子涵:hover {
                font-size: xx-large;
                border: medium solid white;
                background-color: blue;
                color: white;
                padding: 4px;
                -webkit-transition-delay: 100ms;
                -webkit-transition-property: background-color, color, padding, font-size, border;
                -webkit-transition-duration: 5000ms;
                -webkit-transition-timing-function: linear;
            }
        </style>
    </head>
    <body>
        <p>
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            沉默以拥吻抵抗一切的冰与冷,晚意借北风轻轻的飘起长长裙
            多温馨心里风中那笑声 淌泪,尝尽了失意的我将一切都褪去
            再到这风中心中竟仿似伤痕累累,然后再记忆起当晚跟你在这里
            相依相拥中交出的心早已失去<span id="黄子涵">黄子涵</span>失去已破碎不可以再追洒泪
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            多久了,我都没变,爱你这回事,整整六年
            有一个人能去爱,多珍贵。没关系你也不用给我机会
            反正我还有一生可以浪费
        </p>
    </body>
</html>

这里我选择了linear,个人感觉它是过渡效果最为流畅的一个值。

image

使用动画

CSS动画本质上是增强的过渡。在如何从一种CSS样式过渡到另一种样式的过程中,你具有了更多选择、更多控制,以及更多灵活性。下表列岀了动画属性。

动画属性

属 性 说 明
animation-delay 设置动画开始前的延迟 <时间>
animation-direction 设置动画循环播放的时候是否反向播放 normal alternate
animation-duration 设置动画播放的持续时间 <时间>
animation-iteration-count 设置动画的播放次数 infinit <数值>
animation-name 指定动画名称 none <字符串>
animation-play-state 允许动画暂停和重新播放 running paused
animation-timmg-function 指定如何计算中间动画值 ease linear ease-in ease-out ease-in-out cubic-bezier
animation 简写属性

animation简写属性的格式如下:

animation: <animation-name> <animation.duration> <animation-timing-function> <animation-delay> <animation-iteration-count>

注意,这些属性都不是用来指定要作为动画的CSS属性的。这是因为动画是在两部分定义的。第一部分包含在样式声明中,使用下表列出的属性。它们定义了动画的样式,但并没有定义哪些属性是动画。第二部分使用@key-frames规则创建,用来定义应用动画的属性。从代码清单5中可以看到定义动画的这两部分。

代码清单5 创建动画

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
        <style>
            @font-face {
                font-style: normal;
                font-weight: normal;
                font-family: '水果冰淇淋';
                src: url('http://192.168.1.102/HTML5权威指南/第22章 设置文本样式/水果冰淇淋.woff');
            }
            p {
                padding: 5px;
                border: medium double black;
                background-color: lightgray;
                font-family: '水果冰淇淋';
                font-size: xx-large;
            }
            #黄子涵 {
                font-size: x-large;
                border: medium solid black;
            }
            #黄子涵:hover {
                -webkit-animation-delay: 100ms;
                -webkit-animation-duration: 5000ms;
                -webkit-animation-iteration-count: infinite;
                -webkit-transition-timing-function: linear;
                -webkit-animation-name: 'GrowShrink';
            }
            @-webkit-keyframes GrowShrink {
                to {
                    font-size: x-large;
                    border: medium solid white;
                    background-color: blue;
                    color: white;
                    padding: 4px;
                }
            }
        </style>
    </head>
    <body>
        <p>
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            沉默以拥吻抵抗一切的冰与冷,晚意借北风轻轻的飘起长长裙
            多温馨心里风中那笑声 淌泪,尝尽了失意的我将一切都褪去
            再到这风中心中竟仿似伤痕累累,然后再记忆起当晚跟你在这里
            相依相拥中交出的心早已失去<span id="黄子涵">黄子涵</span>失去已破碎不可以再追洒泪
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            多久了,我都没变,爱你这回事,整整六年
            有一个人能去爱,多珍贵。没关系你也不用给我机会
            反正我还有一生可以浪费
        </p>
    </body>
</html>

要明白我们在这个示例中做了什么,你应该仔细研究一下动画的两部分。第一部分是在样式中定义动画属性,是跟#banana:hover选择器一起的。我们先看看基本属性:选择器样式应用100ms后开始播放动画,持续时间500ms,无限重复播放,中间值使用linear函数计算。除了重复播放动画,这些属性在过渡中都有对应属性。

这些基本的属性并没有指出为哪些CSS属性应用动画。为此,要使用animation-name属性给动画属性起个名字,这里叫GrowShrink。这样,就相当于告诉浏览器找一组名为GrowShrink的关键帧,然后将这些基本属性的值应用到@keyframes指定的动画属性上。下面是代码清单中关键帧的声明(我省略了-webkit前缀):

@keyframes GrowShrink {
   to {
        font-size: x-large;
		border: medium solid white;
		background-color: green;
		color: white;
		padding: 4px;
   }
}

声明的开始是@keyframes,接着指定了这组关键帧的名字GrowShrink。声明内部指定了一组要应用动画效果的属性。这里在一个to声明中指定了五个属性及其值。这是关键帧设置最简单的类型。to声明定义了一组设置动画样式的属性,同时也定义了动画结束时这些属性的最终值。(稍后会向你展示更复杂的关键帧。)动画的初始值来自进行动画处理的元素在应用样式之前的属性值。

代码清单中的动画跟本章之前为过渡应用的示例相同,在浏览器中查看HTML文档并且将鼠标悬停在span元素上后,效果甚至也看起来差不多。最起码刚开始看起来是完全一样的,然后动画不断重复,这是第一点不同。span元素变大,达到最大值,然后返回初始值,这时动画重新开始,效果如下图所示。

image

使用关键帧

CSS动画的关键帧极其灵活,非常值得研究。

设置初始状态

在前面的示例中,要处理为动画的属性的初始值来自元素自身。你可以使用from子句指定另一组初始值,如代码清单6所示。

代码清单6 指定另一组初始值
<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
        <style>
            @font-face {
                font-style: normal;
                font-weight: normal;
                font-family: '水果冰淇淋';
                src: url('http://192.168.1.102/HTML5权威指南/第22章 设置文本样式/水果冰淇淋.woff');
            }
            p {
                padding: 5px;
                border: medium double black;
                background-color: lightgray;
                font-family: '水果冰淇淋';
                font-size: xx-large;
            }
            #黄子涵 {
                font-size: x-large;
                border: medium solid black;
            }
            #黄子涵:hover {
                -webkit-animation-delay: 100ms;
                -webkit-animation-duration: 5000ms;
                -webkit-animation-iteration-count: infinite;
                -webkit-transition-timing-function: linear;
                -webkit-animation-name: 'GrowShrink';
            }
            @-webkit-keyframes GrowShrink {
                from {
                    font-size: small;
                    background-color: red;
                }
                
                to {
                    font-size: x-large;
                    border: medium solid white;
                    background-color: blue;
                    color: white;
                    padding: 4px;
                }
            }
        </style>
    </head>
    <body>
        <p>
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            沉默以拥吻抵抗一切的冰与冷,晚意借北风轻轻的飘起长长裙
            多温馨心里风中那笑声 淌泪,尝尽了失意的我将一切都褪去
            再到这风中心中竟仿似伤痕累累,然后再记忆起当晚跟你在这里
            相依相拥中交出的心早已失去<span id="黄子涵">黄子涵</span>失去已破碎不可以再追洒泪
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            多久了,我都没变,爱你这回事,整整六年
            有一个人能去爱,多珍贵。没关系你也不用给我机会
            反正我还有一生可以浪费
        </p>
    </body>
</html>

在这个例子中,我为font-sizebackground-color属性提供了初始值,在to子句中指定的其他属性在动画开始时的初始值来自元素自身。新子句的效果如下图所示。动画开始时,文本大小和span元素的背景颜色变为行from子句中指定的初始值。

image

指定中间关键帧

也可以添加其他关键帧定义动画的中间阶段。这是通过添加百分数子句实现的,如代码清单7所示。

代码清单7 添加中间关键帧
<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
        <style>
            @font-face {
                font-style: normal;
                font-weight: normal;
                font-family: '水果冰淇淋';
                src: url('http://192.168.1.102/HTML5权威指南/第22章 设置文本样式/水果冰淇淋.woff');
            }
            p {
                padding: 5px;
                border: medium double black;
                background-color: lightgray;
                font-family: '水果冰淇淋';
                font-size: xx-large;
            }
            #黄子涵 {
                font-size: x-large;
                border: medium solid black;
            }
            #黄子涵:hover {
                -webkit-animation-delay: 100ms;
                -webkit-animation-duration: 20000ms;
                -webkit-animation-iteration-count: infinite;
                -webkit-transition-timing-function: linear;
                -webkit-animation-name: 'GrowShrink';
            }
            @-webkit-keyframes GrowShrink {
                from {
                    font-size: small;
                    background-color: red;
                }
                
                14% {
                    background-color: orange;
                    padding: 2px;
                }
                
                42% {
                    background-color: yellow;
                    padding: 3px;
                }
                
                56% {
                    background-color: green;
                    padding: 4px;
                }
                
                70% {
                    background-color: cyan;
                    padding: 5px;
                }
                
                84% {
                    background-color: blue;
                    padding: 6px;
                }
                
                to {
                    font-size: x-large;
                    border: medium solid white;
                    background-color: purple;
                    color: white;
                    padding: 7px;
                }
            }
        </style>
    </head>
    <body>
        <p>
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            沉默以拥吻抵抗一切的冰与冷,晚意借北风轻轻的飘起长长裙
            多温馨心里风中那笑声 淌泪,尝尽了失意的我将一切都褪去
            再到这风中心中竟仿似伤痕累累,然后再记忆起当晚跟你在这里
            相依相拥中交出的心早已失去<span id="黄子涵">黄子涵</span>失去已破碎不可以再追洒泪
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            多久了,我都没变,爱你这回事,整整六年
            有一个人能去爱,多珍贵。没关系你也不用给我机会
            反正我还有一生可以浪费
        </p>
    </body>
</html>

对于每一个百分数子句,你在动画中定义了一个点,这时子句中指定的属性和值会完全应用到样式上。在这个例子中,我定义了50%和75%子句。

中间关键帧有两个用途。一是为属性定义新的变化速率。padding属性的设置就是从这个角度出发的。在中间点(由50%子句定义),动画元素的内边距是1px;在75%处,内边距是2px;而在动画结束的时候,内边距被设置为4px。浏览器会使用animation-timing-function属性指定的调速函数计算由一个关键帧移动到下一个关键帧需要的中间值,以确保关键帧与关键帧之间流畅地播放。


提示

如果你自己有所偏好,也可以分别使用0%和100%代替from和to子句定义开始关键帧和结束关键帧。


中间关键帧的另一个用途是定义属性值,以便创建更为复杂的动画。background-color属性的设置就是从这个角度出发的。初始值(red)在任子句中定义,在50%处,这个值会变成yellow,而在动画结束时,它又会成为green。通过添加非序列化的中间值,我在一个动画中创建了两个颜色过渡:由红色到黄色,由黄色到绿色。注意,我没有在75%子句中设置颜色的中间值,因为不必给每个关键帧都设置值。新关键帧的效果如下图所示。

image

设置重复方向

动画结束后浏览器可以选择接下来动画以何种方式重复。使用animation-direction属性指定首选方式,下表列出了这个属性允许的值。

animation-direction属性的值

说明
normal 每次重复都向前播放,如果可重复播放多次,每次动画都恢复初始状态,从头开始播放
alternate 动画先向前播放,然后反方向播放,相当于animation-iteration-count属性的值为2

代码清单8展示了animation-direction属性的用法。

代码清单8 使用animation-direction属性

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
        <style>
            @font-face {
                font-style: normal;
                font-weight: normal;
                font-family: '水果冰淇淋';
                src: url('http://192.168.1.102/HTML5权威指南/第22章 设置文本样式/水果冰淇淋.woff');
            }
            p {
                padding: 5px;
                border: medium double black;
                background-color: lightgray;
                font-family: '水果冰淇淋';
                font-size: xx-large;
            }
            #黄子涵 {
                font-size: x-large;
                border: medium solid black;
            }
            #黄子涵:hover {
                -webkit-animation-delay: 100ms;
                -webkit-animation-duration: 20000ms;
                -webkit-animation-iteration-count: 2;
                -webkit-animation-iteration-count: infinite;
                -webkit-transition-timing-function: linear;
                -webkit-animation-name: 'GrowShrink';
                -webkit-animation-direction: alternate;
            }
            @-webkit-keyframes GrowShrink {
                from {
                    font-size: small;
                    background-color: red;
                }
                
                14% {
                    background-color: orange;
                    padding: 2px;
                }
                
                42% {
                    background-color: yellow;
                    padding: 3px;
                }
                
                56% {
                    background-color: green;
                    padding: 4px;
                }
                
                70% {
                    background-color: cyan;
                    padding: 5px;
                }
                
                84% {
                    background-color: blue;
                    padding: 6px;
                }
                
                to {
                    font-size: x-large;
                    border: medium solid white;
                    background-color: purple;
                    color: white;
                    padding: 7px;
                }
            }
        </style>
    </head>
    <body>
        <p>
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            沉默以拥吻抵抗一切的冰与冷,晚意借北风轻轻的飘起长长裙
            多温馨心里风中那笑声 淌泪,尝尽了失意的我将一切都褪去
            再到这风中心中竟仿似伤痕累累,然后再记忆起当晚跟你在这里
            相依相拥中交出的心早已失去<span id="黄子涵">黄子涵</span>失去已破碎不可以再追洒泪
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            多久了,我都没变,爱你这回事,整整六年
            有一个人能去爱,多珍贵。没关系你也不用给我机会
            反正我还有一生可以浪费
        </p>
    </body>
</html>

在这个例子中,我使用了animation-iteration-count属性指定动画重复播放两次。第二次迭代结束后,动画元素就回到初始状态。我为animation-direction属性使用了alternate值,动画就会首先向前播放,之后反方向播放。效果如下图所示。

如果将animation-iteration-count属性的值设为infinite,那么只要鼠标悬停在span元素上,动画就无休止地向前和向后交替播放。

normal值则会让动画回到初始状态,每次重复播放都是向前播放。效果如下图所示。

image

理解结束状态

CSS动画的一个局限是关键帧为属性定义的值只能在动画中应用。动画结束后,动画元素的外观回到初始状态。代码清单9给出了一个例子。

代码清单9 动画结束后动画状态丢失

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
        <style>
            @font-face {
                font-style: normal;
                font-weight: normal;
                font-family: '水果冰淇淋';
                src: url('http://192.168.1.102/HTML5权威指南/第22章 设置文本样式/水果冰淇淋.woff');
            }
            p {
                padding: 5px;
                border: medium double black;
                background-color: lightgray;
                font-family: '水果冰淇淋';
                font-size: xx-large;
            }
            #黄子涵 {
                font-size: x-large;
                border: medium solid black;
            }
            #黄子涵:hover {
                -webkit-animation-delay: 100ms;
                -webkit-animation-duration: 20000ms;
                -webkit-animation-iteration-count: 1;
                -webkit-transition-timing-function: linear;
                -webkit-animation-name: 'GrowShrink';
                -webkit-animation-direction: alternate;
            }
            @-webkit-keyframes GrowShrink {
                from {
                    font-size: small;
                    background-color: red;
                }
                
                14% {
                    background-color: orange;
                    padding: 2px;
                }
                
                42% {
                    background-color: yellow;
                    padding: 3px;
                }
                
                56% {
                    background-color: green;
                    padding: 4px;
                }
                
                70% {
                    background-color: cyan;
                    padding: 5px;
                }
                
                84% {
                    background-color: blue;
                    padding: 6px;
                }
                
                to {
                    font-size: x-large;
                    border: medium solid white;
                    background-color: purple;
                    color: white;
                    padding: 7px;
                }
            }
        </style>
    </head>
    <body>
        <p>
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            沉默以拥吻抵抗一切的冰与冷,晚意借北风轻轻的飘起长长裙
            多温馨心里风中那笑声 淌泪,尝尽了失意的我将一切都褪去
            再到这风中心中竟仿似伤痕累累,然后再记忆起当晚跟你在这里
            相依相拥中交出的心早已失去<span id="黄子涵">黄子涵</span>失去已破碎不可以再追洒泪
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            多久了,我都没变,爱你这回事,整整六年
            有一个人能去爱,多珍贵。没关系你也不用给我机会
            反正我还有一生可以浪费
        </p>
    </body>
</html>

这段代码制造的效果如下图所示。即使鼠标仍然悬停在span元素上,元素的外观在动画结束后就回到了初始状态一动画状态完全消失。

image

出现这种情况的原因是CSS动画只是驱动新样式的应用,并没有让自身出现任何持久变化。

初始布局时应用动画

跟过渡相比,动画的一个优势是你可以将其应用到页面的初始布局。代码清单10给出了一个例子。

代码清单10 在页面初始布局时为元素应用动画

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
        <style>
            @font-face {
                font-style: normal;
                font-weight: normal;
                font-family: '水果冰淇淋';
                src: url('http://192.168.1.102/HTML5权威指南/第22章 设置文本样式/水果冰淇淋.woff');
            }
            p {
                padding: 5px;
                border: medium double black;
                background-color: lightgray;
                font-family: '水果冰淇淋';
                font-size: xx-large;
            }
            #黄子涵 {
                font-size: x-large;
                border: medium solid black;
                -webkit-animation-duration: 10000ms;
                -webkit-animation-iteration-count: infinite;
                -webkit-animation-direction: alternate;
                -webkit-animation-timing-function: linear;
                -webkit-animation-name: 'ColorSwap';
            }
            @-webkit-keyframes ColorSwap {
                from {
                    font-size: small;
                    background-color: red;
                }
                
                14% {
                    background-color: orange;
                    padding: 2px;
                }
                
                42% {
                    background-color: yellow;
                    padding: 3px;
                }
                
                56% {
                    background-color: green;
                    padding: 4px;
                }
                
                70% {
                    background-color: cyan;
                    padding: 5px;
                }
                
                84% {
                    background-color: blue;
                    padding: 6px;
                }
                
                to {
                    font-size: x-large;
                    border: medium solid white;
                    background-color: purple;
                    color: white;
                    padding: 7px;
                }
            }
        </style>
    </head>
    <body>
        <p>
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            沉默以拥吻抵抗一切的冰与冷,晚意借北风轻轻的飘起长长裙
            多温馨心里风中那笑声 淌泪,尝尽了失意的我将一切都褪去
            再到这风中心中竟仿似伤痕累累,然后再记忆起当晚跟你在这里
            相依相拥中交出的心早已失去<span id="黄子涵">黄子涵</span>失去已破碎不可以再追洒泪
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            多久了,我都没变,爱你这回事,整整六年
            有一个人能去爱,多珍贵。没关系你也不用给我机会
            反正我还有一生可以浪费
        </p>
    </body>
</html>

在这个例子中,我在样式的#banana选择器中定义了动画。页面一旦加载就会自动应用样式,这就意味着浏览器一旦显示HTML就有了动画效果。

image


提示

使用上述方法要谨慎。如果要在页面中使用动画,而动画效果不是邀请用户执行某一动作,这种情况更应该慎之又慎。如果确实要使用动画,要保证动画效果缓和一些,不要妨碍用户阅读或者与页面其他部分交互。


重用关键帧

我们可以对同一组关键帧应用多个动画,从而为动画属性配置不同的值。代码清单11给出了一个示例。

代码清单11 在多个动画之间重用关键帧

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
        <style>
            @font-face {
                font-style: normal;
                font-weight: normal;
                font-family: '水果冰淇淋';
                src: url('http://192.168.1.102/HTML5权威指南/第22章 设置文本样式/水果冰淇淋.woff');
            }
            p {
                padding: 5px;
                border: medium double black;
                background-color: lightgray;
                font-family: '水果冰淇淋';
                font-size: xx-large;
            }
            span {
                font-size: x-large;
                border: medium solid black;
            }
            #黄子涵是帅哥 {
                -webkit-animation-duration: 10000ms;
                -webkit-animation-iteration-count: infinite;
                -webkit-animation-direction: alternate;
                -webkit-animation-timing-function: linear;
                -webkit-animation-name: 'ColorSwap';
            }
            #黄子涵是靓仔 {
                -webkit-animation-duration: 20000ms;
                -webkit-animation-iteration-count: infinite;
                -webkit-animation-direction: normal;
                -webkit-animation-timing-function: ease-in-out;
                -webkit-animation-name: 'ColorSwap';
            }
            @-webkit-keyframes ColorSwap {
                from {
                    font-size: small;
                    background-color: red;
                }
                
                14% {
                    background-color: orange;
                    padding: 2px;
                }
                
                42% {
                    background-color: yellow;
                    padding: 3px;
                }
                
                56% {
                    background-color: green;
                    padding: 4px;
                }
                
                70% {
                    background-color: cyan;
                    padding: 5px;
                }
                
                84% {
                    background-color: blue;
                    padding: 6px;
                }
                
                to {
                    font-size: x-large;
                    border: medium solid white;
                    background-color: purple;
                    color: white;
                    padding: 7px;
                }
            }
        </style>
    </head>
    <body>
        <p>
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            沉默以拥吻抵抗一切的冰与冷,晚意借北风轻轻的飘起长长裙
            多温馨心里风中那笑声淌泪,<span id="黄子涵是帅哥">黄子涵是帅哥</span>尝尽了失意的我将一切都褪去
            再到这风中心中竟仿似伤痕累累,然后再记忆起当晚跟你在这里
            相依相拥中交出的心早已失去失去已破碎不可以再追洒泪
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            多久了,我都没变,<span id="黄子涵是靓仔">黄子涵是靓仔</span>爱你这回事,整整六年
            有一个人能去爱,多珍贵。没关系你也不用给我机会
            反正我还有一生可以浪费
        </p>
    </body>
</html>

代码清单11展示了两个样式,它们都使用了ColorSwap关键帧。跟#apple选择器关联的动画会执行一小段时间,且跟#banana选择器关联的动画使用的计时函数不同,不过两者都是向前播放。

image

为多个元素应用多个动画

前面例子的一个变体是为多个元素应用同一个动画。在包含动画细节的样式中,扩展选择器的范围即可实现这一点,如代码清单12所示。

代码清单12 为多个元素应用一个动画

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
        <style>
            @font-face {
                font-style: normal;
                font-weight: normal;
                font-family: '水果冰淇淋';
                src: url('http://192.168.1.102/HTML5权威指南/第22章 设置文本样式/水果冰淇淋.woff');
            }
            p {
                padding: 5px;
                border: medium double black;
                background-color: lightgray;
                font-family: '水果冰淇淋';
                font-size: xx-large;
            }
            span {
                font-size: x-large;
                border: medium solid black;
            }
            #黄子涵是帅哥, #黄子涵是靓仔 {
                -webkit-animation-duration: 10000ms;
                -webkit-animation-iteration-count: infinite;
                -webkit-animation-direction: alternate;
                -webkit-animation-timing-function: linear;
                -webkit-animation-name: 'ColorSwap';
            }
            @-webkit-keyframes ColorSwap {
                from {
                    font-size: small;
                    background-color: red;
                }
                
                14% {
                    background-color: orange;
                    padding: 2px;
                }
                
                42% {
                    background-color: yellow;
                    padding: 3px;
                }
                
                56% {
                    background-color: green;
                    padding: 4px;
                }
                
                70% {
                    background-color: cyan;
                    padding: 5px;
                }
                
                84% {
                    background-color: blue;
                    padding: 6px;
                }
                
                to {
                    font-size: x-large;
                    border: medium solid white;
                    background-color: purple;
                    color: white;
                    padding: 7px;
                }
            }
        </style>
    </head>
    <body>
        <p>
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            沉默以拥吻抵抗一切的冰与冷,晚意借北风轻轻的飘起长长裙
            多温馨心里风中那笑声淌泪,<span id="黄子涵是帅哥">黄子涵是帅哥</span>尝尽了失意的我将一切都褪去
            再到这风中心中竟仿似伤痕累累,然后再记忆起当晚跟你在这里
            相依相拥中交出的心早已失去失去已破碎不可以再追洒泪
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            多久了,我都没变,<span id="黄子涵是靓仔">黄子涵是靓仔</span>爱你这回事,整整六年
            有一个人能去爱,多珍贵。没关系你也不用给我机会
            反正我还有一生可以浪费
        </p>
    </body>
</html>

在这个例子中,文档中的两个span元素都跟选择器匹配,因此都会使用关键帧和相同的配置应用动画,效果如下图所示。

image

我们还可以为一个元素应用多个动画,只需用逗号将动画属性的不同值隔开即可。代码清单13展示了如何为一个元素应用多个关键帧。

代码清单13 为一个元素应用多个关键帧

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
        <style>
            @font-face {
                font-style: normal;
                font-weight: normal;
                font-family: '水果冰淇淋';
                src: url('http://192.168.1.102/HTML5权威指南/第22章 设置文本样式/水果冰淇淋.woff');
            }
            p {
                padding: 5px;
                border: medium double black;
                background-color: lightgray;
                font-family: '水果冰淇淋';
                font-size: xx-large;
            }
            span {
                font-size: x-large;
                border: medium solid black;
            }
            #黄子涵是帅哥, #黄子涵是靓仔 {
                -webkit-animation-duration: 10000ms;
                -webkit-animation-iteration-count: infinite;
                -webkit-animation-direction: alternate;
                -webkit-animation-timing-function: linear;
                -webkit-animation-name: 'ColorSwap', 'GrowShrink';
            }
            @-webkit-keyframes ColorSwap {
                from {
                    font-size: small;
                    background-color: red;
                }
                
                14% {
                    background-color: orange;
                    padding: 2px;
                }
                
                42% {
                    background-color: yellow;
                    padding: 3px;
                }
                
                56% {
                    background-color: green;
                    padding: 4px;
                }
                
                70% {
                    background-color: cyan;
                    padding: 5px;
                }
                
                84% {
                    background-color: blue;
                    padding: 6px;
                }
                
                to {
                    border: medium solid white;
                    background-color: purple;
                    color: white;
                }
            }
            @-webkit-keyframes GrowShrink {
                from {
                    font-size: small;
                    background-color: red;
                }
                
                14% {
                    background-color: orange;
                    padding: 2px;
                }
                
                42% {
                    background-color: yellow;
                    padding: 3px;
                }
                
                56% {
                    background-color: green;
                    padding: 4px;
                }
                
                70% {
                    background-color: cyan;
                    padding: 5px;
                }
                
                84% {
                    background-color: blue;
                    padding: 6px;
                }
                
                to {
                    font-size: x-large;
                    color: white;
                    padding: 7px;
                }
            }
        </style>
    </head>
    <body>
        <p>
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            沉默以拥吻抵抗一切的冰与冷,晚意借北风轻轻的飘起长长裙
            多温馨心里风中那笑声淌泪,<span id="黄子涵是帅哥">黄子涵是帅哥</span>尝尽了失意的我将一切都褪去
            再到这风中心中竟仿似伤痕累累,然后再记忆起当晚跟你在这里
            相依相拥中交出的心早已失去失去已破碎不可以再追洒泪
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            多久了,我都没变,<span id="黄子涵是靓仔">黄子涵是靓仔</span>爱你这回事,整整六年
            有一个人能去爱,多珍贵。没关系你也不用给我机会
            反正我还有一生可以浪费
        </p>
    </body>
</html>

在这个例子中,我为#banana和#apple选择器应用了ColorSwap和GrowShrink关键帧,浏览器会同时应用两个关键帧。

image

停止和启动动画

animation-play-state属性可以用来停止和启动动画。如果这个属性的值为paused,动画就会停止。如果换成playing,动画就会开始播放。代码清单14展示了如何使用JavaScript改变这个属性的值。

代码清单14 停止和启动动画

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
        <style>
            @font-face {
                font-style: normal;
                font-weight: normal;
                font-family: '水果冰淇淋';
                src: url('http://192.168.1.102/HTML5权威指南/第22章 设置文本样式/水果冰淇淋.woff');
            }
            #黄子涵 {
                padding: 5px;
                border: medium double black;
                background-color: lightgray;
                font-family: '水果冰淇淋';
                font-size: xx-large;
            }
            span {
                font-size: x-large;
                border: medium solid black;
            }
            #黄子涵是帅哥, #黄子涵是靓仔 {
                -webkit-animation-duration: 10000ms;
                -webkit-animation-iteration-count: infinite;
                -webkit-animation-direction: alternate;
                -webkit-animation-timing-function: linear;
                -webkit-animation-name: 'ColorSwap', 'GrowShrink';
            }
            @-webkit-keyframes ColorSwap {
                from {
                    font-size: small;
                    background-color: red;
                }
                
                14% {
                    background-color: orange;
                    padding: 2px;
                }
                
                42% {
                    background-color: yellow;
                    padding: 3px;
                }
                
                56% {
                    background-color: green;
                    padding: 4px;
                }
                
                70% {
                    background-color: cyan;
                    padding: 5px;
                }
                
                84% {
                    background-color: blue;
                    padding: 6px;
                }
                
                to {
                    border: medium solid white;
                    background-color: purple;
                    color: white;
                }
            }
            @-webkit-keyframes GrowShrink {
                from {
                    font-size: small;
                    background-color: red;
                }
                
                14% {
                    background-color: orange;
                    padding: 2px;
                }
                
                42% {
                    background-color: yellow;
                    padding: 3px;
                }
                
                56% {
                    background-color: green;
                    padding: 4px;
                }
                
                70% {
                    background-color: cyan;
                    padding: 5px;
                }
                
                84% {
                    background-color: blue;
                    padding: 6px;
                }
                
                to {
                    font-size: x-large;
                    color: white;
                    padding: 7px;
                }
            }
        </style>
    </head>
    <body>
        <p id="黄子涵">
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            沉默以拥吻抵抗一切的冰与冷,晚意借北风轻轻的飘起长长裙
            多温馨心里风中那笑声淌泪,<span id="黄子涵是帅哥">黄子涵是帅哥</span>尝尽了失意的我将一切都褪去
            再到这风中心中竟仿似伤痕累累,然后再记忆起当晚跟你在这里
            相依相拥中交出的心早已失去失去已破碎不可以再追洒泪
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            多久了,我都没变,<span id="黄子涵是靓仔">黄子涵是靓仔</span>爱你这回事,整整六年
            有一个人能去爱,多珍贵。没关系你也不用给我机会
            反正我还有一生可以浪费
        </p>
        <p>
            <button>Running</button>
            <button>Paused</button>
        </p>
        <script>
            var buttons = document.getElementsByTagName("BUTTON");
            for(var i = 0; i < buttons.length; i++) {
                buttons[i].onclick = function(e) {
                    document.getElementById("黄子涵是帅哥").style.webkitAnimationPlayState = e.target.innerHTML;
                    document.getElementById("黄子涵是靓仔").style.webkitAnimationPlayState = e.target.innerHTML;
                }
            }
        </script>
    </body>
</html>

image

使用变换

我们可以使用CSS变换为元素应用线性变换,也就是说你可以旋转、缩放、倾斜和平移某个元素。下表列岀了应用变换使用的属性。

transform属性

属 性 说 明
transform 指定应用的变换功能
transform-origin 指定变换的起点

应用变换

我们通过transform属性为元素应用变换。这个属性允许的值是一组预定义的函数,如下表所示。

transform属性的值

说 明
translate(<长度值或百分数值>) translateX(<长度值或百分数值>) translateY (<长度值或百分数值>) 在水平方向、垂直方向或者两个方向上平移元素
scale(<数值>) scaleX(<数值>) scaleY(<数值>) 在水平方向、垂直方向或者两个方向上缩放元素
rotate(< 角度>) 旋转元素
skew(<角度>) skewX(<角度>) skewY(<角度>) 在水平方向、垂直方向或者两个方向上使元素倾斜一定的角度
matrix(4 ~ 6个数值,逗号隔开) 指定自定义变换。大多数浏览器还没有实现Z轴缩放,因此最后两个数字可以忽略(有些情况必须要省略)

代码清单15是一个变换的例子。代码清单中使用了-moz前缀,因为Firefox浏览器算是实现最完整的。

代码清单15 为元素应用变换

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
        <style>
            @font-face {
                font-style: normal;
                font-weight: normal;
                font-family: '水果冰淇淋';
                src: url('http://192.168.1.102/HTML5权威指南/第22章 设置文本样式/水果冰淇淋.woff');
            }
            p {
                padding: 5px;
                border: medium double black;
                background-color: lightgray;
                font-family: '水果冰淇淋';
                font-size: xx-large;
            }
            #黄子涵是帅哥 {
                display: block;
                font-size: x-large;
                border: medium solid white;
                background-color: blue;
                color: white;
                padding: 3px;
                width: 24px;
                height: 160px;
                position: relative;
                left: 200px;
                -moz-transform: rotate(-80deg) scaleX(1.2);
            }
            #黄子涵是靓仔 {
                display: block;
                font-size: x-large;
                border: medium solid white;
                background-color: blue;
                color: white;
                padding: 3px;
                width: 24px;
                height: 160px;
                position: relative;
                right: -1000px;
                -moz-transform: rotate(80deg) scaleX(1.2);
            }
        </style>
    </head>
    <body>
        <p>
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            沉默以拥吻抵抗一切的冰与冷,晚意借北风轻轻的飘起长长裙
            多温馨心里风中那笑声淌泪,<span id="黄子涵是帅哥">黄子涵是帅哥</span>尝尽了失意的我将一切都褪去
            再到这风中心中竟仿似伤痕累累,然后再记忆起当晚跟你在这里
            相依相拥中交出的心早已失去失去已破碎不可以再追洒泪
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            多久了,我都没变,<span id="黄子涵是靓仔">黄子涵是靓仔</span>爱你这回事,整整六年
            有一个人能去爱,多珍贵。没关系你也不用给我机会
            反正我还有一生可以浪费
        </p>
    </body>
</html>

在这个例子中,我为#banana选择器添加了一个transform属性声明,指定了两个变换。第一个是旋转-45。(即逆时针旋转45°);第二个是沿x轴进行因子为1.2的缩放。这些变换的效果如下图所示。

image

从图中可以看到,元素按照指定方式进行了旋转和放大。注意页面的布局并没有因此改变。元素变换后覆盖了周围的一些内容。

指定元素变换的起点

transform-origin属性允许我们指定应用变换的起点。默认情况下,使用元素的中心作为起点,不过,你可以使用下表中的值选择其他起点。

transform-origin属性的值

说 明
<%> 指定元素x轴或者y轴的起点
<长度> 指定距离
left center Right 指定x轴上的位置
top center bottom 指定y轴上的位置

要定起点,需要x轴和y轴各定义一个值。如果只提供一个值,另一个值会被认为是中心位置。代码清单16展示了transform-origin属性的用法。

代码清单16 使用transform-origin属性

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥"/>
        <meta name=renderer content=ie-comp>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
        <style>
            @font-face {
                font-style: normal;
                font-weight: normal;
                font-family: '水果冰淇淋';
                src: url('http://192.168.1.102/HTML5权威指南/第22章 设置文本样式/水果冰淇淋.woff');
            }
            p {
                padding: 5px;
                border: medium double black;
                background-color: lightgray;
                font-family: '水果冰淇淋';
                font-size: xx-large;
            }
            #黄子涵是帅哥, #黄子涵是靓仔 {
                font-size: x-large;
                border: medium solid white;
                background-color: blue;
                color: white;
                padding: 4px;
                -moz-transform: rotate(-45deg) scaleX(1.2);
                -ms-transform: rotate(-45deg) scaleX(1.2);
                -moz-transform-origin: right top;
                -ms-transform-origin: right top;
            }
        </style>
    </head>
    <body>
        <p>
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            沉默以拥吻抵抗一切的冰与冷,晚意借北风轻轻的飘起长长裙
            多温馨心里风中那笑声淌泪,<span id="黄子涵是帅哥">黄子涵是帅哥</span>尝尽了失意的我将一切都褪去
            再到这风中心中竟仿似伤痕累累,然后再记忆起当晚跟你在这里
            相依相拥中交出的心早已失去失去已破碎不可以再追洒泪
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            多久了,我都没变,<span id="黄子涵是靓仔">黄子涵是靓仔</span>爱你这回事,整整六年
            有一个人能去爱,多珍贵。没关系你也不用给我机会
            反正我还有一生可以浪费
        </p>
    </body>
</html>

在这个例子中,我将变换的起点移到了元素的右上角,从下图中可以看到效果。

image

将变换作为动画和过渡处理

我们可以为变换应用动画和过渡,就跟其他CSS属性一样。代码清单17展示了一个例子。

代码清单17 为变换应用过渡

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
        <style>
            @font-face {
                font-style: normal;
                font-weight: normal;
                font-family: '水果冰淇淋';
                src: url('http://192.168.1.102/HTML5权威指南/第22章 设置文本样式/水果冰淇淋.woff');
            }
            p {
                padding: 5px;
                border: medium double black;
                background-color: lightgray;
                font-family: '水果冰淇淋';
                font-size: xx-large;
            }
            #黄子涵是帅哥 {
                display: block;
                width: 24px;
                height: 160px;
                font-size: x-large;
                border: medium solid white;
                background-color: blue;
                color: white;
                padding: 4px;
                position: relative;
                left: 200px;
            }
            #黄子涵是靓仔 {
                display: block;
                width: 24px;
                height: 160px;
                font-size: x-large;
                border: medium solid white;
                background-color: blue;
                color: white;
                padding: 4px;
                position: relative;
                right: -1000px;
            }
            #黄子涵是帅哥:hover {
                -moz-transition-duration: 1.5s;
                -webkit-transition-duration: 1.5s;
                -o-transition-duration: 1.5s;
                transition-duration: 1.5s;
                -ms-transition-duration: 1.5s;
                
                -moz-transform: rotate(360deg);
                -webkit-transform: rotate(360deg);
                -o-transform: rotate(360deg);
                transform: rotate(360deg);
                -ms-transform: rotate(360deg);
            }
            #黄子涵是靓仔:hover {
                -moz-transition-duration: 1.5s;
                -webkit-transition-duration: 1.5s;
                -o-transition-duration: 1.5s;
                transition-duration: 1.5s;
                -ms-transition-duration: 1.5s;
                
                -moz-transform: rotate(-360deg);
                -webkit-transform: rotate(-360deg);
                -o-transform: rotate(-360deg);
                transform: rotate(-360deg);
                -ms-transform: rotate(-360deg);
            }
        </style>
    </head>
    <body>
        <p>
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            沉默以拥吻抵抗一切的冰与冷,晚意借北风轻轻的飘起长长裙
            多温馨心里风中那笑声淌泪,<span id="黄子涵是帅哥">黄子涵是帅哥</span>尝尽了失意的我将一切都褪去
            再到这风中心中竟仿似伤痕累累,然后再记忆起当晚跟你在这里
            相依相拥中交出的心早已失去失去已破碎不可以再追洒泪
            煤气灯不禁影照街里一对蚯蚓,照过以俩心相亲一对小情人
            多久了,我都没变,<span id="黄子涵是靓仔">黄子涵是靓仔</span>爱你这回事,整整六年
            有一个人能去爱,多珍贵。没关系你也不用给我机会
            反正我还有一生可以浪费
        </p>
    </body>
</html>

在这个例子中,我定义了一个过渡,它会经过1.5秒钟完成一次360。旋转变换。当用户将鼠标悬停在span元素上,就会应用过渡,效果如下图所示。

image

posted @ 2021-09-26 22:05  黄子涵  阅读(71)  评论(0编辑  收藏  举报