乍看layer這個字,還以為是像Photoshop的圖層概念之類的東西,亦或是針對z-index之類的selector。結果竟是用來解決selector權重用的(對於CSS權重不是很了解的話,可以快速看一下這篇筆記。)依照layer宣告的順序,來決定樣式優先順序,後宣告的即使權重較小,也會覆寫。
這對於管理較大型、有一個一定複雜程度的樣式表的網站時,算是一個蠻實用的功能。可以減少在那邊important來important去的問題。
至於@layer的瀏覽器相容性,可以看一下這邊 https://caniuse.com/css-cascade-layers,目前看起來主流瀏覽器已經都支援,現階段已可以放心使用沒問題。
怎麼用?
將需要被分層級的樣式,用 @layer layername { … } 包起來,或者在import的時候宣告,例如:@import ‘base.css’ layer(base);。這時就已經會依照上述的順序規則來呈現結果了。
@import 'base.css' layer(base); | |
@layer layout { | |
.container { | |
border: 1px solid #0F0; | |
} | |
} | |
@layer plugin { | |
.container { | |
border: 1px solid #F00; | |
} | |
} |
也可以另外宣告 layers 的順序,@layer 也可以是巢狀結構:
@layer base { | |
@layer layout { | |
.container { | |
width: 80vw; | |
margin: 0 auto; | |
} | |
} | |
@layer utils { | |
.card { | |
border: 1px solid #f00; | |
border-radius: 4px; | |
} | |
} | |
} | |
/* 另外宣告順序 */ | |
@layer base.layout, base.card; |
如果只宣告一個layer的順序呢?
假設我們有三個layers,如下面的例子:
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title></title> | |
<style> | |
@layer layerOne { | |
.css-layer { | |
border: 1px solid #0F0; | |
} | |
} | |
@layer layerTwo { | |
.css-layer { | |
border: 1px solid #F00; | |
} | |
} | |
@layer layerThree { | |
.css-layer { | |
border: 1px solid #00F; | |
} | |
} | |
/* 只宣告layerThree的順序 */ | |
@layer layerThree; | |
</style> | |
</head> | |
<body> | |
<div class="css-layer"> | |
css @layer demo | |
</div> | |
</body> | |
</html> |
我們重新宣告了 @layer layerThree; 的順序,那最下方的 <div class=”css-layer”> 會顯示什麼顏色的匡線呢?
答案是紅色匡線。為什麼呢?明明只宣告了layerThree,其他的為什麼也會跑進來參一咖?
因為即使沒有宣告所有Layer的順序,沒被宣告的Layer還是依然存在,且順序如同樣式表中的順序往後排在宣告過的layer後面。也就是說,剛剛雖然僅宣告了layerThree,最後得到的順序會是:
layerThree, layerOne, layerTwo
也就是layerTwo最為優先。同理,如果只宣告了 layerTwo,順序會變成:
layerTwo, layerOne, layerThree
變成layerThree最為優先。
non-layered style以及!important
non-layered style 比 layered style 優先,就算寫在 layered style之前也一樣。例如:
.container { | |
/* 以這邊優先 */ | |
border: 1px solid #0F0; | |
} | |
@layer base { | |
.container { | |
border: 1px solid #F00; | |
} | |
} |
而 !important 就比較有趣。假設兩個都是 layered style 的 important ,優先度會依照寫的順序或宣告的順序而定。假設其中一個是non-layered style,卻是以layered style 的 !important 為優先。
.container { | |
border: 1px solid #0F0 !important; | |
} | |
@layer base { | |
.container { | |
/* 以這邊優先 */ | |
border: 1px solid #F00 !important; | |
} | |
} |
參考資料:https://developer.mozilla.org/zh-CN/docs/Web/CSS/@layer
引入外部样式,然后改变其顺序,似乎不生效。
@layer component-1,component,importLayer;
// @import ‘./import.css’;
@import url(‘./import.css’) layer(importLayer); 新希望 importLayer 最优先,不工作。请问这是为什么
我測試似乎沒有問題耶,在這個範例中 https://codepen.io/boggyjan/pen/bGPZRaz import 的css (layer0) 放在最後,使文字可以顯示layer0中設定的紅色
(引入的 css https://codepen.io/boggyjan/pen/VwJRWQr)