首頁  >  文章  >  web前端  >  使用顯示和大小屬性簡化 CSS 動畫

使用顯示和大小屬性簡化 CSS 動畫

DDD
DDD原創
2024-10-31 05:58:02512瀏覽

薩利赫·穆巴沙爾撰寫✏️

直到最近,只有有限數量的 CSS 屬性可以進行動畫處理。例如,要建立淡入或淡出效果,通常會使用 opacity 屬性而不是 display 屬性,因為後者無法設定動畫。然而,問題是,雖然該元素在視覺上變得隱藏,但它仍然存在於頁面上。

最近,Chrome 推出了新功能來解決此問題並使開發過程變得更加簡單。在本文中,我們將比較顯示和大小屬性動畫的傳統方法與這些新功能。

動畫顯示和元素大小的問題

有可能,您必須在某些時候使用 CSS 在某些元素上建立淡入/淡出效果。首選方法是將動畫或過渡應用到元素的不透明度。但將不透明度設為零實際上並不會刪除該元素 - 它只是使其不可見。大多數時候,這就夠了。

但是假設您有一個待辦事項列表,用戶可以在其中刪除項目。如果要建立退出動畫以使項目淡出,通常會使用不透明度。但如果清單需要調整其高度,您還需要將顯示設為無。這裡的問題是,雖然該項目在視覺上消失了,但它仍然佔用 DOM 中的空間,並擾亂佈局和用戶互動等內容。

這是兩種方法的並排比較:一種僅使用不透明度,另一種將不透明度與顯示相結合。您可以嘗試下面的範例來查看差異:


查看 CodePen 上 Saleh-Mubahar (@saleh-mubahar) 的 Pen Simple Todo 應用程式比較。

請注意,將顯示與不透明度結合使用時佈局如何變化,而單獨使用不透明度會在清單中留下間隙。雖然第二種方法(不透明顯示)解決了佈局問題,但它會幹擾平滑的淡出效果,因為在淡入淡出完成之前應用了 display: none。這會導致突然消失而不是逐漸褪色。

例如,不透明度屬性可以從 0 平滑過渡到 1。但是,顯示屬性無法進行動畫處理,因為它沒有數字範圍 - 它的狀態是二進制的,例如無、區塊或其他值。由於沒有中間值,CSS 無法為顯示設定動畫。

同樣,開發人員在嘗試對元素的固有大小(例如 height: auto)進行動畫處理時經常面臨挑戰。這通常用於可折疊部分(如手風琴)上的過渡,其中高度在關閉時從 0px 開始,並在打開時擴展以適應內容。雖然尺寸屬性(如高度)通常可以進行動畫處理(因為它們具有數位起始值和結束值),但自動設定動畫或從自動設定動畫會產生問題。瀏覽器無法計算0px和auto之間的步長;因此必須使用複雜的解決方法。

動畫顯示和尺寸的傳統解決方案

有多種方法可以解決動畫顯示和元素大小的挑戰。在本節中,我們將討論使用 CSS 和 JavaScript 的最受歡迎的解決方案。

基於 CSS 的解決方案

有幾種方法可以解決使用 CSS 無法設定動畫的顯示屬性的問題。最可靠的方法是使用不透明度以及尺寸屬性(例如高度或寬度)。在這種情況下,size 屬性用於有效地從 DOM 中刪除元素。這可以使用轉換延遲屬性來完成。基本上,我們為尺寸過渡添加延遲,該延遲等於為不透明度過渡設定的時間。一旦元素淡出,其大小立即設為零,有效地將其從佈局中刪除,就好像未應用 display: none 一樣。

再次使用待辦事項清單作為範例,實作看起來有點像這樣:

li {
  height: 50px; /* any measurable value, not "auto" */
  opacity: 1;
  transition: height 0ms 0ms, opacity 400ms 0ms;
}
.fade-out {
  overflow: hidden; /* Hide the element content, while height = 0 */
  height: 0;
  opacity: 0;
  padding: 0;
  transition: height 0ms 400ms, padding 0ms 400ms, opacity 400ms 0ms;
}

這裡的技巧是,一旦不透明度褪色到 0,延遲後將高度和填充設置為 0。不透明度的延遲和長度需要相同 - 在本例中為 400 毫秒。 height: 0 確保清單項目不與版面配置互動。如前所述,height: auto 根據內容動態調整;因此,它不能被動畫化。因此,您需要確保元素具有特定的固定高度,以使動畫正常運作。

將可見性設定為隱藏是另一種常用的方法。但是,這不會從 DOM 中刪除該元素,它仍然會像平常一樣影響佈局,即它會影響周圍元素的位置。

