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