转场 ( transition )
CSS 的转场 transition 可以让元素在样式属性值改变的时候,产生“过程的变化”,进而展现更平滑顺畅的渐变效果,这篇教学会介绍 CSS 转场的相关属性 transition-property、transition-duration、transition-delay、transition-behavior 和 transition-timing-function,也会介绍透过 CSS 函数 cubic-bezier 创造特别的转场速度变化。
快速导览:
transition-duration 转场持续时间
transition-duration 表示“转场持续时间”的样式属性,默认值 0 表示不转场,没有继承特性,使用非负值的数值,数值需要搭配“s”( 秒 ) 或“ms”( 1/1000 秒、毫秒 ) 等时间单位,只要转场时间不为 0,浏览器就会在样式属性的“开始”的属性值与“结束”属性值之间,自动计算补间动画数值。
注意,能够加入补间动画数值的样式属性,需要具备能“计算”的属性值,例如颜色、位置、尺寸、角度、透明度...等,如果是使用“关键字”作为属性值,则无法加入补间动画效果,例如
none、solid、dashed...等。
下方范例使用四个 h2 元素,前三个 h2 当鼠标移动到文字上方时分别会产生 0.75 秒和 0.3 秒的转场效果,而第四个 h2 因为是在 solid 和 dashed 之间切换,就不会有转场效果。
<!-- HTML 程式碼-->
將滑鼠移動到下方文字上
<h2 class="a">我會變大</h2>
<h2 class="b">我會變色</h2>
<h2 class="c">我會變透明</h2>
<h2 class="d">我無法產生補間動畫</h2>
<!-- CSS 程式碼 -->
<style>
h2 {
border: 3px solid #000;
width: 240px;
height: 50px;
}
.a {transition-duration: .75s;} /* 轉場持續時間 0.75 秒 */
.a:hover {font-size: 30px;}
.b {transition-duration: 750ms;} /* 轉場持續時間 0.75 秒 */
.b:hover {
color: red;
border-color: red;
}
.c {transition-duration: 0.3s;} /* 轉場持續時間 0.3 秒 */
.c:hover {opacity: 0;}
.d {transition-duration: 0.3s;} /* 轉場持續時間 0.75 秒 */
.d:hover {
border-style: dashed; /* 這種關鍵字屬性值無法產生補間動畫的轉場效果 */
}
</style>
转场持续时间作用在“目前的选择器”,因此同一个元素可以透过不同的选择器,套用不同的持续时间,下方范例的 h2 在鼠标移动到上方时,会使用 3 秒的转场持续时间,当鼠标离开后,会改用 0.5 秒的转场持续时间。
<!-- HTML 程式碼-->
將滑鼠移動到下方文字上
<h2>oxxo</h2>
<!-- CSS 程式碼 -->
<style>
h2 {transition-duration: 0.5s;}
h2:hover {
transition-duration: 3s;
font-size: 40px;
}
</style>
transition-property 转场属性
transition-property 表示“要套用转场的样式属性”,默认值“all”表示全部能套用转场的样式属性都会套用,没有继承特性,也可以直接将特定样式属性名称作为属性值,若有多个样式属性则使用“逗号”分隔。
注意,能够加入补间动画数值的样式属性,需要具备能“计算”的属性值,例如颜色、位置、尺寸、角度、透明度...等,如果是使用“关键字”作为属性值,则无法加入补间动画效果,例如
none、solid、dashed...等。
下方范例有两个 h2,第一个 h2 所有样式都会套用转场效果,而第二个 h2 只有颜色和透明度会套用转场效果 ( 所以会有“直接变大”的感觉 )。
<!-- HTML 程式碼-->
將滑鼠移動到下方文字上
<h2 class="a">所有樣式都會有轉場效果</h2>
<h2 class="b">只有顏色、透明度有轉場效果</h2>
<!-- CSS 程式碼 -->
<style>
h2 {
transition-duration: 1s;
border: 2px solid #000;
}
h2:hover {
color: red;
font-size:30px;
opacity: 0.2;
border-width: 5px;
}
.a {transition-property: all;}
.b {transition-property: color, opacity;} /* 只有 color 和 opacity 要套用轉場效果 */
</style>
如果使用 transition-property 设定“多组”样式属性,也能搭配 transition-duration 让多组样式属性都使用不同的转场持续时间,下方的范例会让 width、height、font-size、border-width 套用不同的转场时间。
<!-- HTML 程式碼-->
<h2>滑鼠移動到我上方看效果</h2>
<div>oxxo</div>
<!-- CSS 程式碼 -->
<style>
h2 {border: 2px solid #000;}
h2:hover+div {
width: 200px;
height: 200px;
font-size: 80px;
border-width: 10px;
}
div {
width: 100px;
height: 100px;
border: 2px solid #000;
transition-property: width, height, font-size, border-width;
transition-duration: 1s, 3s, 5s, 2s; /* 轉場時間分別對應上方樣式屬性 */
}
</style>
transition-delay 转场延迟时间
transition-delay 表示“延迟多久后进行转场”,默认值 0 表示不延迟,没有继承特性,使用非负值的数值,数值需要搭配“s”( 秒 ) 或“ms”( 1/1000 秒、毫秒 ) 等时间单位。下方范例有两个 h2,第一个 h2 不会延迟,而第二个 h2 会套用 1 秒的延迟效果。
<!-- HTML 程式碼-->
將滑鼠移動到下方文字上
<h2 class="a">我沒有延遲</h2>
<h2 class="b">我會延遲 1 秒</h2>
<!-- CSS 程式碼 -->
<style>
h2 {
transition-duration: 1s;
border: 2px solid #000;
}
h2:hover {
color: red;
font-size:30px;
opacity: 0.2;
border-width: 5px;
}
.a {transition-delay: 0;}
.b {transition-delay: 1s;} /* 延遲一秒 */
</style>
transition-behavior 转场行为
transition-behavior 是一个专门针对“离散样式属性”设定“转场行为”的样式属性,默认值为 normal,没有继承特性。所谓的“离散”样式属性就是“不连续”的样式属性,泛指为透过“关键字”为属性值的样式,例如 border-style 使用 solid、dashed、dotted 等,或 display 使用 none、block 等,都属于“离散”样式属性,如果将 transition-behavior 属性值设定为 allow-discrete,则可以让这些无法产生转场补间动画效果的样式属性,在转场过程中更加平顺。
不论有没有设定
transition-behavior,都不会影响非离散的样式属性。
下方范例使用两个 h2 分别呈现 normal 和 allow-discrete 的效果,可以看到虽然 border 的 solid 样式无法直接转变成 dashed,但设定为 allow-discrete 的转场效果明显好很多。
<!-- HTML 程式碼-->
將滑鼠移動到下方文字上
<h2 class="a">normal</h2>
<h2 class="b">allow-discrete</h2>
<!-- CSS 程式碼 -->
<style>
h2 {
width: 240px;
height: 100px;
transition-duration: 2s;
border: 20px solid #000;
box-sizing: border-box;
}
h2:hover {border: 1px dashed #000;}
.b {transition-behavior: allow-discrete;}
</style>
不过如果要透过 transition-behavior 设定 display:none 的变化,需要额外搭配 opacity 样式属性和额外运用 @starting-style 声明起始样式,@starting-style 是个只与 transition 有关的规则定义,会设定元素属性的初始值,也就是元素第一次出现页面上的样式。
- 从显示到消失:
transition-behavior: allow-discrete;- 从消失到显示:
@starting-style
下方范例当鼠标移动到第一个红色 h2 时,会将下方两个白色 h2 设定为 display:none,由于第一个 h2 设定了 transition-behavior: allow-discrete;,会先出现 1 秒的转场效果再将元素隐藏,最下方的文字也会在上方元素隐藏后,自动位移到上面。
<!-- HTML 程式碼-->
<h2 class="a">將滑鼠移到我上方</h2>
<h2 class="b">allow-discrete ( 轉場消失 )</h2>
<h2 class="c">normal ( 直接消失 )</h2>
oxxo.studio ( 上方元素 display:none 之後會自動上移 )
<!-- CSS 程式碼 -->
<style>
h2 {
width: 320px;
height: 60px;
transition-duration: 1s;
border: 3px solid #000;
background: #fff;
}
.a {background: pink;}
/* 滑鼠移動到 .a 上方,.a 後方所有的 h2 */
.a:hover~h2 {
opacity: 0;
display: none;
}
.b {transition-behavior: allow-discrete;}
@starting-style {
.b {opacity: 0;} /* 避免滑鼠離開後,透明度直接變成 1 */
}
</style>
transition-timing-function 转场速度
transition-timing-function 可以控制“转场的速度”,默认值为 ease,没有继承特性,这个样式属性可以让转场的过程具有“加速、减速、平缓加速、线性移动”等速度变化,根据“W3C CSS Easing Functions Level 1”的说明,共有下列几种属性值:
| 属性值 | 说明 |
|---|---|
| linear | 线性,没有加减速。 |
| ease-in | 加速开始,线性停止。 |
| ease-out | 线停开始,减速停止。 |
| ease-in-out | 加速开始,减速停止。 |
| ease | 加速开始,减速停止。 |
| step-start | 转场时间后直接跳到完成样式。 |
| step-end | 直接跳到完成样式,并等待转场时间。 |
| steps(n, jump-start) | 分成 n 个步骤跳往完成样式。 |
| steps(n, jump-end) | 分成 n 个步骤跳往完成样式。 |
| steps(n, jump-none) | 分成 n-1 个步骤跳往完成样式。 |
| steps(n, jump-both) | 分成 n+1 个步骤跳往完成样式。 |
下方范例会让不同的 div 从左移动到右,可以观察不同转场速度的效果。
<!-- HTML 程式碼-->
<h2>滑鼠移動到我上方看效果</h2>
<h3>linear</h3><div></div>
<h3>ease-in</h3><div></div>
<h3>ease-out</h3><div></div>
<h3>ease-in-out</h3><div></div>
<h3>ease</h3><div></div>
<h3>step-start</h3><div></div>
<h3>step-end</h3><div></div>
<h3>steps(5, jump-start)</h3><div></div>
<h3>steps(5, jump-end)</h3><div></div>
<h3>steps(5, jump-none)</h3><div></div>
<h3>steps(5, jump-both)</h3><div></div>
<!-- CSS 程式碼 -->
<style>
h2 {border: 2px solid #000;}
h2:hover~div {
margin-left: 200px;
transition-duration: 5s;
}
h3 {
margin:5px;
width: 190px;
height: 30px;
float:left;
clear: both;
text-align: right;
}
div {
float:left;
width: 30px;
height: 30px;
margin:5px;
background: red;
transition-duration: 1s;
}
div:nth-of-type(1) {transition-timing-function: linear;}
div:nth-of-type(2) {transition-timing-function: ease-in;}
div:nth-of-type(3) {transition-timing-function: ease-out;}
div:nth-of-type(4) {transition-timing-function: ease-in-out;}
div:nth-of-type(5) {transition-timing-function: ease;}
div:nth-of-type(6) {transition-timing-function: step-start;}
div:nth-of-type(7) {transition-timing-function: step-end;}
div:nth-of-type(8) {transition-timing-function: steps(5, jump-start);}
div:nth-of-type(9) {transition-timing-function: steps(5, jump-end);}
div:nth-of-type(10) {transition-timing-function: steps(5, jump-none);}
div:nth-of-type(11) {transition-timing-function: steps(5, jump-both);}
</style>
除了使用默认的转场速度,也可以使用 CSS 内建函数 cubic-bezier 设定“客制化的转场速度”,cubic-bezier 是一个可调整的“贝兹曲线”,总共有四个参数,分别是第一个贝兹曲线控制点 p1 的座标 (x1, y1) 和第二个贝兹曲线控制点 p2 的座标 (x2, y2) ( 参考 Cubic Bézier )。
透过线上工具“cubic-bezier.com”可以使用视觉化的方式,拖拉这两个控制点,调整控制点之后,上方就会看见这个转场速度的写法。
下方范例会透过 cubic-bezier,产生四种有趣的转场速度,从中可以看到当设定值超过范围时,甚至会产生超过原本边界的特殊效果。
<!-- HTML 程式碼-->
<h2>滑鼠移動到我上方看效果</h2>
<h3>cubic-bezier(.24,1.19,.68,-0.07)</h3><div></div>
<h3>cubic-bezier(.96,.34,0,.73)</h3><div></div>
<h3>cubic-bezier(.46,-0.75,.18,1.49)</h3><div></div>
<h3>cubic-bezier(.41,.86,.55,2.08)</h3><div></div>
<!-- CSS 程式碼 -->
<style>
h2 {border: 2px solid #000;}
h2:hover~div {
margin-left: 200px;
transition-duration: 5s;
}
h3 {
margin:5px;
width: 290px;
height: 30px;
float:left;
clear: both;
text-align: right;
}
div {
float:left;
width: 30px;
height: 30px;
margin:5px;
background: red;
transition-duration: 1s;
}
div:nth-of-type(1) {transition-timing-function: cubic-bezier(.24,1.19,.68,-0.07);}
div:nth-of-type(2) {transition-timing-function: cubic-bezier(.96,.34,0,.73);}
div:nth-of-type(3) {transition-timing-function: cubic-bezier(.46,-0.75,.18,1.49);}
div:nth-of-type(4) {transition-timing-function: cubic-bezier(.41,.86,.55,2.08);}
</style>
transition 转场属性缩写
元素套用转场效果时,为了避免 CSS 程序码过于冗长,通常不会使用个别的转场样式属性,往往会使用缩写的 transition 样式属性,使用 transition 时只需要将个别的转场样式写在后方,除了转场时间和延迟时间有顺序,其他关键字排列没有顺序之分,下方所列出的写法都是合乎规规则的写法:
div {
transition: 1s; /* 持續時間 1s */
transition: 1s 0.5s; /* 持續時間 1s,延遲時間 0.5s */
transition: 1s ease-in; /* 持續時間 1s,使用 ease-in 轉場速度 */
transition: 1s 0.5s ease-in; /* 持續時間 1s,延遲時間 0.,5s,使用 ease-in 轉場速度 */
transition: 1s color; /* 持續時間 1s,針對 color */
}
下方的范例使用 transition 让四个 div 用不同的方式进行转场。
<!-- HTML 程式碼-->
<h2>滑鼠移動到我上方看效果</h2>
<h3>transition: 5s</h3><div></div>
<h3>transition: 5s ease-in-out</h3><div></div>
<h3>transition: 3s 2s margin-left</h3><div></div>
<h3>transition: 3s 2s</h3><div></div>
<!-- CSS 程式碼 -->
<style>
h2 {border: 2px solid #000;}
h2:hover~div {
margin-left: 200px;
background: green;
}
h3 {
margin:5px;
width: 290px;
height: 30px;
float:left;
clear: both;
text-align: right;
}
div {
float:left;
width: 30px;
height: 30px;
margin:5px;
background: red;
transition: 1s;
}
h2:hover~div:nth-of-type(1) {transition: 5s;}
h2:hover~div:nth-of-type(2) {transition: 5s ease-in-out}
h2:hover~div:nth-of-type(3) {transition: 3s 2s margin-left;} /* 只針對 margin-left */
h2:hover~div:nth-of-type(4) {transition: 3s 2s;}
</style>
小结
transition 通常应用于按钮、选单、或任何需要“动态出现或移动”的元素,透过转场效果,可以让元素不会突兀的出现或改变位置,是很常见的样式属性。
微信扫码关注
抖音扫码关注