[CSS] Efficient CSS
keywords: css
, refactor
:is()
和 :where
:is() @ MDN
範例一
/* 原本的寫法 */
article h2,
article h3,
article h4,
article h5 {
font-weight: bold;
font-family: sans-serif;
}
使用 :is()
(過去曾經稱作 :matches()
或 :any()
)來改寫:
/* 更好的寫法 */
article :is(h2, h3, h4, h5) {
font-weight: bold;
font-family: sans-serif;
}
範例二
/* CREDIT: https://developer.mozilla.org/en-US/docs/Web/CSS/:is */
/* 原本的寫法 */
header p:hover,
main p:hover,
footer p:hover {
color: red;
cursor: pointer;
}
可以優化成:
:is(header, main, footer) p:hover {
color: red;
cursor: pointer;
}
提示
:is()
和 :where()
的作用相同,差別只在於它們的 specificity 不同。
:not()
:not() @ MDN
:not()
前面有空格和沒空格的意思不同p:not(.foo)
:找到元素是<p>
,但 class 不為.foo
的元素p :not(.foo)
:<p>
元素中,class 不為.foo
的「所有」元素
:not(.foo, .bar)
的作用等同於:not(.foo):not(.bar)
/* CREDIT: https://developer.mozilla.org/en-US/docs/Web/CSS/:not */
/* 除了 class 是 .fancy 的其他所有 <p> */
p:not(.fancy) {
color: green;
}
/* <body> 中除了 <p> 之外的所有元素 */
body :not(p) {
text-decoration: underline;
}
/* <body> 中除了 <div> 或 <span> 的所有元素 */
body :not(div):not(span) {
font-weight: bold;
}
/* 等同於上面的寫法 */
body :not(div, span) {
font-weight: bold;
}
也可以搭配其他 selector 做組合技:
/* article 中所有 h2, h4, h5,以及「所有不是在 aside 裡的 h3」 */
article :is(h2, h3:not(aside h3), h4, h5) {
/* rules */
}
:has()
:如果有...則
:has() @ MDN
透過 :has()
可以用來「檢驗某個條件是否符合」,如果符合的話才套用特定的 CSS:
/* CREDIT: https://developer.mozilla.org/en-US/docs/Web/CSS/:has */
/* 如果 a 裡直接有 img,則套用特定樣式到 a 上 */
a:has(> img) {
/* rules */
}
/* 如果 h1 後面直接跟著 p,則套用特定樣式在 h1 上面 */
h1:has(+ p) {
color: red;
}
/* 如果 ul 中 li 有第 6 個 child,則以兩欄的方式顯示 */
ul:has(li:nth-child(6)) {
columns: 2;
}
/* 如果 ul 中 li 有第 11 個 child,則以三欄的方式顯示 */
ul:has(li:nth-child(6)) {
columns: 3;
}
參考資料
- Intermediate HTML and CSS @ Frontend Masters
- CSS @ MDN