將元素動畫化為其固有尺寸(或高度:自動)的最常見 CSS 解決方案是使用 max-height 而不是 height。這不是最簡潔的實現,但它可以完成工作。基本上,您將 max-height 設定為大於元素所能獲得的值。這樣,它就可以模仿平滑過渡,類似於固定高度的動畫:

.collapsible {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.4s ease;
}

.collapsible.open {
  max-height: 500px;
} 

這種方法最明顯的缺點是您必須確保最大高度始終大於元素內的實際內容。另一個問題是,除非內容高度與最大高度值完全匹配,否則過渡時間可能會感覺不準確。

假設您的內容高 400 像素,但您將最大高度設為 1000 像素。從技術上講,動畫將在整個持續時間內持續(假設兩秒)。但從視覺上看,元素一旦達到內容的實際高度(400px)就會停止成長,而 max-height 不斷過渡到 1000px。因此,在這種情況下,過渡持續時間將比您指定的時間短。

JavaScript 方法

上面討論的所有 CSS 解決方案都非常複雜,並且可能會導致不可預測的結果。直到最近,實現這一目標的最可靠方法還是透過 JavaScript。

要在不透明度轉換後套用不顯示,我們可以使用 setInterval 或 setTimeout 函數來新增與不透明度轉換持續時間相符的延遲。在此延遲之後,您可以將顯示設為無。這是一個例子:

li {
  height: 50px; /* any measurable value, not "auto" */
  opacity: 1;
  transition: height 0ms 0ms, opacity 400ms 0ms;
}
.fade-out {
  overflow: hidden; /* Hide the element content, while height = 0 */
  height: 0;
  opacity: 0;
  padding: 0;
  transition: height 0ms 400ms, padding 0ms 400ms, opacity 400ms 0ms;
}

在此程式碼中,按一下按鈕後,元素會在一秒鐘內淡出,然後其顯示立即設為無 - 實質上是將其從佈局中刪除。

類似地,為了對內在尺寸進行動畫處理,我們可以在 JavaScript 中計算元素的高度,並使用該值作為高度的端點。這種方法更加可靠和精確。但是,請記住,我們仍在高度屬性上設定動畫。

這裡明顯的好處是,您可以根據元素的實際內容動態設定高度,確保過渡與真實高度匹配,而不是用 max-height 進行猜測。

具體操作方法如下:

.collapsible {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.4s ease;
}

.collapsible.open {
  max-height: 500px;
} 

在此範例中,我們擴展了一個以 0 高度開始的部分。我們使用scrollHeight 來獲得內容的完整高度,並將其用作過渡的端點。轉換完成後,我們將高度切換為自動,這允許瀏覽器根據容器的內容自動調整容器的高度。此步驟是可選的,但如果您希望容器內的內容隨著時間的推移而變化,它會很有用。

用於動畫顯示和固有尺寸屬性的新 CSS 功能

現在讓我們來看看最近發布或即將發佈到瀏覽器的 CSS 新功能。這些新工具消除了我們之前討論的場景中對 JavaScript 的需求,並幫助您編寫更清晰、更短的 CSS。

顯示和關鍵幀

@keyframes at 規則可讓您透過控制動畫序列中的中間步驟來建立動畫。最新更新可讓您在關鍵影格時間軸內對顯示和內容可見性屬性進行動畫處理。

我們並沒有完全在 display none 和 block 之間進行插值(因為這是不可能的)。相反,我們等待所有其他效果完成,然後切換顯示狀態。這與我們對 JavaScript 所做的類似 - 在應用 display: none 之前等待轉換完成 - 但現在使用 CSS 更容易。

Chrome 開發部落格有一個非常酷的演示,讓事情變得清晰:


觀看筆淡出卡片 - CodePen 上 web.dev (@web-dot-dev) 的動畫。

首先,在 250 毫秒內將不透明度設為 0。此序列完成後,顯示立即設定為無:

li {
  height: 50px; /* any measurable value, not "auto" */
  opacity: 1;
  transition: height 0ms 0ms, opacity 400ms 0ms;
}
.fade-out {
  overflow: hidden; /* Hide the element content, while height = 0 */
  height: 0;
  opacity: 0;
  padding: 0;
  transition: height 0ms 400ms, padding 0ms 400ms, opacity 400ms 0ms;
}

這裡最大的好處是涉及顯示屬性的更複雜的動畫,直到最近使用 CSS(或 JavaScript)實現起來都非常困難,現在可以相對輕鬆地創建。

轉換行為如何簡化顯示轉換

