:is() 是什麼?讓選擇器更簡潔的實用語法在寫 CSS 時,我們常常會遇到多個 selector 需要套用同一組樣式的情境。
如果每個 selector 都分開寫,CSS 很容易變得冗長、重複,也不太好維護。
這時候就可以使用 CSS 的 :is() 選擇器函式。
:is() 是什麼?:is() 是 CSS 的一種 選擇器函式,可以把多個 selector 條件合併在一起。
它的意思可以理解成:
只要符合括號裡任一個 selector,就套用這段 CSS。
例如:
:is(h1, h2, h3) {
color: red;
}
代表 h1、h2、h3 都會套用這組樣式。
原本我們可能會這樣寫:
.card h1,
.card h2,
.card h3 {
color: red;
}
使用 :is() 後,可以改成:
.card :is(h1, h2, h3) {
color: red;
}
這段 CSS 的意思是:
.card 裡面的 h1、h2、h3 都套用 color: red
也就是說,:is(h1, h2, h3) 代表:
h1 或 h2 或 h3
在使用 :is() 時,要注意 selector 中間有沒有空格,因為意思會不一樣。
.card :is(h1, h2, h3) {
color: red;
}
代表:
.card 裡面的 h1、h2、h3
也就是選取 .card 內部的標題元素。
.card:is(h1, h2, h3) {
color: red;
}
代表:
同一個元素本身同時有 .card,且它本身是 h1、h2 或 h3
例如下面這種元素才會被選到:
<h1 class="card">Title</h1>
所以:
.card :is(h1, h2, h3)
和:
.card:is(h1, h2, h3)
意思是不一樣的。
:is()?假設我們想讓 header、main、footer 裡面的連結都套用同樣樣式。
原本可能會寫成:
header a,
main a,
footer a {
color: blue;
}
使用 :is() 可以簡化成:
:is(header, main, footer) a {
color: blue;
}
這樣不只比較短,也比較容易閱讀。
例如我們有兩種按鈕樣式:
.btn-primary {
padding: 8px 16px;
border-radius: 4px;
}
.btn-secondary {
padding: 8px 16px;
border-radius: 4px;
}
這兩個 class 有相同的基礎樣式,就可以使用 :is() 合併:
:is(.btn-primary, .btn-secondary) {
padding: 8px 16px;
border-radius: 4px;
}
這樣可以避免重複撰寫相同的 CSS。
在處理文章頁、Blog 頁、CMS 內容時,常常會針對標題、段落、清單統一設定間距。
例如:
.article :is(h2, h3, p, ul, ol) {
margin-bottom: 16px;
}
代表:
.article 裡面的 h2、h3、p、ul、ol 都會有 margin-bottom: 16px
這種寫法很適合用在文章內容排版,因為可以減少大量重複的 selector。
:is() 也可以搭配 :hover、:focus 這類狀態 selector。
例如:
button:is(:hover, :focus) {
background: black;
color: white;
}
這段的意思是:
button 在 hover 或 focus 狀態時,都套用這組樣式
如果不用 :is(),可能會寫成:
button:hover,
button:focus {
background: black;
color: white;
}
使用 :is() 後可以讓狀態條件更集中。
:is() 和 :where() 的差別:is() 和 :where() 看起來很像,都是用來合併 selector。
例如:
:is(.card, #main) p {
color: red;
}
以及:
:where(.card, #main) p {
color: red;
}
兩者最大的差別在於 CSS 權重,也就是 specificity。
:is() 會採用括號內最高的權重:is() 本身不會額外增加權重,但它會採用括號內 selector 中 權重最高的那一個。
例如:
:is(.card, #main) p {
color: red;
}
因為 #main 是 id selector,權重比 .card 高,所以 :is(.card, #main) 這一段會採用 #main 的權重。
也就是說,這段 selector 的權重會比較高,後續如果想覆蓋樣式,就需要注意 specificity 的影響。
:where() 權重永遠是 0:where() 的特點是:
本身權重永遠是 0
例如:
:where(.card, #main) p {
color: red;
}
即使括號裡有 .card 或 #main,:where() 也不會增加權重。
所以 :where() 很適合用在「預設樣式」、「基礎樣式」、「容易被覆蓋的樣式」。
| 語法 | 用途 | 權重 |
|---|---|---|
:is() |
合併多個 selector | 採用括號內最高權重 |
:where() |
合併多個 selector | 權重永遠是 0 |
簡單記法:
:is() = 合併 selector,會採用括號內最高權重
:where() = 合併 selector,但權重是 0,容易被覆蓋
:is()?適合使用 :is() 的情境包含:
1. 多個 selector 要套用同一組樣式
2. 想減少 CSS 重複撰寫
3. 想讓巢狀 selector 更好閱讀
4. 多個狀態需要共用樣式
5. 文章頁、內容頁需要統一設定標題與段落樣式
例如:
.article :is(h1, h2, h3, p, blockquote) {
margin-bottom: 1rem;
}
或是:
.form-control:is(:hover, :focus) {
border-color: #333;
}
:is() 要注意什麼?雖然 :is() 很方便,但還是要注意權重問題。
例如:
:is(.card, #main) p {
color: red;
}
因為裡面包含 #main,所以整段 selector 的權重會變高。
如果你的目標只是寫一組容易被覆蓋的基礎樣式,可能就比較適合使用 :where()。
另外,也要注意 selector 中間有沒有空格:
.card :is(h1, h2, h3)
代表選取 .card 裡面的 h1、h2、h3。
但:
.card:is(h1, h2, h3)
代表選取本身同時符合 .card,且是 h1、h2 或 h3 的元素。
:is() 是一個可以讓 CSS selector 更簡潔、更好維護的語法。
它特別適合用在多個 selector 共用樣式的情境,例如標題、段落、按鈕、表單狀態等等。
可以把它簡單理解成:
:is() = 括號裡只要符合其中一個條件,就套用樣式
而它和 :where() 最大的差別是:
:is() 會採用括號內最高權重
:where() 權重永遠是 0
在實務上,如果你想減少重複 selector,又希望保留正常 CSS 權重,可以使用 :is()。
如果你想寫容易被覆蓋的基礎樣式,則可以考慮使用 :where()。