3000 字總結(jié)CSS 中的過渡、動(dòng)畫和變換詳解
一、CSS 過渡(Transitions)
1. 基本概念
CSS 過渡是一種平滑改變 CSS 屬性值的機(jī)制,允許屬性值在一定時(shí)間內(nèi)從一個(gè)值逐漸變化到另一個(gè)值,從而創(chuàng)建流暢的動(dòng)畫效果。過渡只能用于具有中間值的屬性(如顏色、大小、位置等),不能用于 display 等離散屬性。
2. 核心屬性
transition-property
指定哪些 CSS 屬性參與過渡。可以是單個(gè)屬性(如width
)、多個(gè)屬性(如width, height
)或all
(所有可過渡屬性)。
.element {
transition-property: width, height;
}
transition-duration
指定過渡持續(xù)的時(shí)間,單位可以是秒(s)或毫秒(ms)。
.element {
transition-duration: 0.5s; /* 0.5秒 */
}
transition-timing-function
定義過渡的速度曲線,常見值包括:
ease
:默認(rèn)值,慢-快-慢linear
:勻速ease-in
:慢速開始ease-out
:慢速結(jié)束ease-in-out
:慢速開始和結(jié)束cubic-bezier(n,n,n,n)
:自定義貝塞爾曲線
.element {
transition-timing-function: ease-in-out;
}
transition-delay
指定過渡開始前的延遲時(shí)間。
.element {
transition-delay: 0.2s; /* 延遲0.2秒 */
}
3. 簡寫語法
.element {
transition: width 0.5s ease-in-out 0.2s;
/* 依次為:屬性 持續(xù)時(shí)間 時(shí)間函數(shù) 延遲時(shí)間 */
}
4. 觸發(fā)方式
過渡需要一個(gè)觸發(fā)條件才能生效,常見的觸發(fā)方式有:
:hover 偽類
.button {
background-color: blue;
transition: background-color 0.3s;
}
.button:hover {
background-color: red;
}
:focus 偽類
.input {
border: 1px solid #ccc;
transition: border-color 0.3s;
}
.input:focus {
border-color: blue;
}
JavaScript 動(dòng)態(tài)修改
<button id="changeColor">變色</button>
<div id="box" style="width: 100px; height: 100px; background-color: red; transition: background-color 0.5s;"></div>
<script>
document.getElementById('changeColor').addEventListener('click', () => {
const box = document.getElementById('box');
box.style.backgroundColor = box.style.backgroundColor === 'red' ? 'blue' : 'red';
});
</script>
5. 應(yīng)用場景
- 按鈕懸停效果
- 導(dǎo)航欄交互
- 表單元素狀態(tài)變化
- 圖片縮放預(yù)覽
二、CSS 動(dòng)畫(Animations)
1. 基本概念
CSS 動(dòng)畫通過 @keyframes 規(guī)則定義一系列關(guān)鍵幀,然后將這些關(guān)鍵幀應(yīng)用到元素上,實(shí)現(xiàn)更復(fù)雜、更可控的動(dòng)畫效果。與過渡不同,動(dòng)畫不需要觸發(fā)條件,可以自動(dòng)運(yùn)行。
2. @keyframes 規(guī)則
定義動(dòng)畫的關(guān)鍵幀,格式如下:
@keyframes animationName {
0% { /* 初始狀態(tài) */ }
50% { /* 中間狀態(tài) */ }
100% { /* 結(jié)束狀態(tài) */ }
}
也可以使用 from 和 to 表示 0% 和 100%:
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
3. 動(dòng)畫屬性
animation-name
指定要應(yīng)用的動(dòng)畫名稱,對應(yīng) @keyframes 定義的名稱。
.element {
animation-name: fadeIn;
}
animation-duration
指定動(dòng)畫的持續(xù)時(shí)間,單位為秒(s)或毫秒(ms)。
.element {
animation-duration: 2s;
}
animation-timing-function
定義動(dòng)畫的速度曲線,與過渡的 timing-function 類似。
.element {
animation-timing-function: ease-in-out;
}
animation-delay
指定動(dòng)畫開始前的延遲時(shí)間。
.element {
animation-delay: 0.5s;
}
animation-iteration-count
指定動(dòng)畫的播放次數(shù),可以是數(shù)字或 infinite(無限循環(huán))。
.element {
animation-iteration-count: 3; /* 播放3次 */
}
animation-direction
指定動(dòng)畫的播放方向,常見值包括:
normal
:默認(rèn)值,正向播放reverse
:反向播放alternate
:正向和反向交替播放alternate-reverse
:反向和正向交替播放
.element {
animation-direction: alternate;
}
animation-fill-mode
定義動(dòng)畫在播放前和播放后的狀態(tài),常見值包括:
none
:默認(rèn)值,不應(yīng)用任何樣式forwards
:保持動(dòng)畫結(jié)束時(shí)的狀態(tài)backwards
:在延遲期間應(yīng)用動(dòng)畫的初始狀態(tài)both
:同時(shí)應(yīng)用 forwards 和 backwards
.element {
animation-fill-mode: forwards;
}
animation-play-state
控制動(dòng)畫的播放狀態(tài),可以是 running
或 paused
。
.element {
animation-play-state: paused;
}
4. 簡寫語法
.element {
animation: fadeIn 2s ease-in-out 0.5s 3 alternate forwards;
/* 依次為:名稱 持續(xù)時(shí)間 時(shí)間函數(shù) 延遲時(shí)間 播放次數(shù) 播放方向 填充模式 */
}
5. 應(yīng)用場景
- 加載動(dòng)畫
- 通知提示效果
- 頁面滾動(dòng)動(dòng)畫
- 互動(dòng)游戲元素
三、CSS 變換(Transforms)
1. 基本概念
CSS 變換允許改變元素的形狀、大小和位置,而不影響文檔流。變換可以是 2D 或 3D 的,通過 transform 屬性實(shí)現(xiàn)。
2. 2D 變換
translate()
移動(dòng)元素的位置,參數(shù)為 X 和 Y 方向的偏移量。
.element {
transform: translate(50px, 20px); /* 向右移動(dòng)50px,向下移動(dòng)20px */
}
rotate()
旋轉(zhuǎn)元素,參數(shù)為旋轉(zhuǎn)角度(單位為 deg)。
.element {
transform: rotate(45deg); /* 順時(shí)針旋轉(zhuǎn)45度 */
}
scale()
縮放元素,參數(shù)為 X 和 Y 方向的縮放比例。
.element {
transform: scale(1.5, 0.8); /* 水平放大1.5倍,垂直縮小0.8倍 */
}
skew()
傾斜元素,參數(shù)為 X 和 Y 方向的傾斜角度。
.element {
transform: skew(20deg, 10deg); /* 水平傾斜20度,垂直傾斜10度 */
}
matrix()
使用矩陣方式定義變換,包含六個(gè)參數(shù):matrix(a, b, c, d, e, f)。
.element {
transform: matrix(1.1, 0, 0, 1.1, 50, 0); /* 相當(dāng)于 scale(1.1) translate(50px, 0) */
}
3. 3D 變換
translate3d()
在 3D 空間中移動(dòng)元素,參數(shù)為 X、Y、Z 方向的偏移量。
.element {
transform: translate3d(50px, 20px, 100px);
}
rotate3d()
在 3D 空間中旋轉(zhuǎn)元素,參數(shù)為 (x, y, z, angle),其中 x、y、z 定義旋轉(zhuǎn)軸。
.element {
transform: rotate3d(1, 1, 0, 45deg); /* 繞X軸和Y軸的對角線旋轉(zhuǎn)45度 */
}
scale3d()
在 3D 空間中縮放元素,參數(shù)為 X、Y、Z 方向的縮放比例。
.element {
transform: scale3d(1.5, 0.8, 2);
}
perspective()
設(shè)置透視效果,定義觀察者與 z=0 平面的距離。
.container {
perspective: 1000px;
}
.element {
transform: perspective(1000px) rotateY(45deg);
}
transform-style
指定子元素是否保留 3D 變換效果,值為 flat
(默認(rèn))或 preserve-3d
。
.container {
transform-style: preserve-3d;
}
backface-visibility
控制元素背面是否可見,值為 visible
(默認(rèn))或 hidden
。
.card {
backface-visibility: hidden;
}
4. 變換原點(diǎn)
transform-origin 屬性允許改變變換的原點(diǎn)位置,默認(rèn)值為元素中心 (50% 50%)。
.element {
transform-origin: top left; /* 變換原點(diǎn)為左上角 */
transform: rotate(45deg);
}
四、綜合應(yīng)用
1. 過渡與變換結(jié)合
.button {
background-color: blue;
color: white;
padding: 10px20px;
border: none;
transition: background-color 0.3s, transform 0.3s;
}
.button:hover {
background-color: red;
transform: scale(1.1);
}
2. 動(dòng)畫與變換結(jié)合
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-20px); }
}
.ball {
width: 50px;
height: 50px;
background-color: red;
border-radius: 50%;
animation: bounce 1s infinite;
}
3. 3D 卡片翻轉(zhuǎn)效果
.card {
width: 200px;
height: 200px;
perspective: 1000px;
position: relative;
}
.card-inner {
width: 100%;
height: 100%;
transition: transform 0.8s;
transform-style: preserve-3d;
}
.card:hover.card-inner {
transform: rotateY(180deg);
}
.card-front, .card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.card-front {
background-color: #bbb;
color: black;
}
.card-back {
background-color: dodgerblue;
color: white;
transform: rotateY(180deg);
}
五、性能優(yōu)化
1. 使用 transform 和 opacity
transform 和 opacity 是性能最高的 CSS 屬性,因?yàn)樗鼈儾粫?huì)觸發(fā)重排(reflow)和重繪(repaint),只會(huì)觸發(fā)合成(composite)。
2. 避免過多重排和重繪
頻繁修改會(huì)觸發(fā)重排和重繪的屬性(如 width、height、margin 等)會(huì)導(dǎo)致性能問題。盡量批量修改樣式,或者使用 transform 替代位置和大小的改變。
3. 使用 will-change
提前告知瀏覽器某個(gè)元素即將發(fā)生變化,有助于瀏覽器提前優(yōu)化。
.element {
will-change: transform;
}
4. 硬件加速
通過 transform: translateZ(0) 或 transform: translate3d(0,0,0) 觸發(fā)硬件加速。
.element {
transform: translateZ(0);
}
六、瀏覽器兼容性
1. 前綴問題
早期的瀏覽器需要添加前綴支持,現(xiàn)在大多數(shù)現(xiàn)代瀏覽器已經(jīng)不需要了,但為了兼容性,仍然可以添加:
.element {
-webkit-transition: all 0.3s;
-moz-transition: all 0.3s;
-ms-transition: all 0.3s;
-o-transition: all 0.3s;
transition: all 0.3s;
}
2. 瀏覽器支持情況
- 過渡和 2D 變換:IE10+、Chrome、Firefox、Safari、Edge 等現(xiàn)代瀏覽器均支持
- 3D 變換:IE10+、Chrome、Firefox、Safari、Edge 等現(xiàn)代瀏覽器均支持
- 動(dòng)畫:IE10+、Chrome、Firefox、Safari、Edge 等現(xiàn)代瀏覽器均支持
七、常見應(yīng)用場景
1. 懸停效果
- 按鈕縮放
- 圖片放大
- 導(dǎo)航項(xiàng)高亮
2. 加載動(dòng)畫
- 旋轉(zhuǎn)加載圖標(biāo)
- 脈沖效果
- 骨架屏
3. 交互反饋
- 表單驗(yàn)證動(dòng)畫
- 點(diǎn)擊波紋效果
- 拖放反饋
4. 頁面過渡
- 路由切換動(dòng)畫
- 模態(tài)框淡入淡出
- 滾動(dòng)視差效果
八、注意事項(xiàng)
1. 性能陷阱
過度使用復(fù)雜的動(dòng)畫和變換會(huì)導(dǎo)致性能下降,特別是在移動(dòng)設(shè)備上。
2. 無障礙性
確保動(dòng)畫和變換不會(huì)影響視力障礙用戶的體驗(yàn),避免閃爍效果(可能引發(fā)癲癇)。
3. 兼容性處理
對于不支持某些特性的瀏覽器,提供降級方案。
4. 代碼維護(hù)
避免過多的動(dòng)畫和變換導(dǎo)致代碼難以維護(hù),保持簡潔和一致性。
通過合理使用 CSS 過渡、動(dòng)畫和變換,可以創(chuàng)建出視覺上引人入勝、交互上流暢自然的現(xiàn)代 Web 應(yīng)用。這些技術(shù)不僅提升了用戶體驗(yàn),也為設(shè)計(jì)師和開發(fā)者提供了豐富的創(chuàng)意空間。