對 CSS 使用個別轉換屬性進行精細的控管機制

使用 translaterotatescale 屬性轉換元素

CSS transform 屬性

如要為元素套用轉換,請使用 CSS transform 屬性。該屬性接受一或多個依序套用的 <transform-function>

.target {
  transform: translateX(50%) rotate(30deg) scale(1.2);
}

將目標元素在 X 軸上轉譯 50% 並旋轉 30 度,最後放大為 120%。

雖然 transform 屬性能正常運作,但當您需要個別變更任何值時,就會變得很繁瑣。

如要變更懸停時的縮放比例,就必須複製轉換屬性中的所有函式,即使函式的值維持不變也一樣。

.target:hover {
  transform: translateX(50%) rotate(30deg) scale(2); /* Only the value of scale() changed */
}

個別轉換屬性

Chrome 104 的運費是 CSS 變形的個別屬性。屬性為 scalerotatetranslate,可用來個別定義轉換的各部分。

如此一來,Chrome 就會加入已支援這些資源的 Firefox 和 Safari。

瀏覽器支援

  • 104
  • 104
  • 72
  • 14.1

資料來源

使用個別屬性重新編寫上述 transform 範例,程式碼片段會變成:

.target {
  translate: 50% 0;
  rotate: 30deg;
  scale: 1.2;
}

順序重要

原始 CSS transform 屬性和新屬性的主要差異,在於已宣告的轉換套用順序。

使用 transform 時,轉換函式會按照寫入順序 (從左到右) 依序套用。

使用個別轉換屬性時,順序與宣告順序不同。順序一律相同:第一個 translate (外部)、rotatescale (位於內部)。

因此,以下兩種程式碼片段都會顯示相同的結果:

.transform--individual {
  translate: 50% 0;
  rotate: 30deg;
  scale: 1.2;
}

.transform--individual-alt {
  rotate: 30deg;
  translate: 50% 0;
  scale: 1.2;
}

在這兩種情況下,目標元素會先由 X 軸上的 50% 轉譯,再由 30deg 旋轉,最後再由 1.2 縮放。

如果其中一個轉換屬性與 transform 屬性同時宣告,則系統會先套用個別轉換 (translaterotate,然後 scale),最後 (位於內) 套用 transform。詳情請參閱定義如何計算轉換矩陣的相關規格。

動畫

新增這些屬性的主要原因,是讓動畫更容易播放。假設您想為元素套用以下動畫效果:

主要畫面格圖表。

使用了 transform

如要使用 transform 實作這個動畫,您必須計算所有已定義轉換的值之間的所有值,並將這些值納入每個主要畫面格。舉例來說,如要以 10% 的標記旋轉,就必須一併計算其他轉換的值,因為 transform 屬性需要所有這些值。

已計算中繼值的主要畫面格圖。

產生的 CSS 程式碼會變成:

@keyframes anim {
  0% { transform: translateX(0%); }
  5% { transform: translateX(5%) rotate(90deg) scale(1.2); }
  10% { transform: translateX(10%) rotate(180deg) scale(1.2); }
  90% { transform: translateX(90%) rotate(180deg) scale(1.2); }
  95% { transform: translateX(95%) rotate(270deg) scale(1.2); }
  100% { transform: translateX(100%) rotate(360deg); }
}

.target {
  animation: anim 2s;
  animation-fill-mode: forwards;
}

使用個別轉換屬性

使用個別轉換屬性時,寫入會變得簡單。您可以個別指定每個轉換指令,而不是將所有轉換從主要畫面格拖曳到主要畫面格。您不再需要計算值之間的所有引數。

@keyframes anim {
  0% { translate: 0% 0; }
  100% { translate: 100% 0; }

  0%, 100% { scale: 1; }
  5%, 95% { scale: 1.2; }

  0% { rotate: 0deg; }
  10%, 90% { rotate: 180deg; }
  100% { rotate: 360deg; }
}

.target {
  animation: anim 2s;
  animation-fill-mode: forwards;
}

使用個別轉換屬性和多個主要畫面格

如要將程式碼設為模組化,您可以將每個子動畫分割成專屬的一組主要畫面格。

@keyframes move {
  0% { translate: 0% 0; }
  100% { translate: 100% 0; }
}

@keyframes scale {
  0%, 100% { scale: 1; }
  5%, 95% { scale: 1.2; }
}

@keyframes rotate {
  0% { rotate: 0deg; }
  10%, 90% { rotate: 180deg; }
  100% { rotate: 360deg; }
}

.target {
  animation: move 2s, scale 2s, rotate 2s;
  animation-fill-mode: forwards;
}

多虧了這種分割,您就可以視需要分別套用每組主要畫面格,因為 transform 屬性現已成為個別屬性,不會再相互覆寫。更棒的是,您可以為每種轉換指定不同的時間,不必重新編寫整個函式。

效能

使用這些新屬性的動畫,和現有 transform 屬性的動畫一樣有效率。

translaterotatescale 的動畫在合成器上執行的方式與 transform 動畫相同,因此可提供動畫效能,transform 相同

這些新屬性也適用於 will-change 屬性。一般來說,最好避免將 will-change 用於所需的最少元素數量,並盡可能縮短時間。但建議你盡可能具體明確。舉例來說,如果您使用 will-change 利用 rotatefilter 屬性將動畫最佳化,則應使用 will-change: rotate, filter 進行宣告。比起使用 will-change: transform, filter 製作 rotatefilter 動畫的情況,這會比使用 will-change: transform, filter 來得好,因為 Chrome 預先建立的部分資料結構不同於 transformrotatewill-change

新可互通系列的一部分