現在還可以使用新的 [transition-behavior](https://developer.mozilla.org/en-US/docs/Web/CSS/transition-behavior) 屬性透過過渡來創建淡出效果。這使您可以將過渡應用於具有離散動畫行為的屬性,例如顯示。透過使用allow-discrete,您可以為顯示屬性設定動畫。這是一個簡單的例子:

.collapsible {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.4s ease;
}

.collapsible.open {
  max-height: 500px;
} 

使用 @starting-style 的進入動畫

我們在本文中廣泛討論了淡出效果。但相反的情況又如何呢?進入動畫很棘手,通常只能透過 JavaScript 實現。新的 @starting-style at-rule 讓事情變得更容易。

顧名思義,我們可以使用它來將樣式應用於元素,瀏覽器可以在元素在頁面上可見之前找到該樣式。我們可以在這裡設定進入動畫的初始狀態。元素渲染後,它會轉換回預設狀態。

這是一個基本範例:

document.getElementById("fadeButton").addEventListener("click", function () {
  const element = document.getElementById("myElement");
  element.style.opacity = "0";
  setTimeout(() => {
    element.style.display = "none";
  }, 1000); // Match this value with the duration in CSS
});

一旦 DOM 加載,卡片就會淡入。您可以將@starting-style用於各種進入動畫。這是 Chrome 開發團隊的另一個很棒的範例:


_查看 CodePen 上 web.dev (@web-dot-dev) 的筆項目轉換。
_

使用 calc-size() 函數對內在尺寸進行動畫處理

最近在 Chrome 129 中引入了類似 calc() 的 calc-size 函數。簡單來說,它允許安全可靠地對內在大小執行數學運算。目前支援auto、min-content、max-content、fit-content 四個關鍵字的操作。

這對於將元素動畫化到其固有尺寸或改變其固有尺寸特別有用。 calc-size 允許將目前在 CSS 中指定的任何高度動畫化為零或到/從一個小的固定值。這是一個將可折疊部分從 height: 0 擴展到 auto:
的簡單範例

li {
  height: 50px; /* any measurable value, not "auto" */
  opacity: 1;
  transition: height 0ms 0ms, opacity 400ms 0ms;
}
.fade-out {
  overflow: hidden; /* Hide the element content, while height = 0 */
  height: 0;
  opacity: 0;
  padding: 0;
  transition: height 0ms 400ms, padding 0ms 400ms, opacity 400ms 0ms;
}

瀏覽器相容性

這些功能大部分主要是為了增強動畫而不是必需的 DOM 元件,但由於它們相對較新,因此仍然值得檢查瀏覽器相容性:

  • display 屬性在 Chrome 116 和 Opera 102 是 @keyframe animable 。 Firefox 支援仍在開發中,Safari 正在努力
  • [transition-behavior](https://caniuse.com/mdn-css_properties_transition-behavior) 屬性首先在 Chrome 117 中發布。它與除 Firefox 之外的所有主流瀏覽器相容,Firefox 目前正在開發中
  • [@starting-style](https://caniuse.com/mdn-css_at-rules_starting-style) at-rule 是在 Chrome 117 中引入的。除了 Firefox 之外,所有主要瀏覽器都完全支援它尚不支援顯示動畫:無
  • calc-size() 是 Chrome 129 中引入的最新功能,目前僅在 Chrome 和 Edge 中支援。不過,其他主流瀏覽器很快就會支援它

結論

在本文中,我們探討了開發人員在對 CSS 屬性(如顯示和元素大小)進行動畫處理時面臨的挑戰。傳統方法需要使用 CSS 和 JavaScript 進行複雜的解決方法,才能為無法直接設定動畫的屬性實作動畫。

新功能,例如使用關鍵影格進行動畫顯示、calc-size() 函數和轉場行為屬性,使這些動畫更容易實現。這些函數消除了對 JavaScript 的需求,從而允許更簡單的 CSS 動畫。


您的前端是否佔用了使用者的 CPU?

隨著 Web 前端變得越來越複雜,資源貪婪的功能對瀏覽器的要求越來越高。如果您有興趣監控和追蹤生產中所有使用者的客戶端 CPU 使用情況、記憶體使用情況等,請嘗試 LogRocket。

Simplifying CSS animations with the display and size properties

LogRocket 就像是網路和行動應用程式的 DVR,記錄網路應用程式、行動應用程式或網站中發生的所有情況。您無需猜測問題發生的原因,而是可以匯總和報告關鍵前端效能指標、重播用戶會話以及應用程式狀態、記錄網路請求並自動顯示所有錯誤。

現代化偵錯 Web 和行動應用程式的方式 - 開始免費監控。

以上是使用顯示和大小屬性簡化 CSS 動畫的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn