減少對偽元素的需求
已發表: 2022-03-10 根據 W3C 規範,“偽元素表示不直接存在於文檔樹中的元素”。 它們從 CSS 規範的第 1 版開始就出現了,當時引入了::first-letter
和::first-line
。 流行的::before
和::after
偽元素是在版本 2 中添加的——它們表示源文檔中根本不存在的內容。 它們可以被認為是兩個額外的元素,你可以“附加”到它們的原始元素上。 當前端開發人員聽到“偽元素”時,我們經常會想到::before
和::after
,因為我們以各種方式使用它們來為我們的元素添加裝飾。
除了這些之外,還有其他偽元素。 它們在規範中列在三個類別中:印刷、突出顯示和樹型。
有趣的是,經過多年的 Web 開發,我從未發現自己使用過::first-line
,但它非常簡潔,並且對窗口大小調整反應良好! 看看這個。
::selection
是許多人可以使用的另一個偽元素。 當用戶突出顯示文本時,突出顯示顏色將是您指定的顏色。
小建議
偽元素在 CSS 規範的版本 1 和 2 中使用了一個冒號,但在版本 3 中使用了兩個冒號。這將它們與描述元素狀態的偽類區分開來。 偽類使用一個冒號。
- 對偽元素使用兩個冒號(例如
::before
、::after
、::marker
)。- 偽類使用一個冒號(例如
:hover
、:focus
)。
偽元素並不總是需要
偽元素仍然有一席之地。 這篇文章不是“永遠不要使用偽元素”,而是“我們不再需要盡可能多地使用偽元素”。 我們可以在不需要偽元素的情況下為許多流行的用戶界面元素設置樣式。 通過減少對偽元素的依賴,我們可以編寫更少的 CSS,消除嵌套元素,忽略堆疊上下文問題,並忘記定位。
重新審視具有新 CSS 屬性的可信技術
多年來,我們耐心等待瀏覽器更快地採用 CSS 技術。 當一些主要參與者宣布將停止對 Internet Explorer (IE11) 的支持時,許多前端開發人員的轉折點出現了:
- 所有 Microsoft 365 Web 應用已於 2021 年 8 月 21 日停止支持 IE11。
- Google Workspace( Gmail 、日曆、雲端硬盤等)已於 2021 年 3 月 15 日停止支持 IE11。
這讓我們中的許多人可以更自由地探索更新的 CSS 技術:CSS Grid、 clamp()
、 background-blend-mode
等等。 CSS 屬性支持的狀態很好。 借助可更新的瀏覽器,支持正在加速。
舉個例子!
斜角按鈕
許多前端開發人員都熟悉使用::before
和::after
偽元素和 CSS 邊框規則來創建形狀。 有許多專門用於此目的的生成器工具——這是我收藏的一個。 這些工具指導您選擇形狀(通常是三角形),為您提供正確的 CSS 規則。
在創建有角度的按鈕時,這些工具是救生員。 對於有角度的按鈕,它們不再是必需的。
偽元素版本
許多閱讀本文的人會習慣於偽元素版本:
- 我們使用一個相對定位的帶有大右填充的包裝元素來適應我們的角度——這就是我們的
<button>
; - 我們中的許多人,滑動門技術的學生,習慣於嵌套一個元素來呈現按鈕的背景色。
- 最後,我們將一個帶有邊框規則的偽元素絕對定位到
<button>
的右側填充空白空間中——我們為此使用::before
。
除了這些步驟之外,我們的懸停樣式必須同時考慮我們的嵌套元素和偽元素。 這對您來說似乎可以管理,但是我們的按鈕設計越複雜,懸停樣式的開銷就越大。 此外,在此版本中,帶有自動換行的按鈕完全失敗。
無偽元素版本
如果沒有偽元素,這要容易得多。
- 我們使用一個包裝元素——我們的
<button>
。 - 我們使用
clip-path
屬性來只顯示我們想要的按鈕部分,使用calc()
和 CSS 自定義屬性來調整我們的角度——這些點集對應於左上角、右上角、右中角、底部右和左下角:polygon(0% 0%, calc(100% - var(--angle-width)) 0%, 100% 50%, calc(100% - var(--angle-width)) 100%, 0% 100%)
在 CodePen 示例中,您將--angle-width
自定義屬性從2rem
為另一個值,以查看我們按鈕的角度相應調整。
我們的懸停樣式只需要考慮一個元素——我們的按鈕。 此外,帶有自動換行的按鈕以更優雅的方式運行。
展示櫃中更多有角度的按鈕樣式
訪問最終展示,看看這些其他按鈕樣式在沒有偽元素的情況下變得更容易。 尤其是藍色斜角按鈕的偽元素版本非常殘酷。 由於clip-path
,整體工作量大大減少。
鈕扣濕巾
擦拭效果是一種流行的按鈕樣式。 我已經包括從左到右和從上到下的擦拭巾。
偽元素版本
這可以通過transitioning
偽元素的transform
來實現。
- 我們絕對定位一個
::before
偽元素並給它一個transform: scaleX(0)
所以它不可見。 - 我們還必須顯式設置它的
transform-origin: 0 0
以確保擦除從左側而不是中心進入(transform-origin
默認為中心)。 - 我們在
transform
上設置了transitions
,以實現一些流暢的爵士動畫開/關懸停。 - 因為我們的偽元素是絕對定位的,所以我們需要一個嵌套元素來保存按鈕的文本,
position: relative
在這個嵌套元素上創建一個新的堆疊上下文,因此我們的文本保持在我們正在擦除的偽元素之上。 - 在懸停時,我們可以定位我們的偽元素並將它的
scaleX
transition
為現在為1 (transform: scaleX(1))
。
無偽元素版本
如果我們不必擔心嵌套元素、偽元素定位、堆疊上下文和龐大的懸停規則,為什麼還要擔心呢?
我們可以使用linear-gradient()
和background-size
來確定這一點。
- 我們給我們的
<button>
一個background-color
作為它的默認狀態,同時還通過background-image
設置一個linear-gradient
——但是background-size
將是0
,所以默認情況下我們不會看到任何東西。 - 在懸停時,我們將
background-size
轉換為100% 100%
,這給了我們擦除效果!
請記住, linear-gradient()
使用background-image
屬性,而background-image
取代了background-color
,所以這就是懸停時的優先級。
而已。 不需要嵌套元素。 想要垂直擦拭? 只需更改linear-gradient
方向和background-size
值。 我已經通過 CSS 自定義屬性更改了這些。
帶有屏幕顏色疊加層的瓷磚
這是一種常見的模式,其中半透明顏色覆蓋瓷磚/卡片。 我們示例的圖塊也有一個背景圖像。 在此模式中,保留一組縱橫比通常很重要,這樣如果一組中出現多個圖塊,則圖塊看起來一致。
偽版
我們的偽元素版本也有一些相同的東西:
- 我們使用縱橫比“padding-trick”,為我們的 tile 設置 60% 的 padding-top 值(5:3 比率)。
- 我們必須定位我們的屏幕顏色覆蓋偽元素,給它一個 100% 的
width
和height
來填充瓷磚——我們在懸停時定位這個偽元素來改變它的background-color
。 - 由於偽元素的絕對定位,我們必須為我們的文本內容使用嵌套元素,同時給它
position: absolute
以便它以堆疊順序出現在我們的屏幕顏色疊加層之上,並確保它出現在它應該出現的位置瓷磚。
無偽元素版本
由於寬高比和背景混合模式屬性,它可以簡單得多。
注意: aspect-ratio
在 Safari 14.x 中不起作用,但在版本 15 中會起作用。
也就是說,在撰寫本文時,caniuse 將其列為 70% 以上的全球支持。
- “填充技巧”被
aspect-ratio: 400/240
(我們可以在這裡使用任何基於 5:3 的值)。 - 我們將
background-image
和background-color
屬性與background-blend-mode
結合使用——只需在懸停時更改 tile 元素的background-color
。
Background-blend-mode
background-blend-mode
將background-color
與元素的background-image
混合。 任何閱讀本文的 Photoshop 用戶都會發現background-blend-mode
讓人想起 Photoshop 的混合模式。 與mix-blend-mode
不同, background-blend-mode
不會創建新的堆疊上下文! 所以沒有z-index
地獄!
- 您可以在此處找到完整的展示演示 →
結論
前端開發令人興奮且發展迅速。 使用更新的 CSS 屬性,我們可以拂去舊技術的灰塵,讓它們煥然一新。 這樣做有助於促進減少和更簡單的代碼。 偽元素是有幫助的,但我們不需要盡可能多地使用它們。