CSS transition 過渡

transition 讓 CSS 屬性的變化可以有平滑的過渡效果,而不是瞬間改變。

基本語法

transition: 屬性 時間 時間函數 延遲;
.box {
  background-color: blue;
  transition: background-color 0.3s ease;
}

.box:hover {
  background-color: red;
}

transition 子屬性

transition-property

指定要套用過渡效果的屬性。

.box {
  transition-property: background-color;     /* 單一屬性 */
  transition-property: background-color, transform;  /* 多個屬性 */
  transition-property: all;                  /* 所有屬性 */
  transition-property: none;                 /* 無 */
}

transition-duration

過渡動畫的持續時間。

.box {
  transition-duration: 0.3s;    /* 0.3 秒 */
  transition-duration: 300ms;   /* 300 毫秒 */
  transition-duration: 1s;      /* 1 秒 */
}

transition-timing-function

過渡動畫的速度曲線。

.box {
  transition-timing-function: ease;         /* 預設,慢-快-慢 */
  transition-timing-function: linear;       /* 等速 */
  transition-timing-function: ease-in;      /* 慢-快 */
  transition-timing-function: ease-out;     /* 快-慢 */
  transition-timing-function: ease-in-out;  /* 慢-快-慢 */
}

cubic-bezier

自訂速度曲線:

.box {
  transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55);
}

可以使用工具如 cubic-bezier.com 來設計曲線。

steps

分段式過渡(非連續):

.box {
  transition-timing-function: steps(4);          /* 分 4 段 */
  transition-timing-function: steps(4, start);
  transition-timing-function: steps(4, end);
}

transition-delay

過渡開始前的延遲時間。

.box {
  transition-delay: 0s;       /* 無延遲(預設) */
  transition-delay: 0.5s;     /* 延遲 0.5 秒 */
  transition-delay: 200ms;
}

transition 縮寫

/* transition: property duration timing-function delay; */

.box {
  transition: all 0.3s ease 0s;
}

/* 簡化 */
.box {
  transition: all 0.3s;
}

/* 只過渡特定屬性 */
.box {
  transition: background-color 0.3s, transform 0.5s ease-out;
}

可以過渡的屬性

不是所有 CSS 屬性都可以過渡。常見可過渡的屬性:

  • 顏色:color, background-color, border-color
  • 大小:width, height, padding, margin
  • 位置:top, right, bottom, left
  • 變形:transform
  • 透明度:opacity
  • 邊框:border-width, border-radius
  • 陰影:box-shadow, text-shadow
  • 字體:font-size, letter-spacing

無法過渡的屬性:

  • display
  • font-family
  • visibility(有限支援)

實用範例

按鈕 Hover

.button {
  background-color: #007bff;
  color: white;
  padding: 12px 24px;
  transition: background-color 0.2s, transform 0.2s;
}

.button:hover {
  background-color: #0056b3;
  transform: translateY(-2px);
}

.button:active {
  transform: translateY(0);
}

漸變背景

.card {
  background-color: white;
  transition: background-color 0.3s, box-shadow 0.3s;
}

.card:hover {
  background-color: #f5f5f5;
  box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}

展開選單

.dropdown {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease-out;
}

.dropdown.active {
  max-height: 500px;
}

淡入效果

.fade {
  opacity: 0;
  transition: opacity 0.5s;
}

.fade.visible {
  opacity: 1;
}

圖片覆蓋層

.image-container {
  position: relative;
}

.overlay {
  position: absolute;
  inset: 0;
  background: rgba(0,0,0,0);
  transition: background 0.3s;
}

.image-container:hover .overlay {
  background: rgba(0,0,0,0.5);
}

輸入框聚焦

input {
  border: 2px solid #ddd;
  transition: border-color 0.2s, box-shadow 0.2s;
}

input:focus {
  border-color: #007bff;
  box-shadow: 0 0 0 3px rgba(0,123,255,0.25);
  outline: none;
}

連結底線

.link {
  position: relative;
  text-decoration: none;
}

.link::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 0;
  height: 2px;
  background: currentColor;
  transition: width 0.3s;
}

.link:hover::after {
  width: 100%;
}

多屬性不同設定

.box {
  transition: 
    background-color 0.3s ease,
    transform 0.5s ease-out 0.1s,
    opacity 0.2s;
}

效能建議

為了更好的效能,建議只過渡以下屬性:

  • transform
  • opacity

這兩個屬性可以被 GPU 加速,不會觸發重排。

/* 推薦 */
.box {
  transition: transform 0.3s, opacity 0.3s;
}

/* 避免 */
.box {
  transition: width 0.3s, height 0.3s, margin 0.3s;
}

偵測過渡結束

可以用 JavaScript 偵測過渡結束:

element.addEventListener('transitionend', function(e) {
  console.log('過渡結束');
});