CSS :has / :is 選取器筆記

簡易的可操作範例可參考 codepen。

:has()

MND: :has() represents an element if any of the relative selectors that are passed as an argument match at least one element when anchored against this element. This pseudo-class presents a way of selecting a parent element or a previous sibling element with respect to a reference element by taking a relative selector list as an argument.

參數:(目標親元件、錨點)需要包含的子元件。

行為:選取包含指定元件的親元件。

注意事項:


選擇所有「包含 .special 元件」的 div 元件:

div:has(.special) {
  border: 2px dashed salmon;
  color: gold;
}

選取所有「被 p 元件緊隨在後」的 h1 元件:

h1:has(+ p) {
  margin-bottom: 0;
}

:is()

MDN: :is() takes a selector list as its argument, and selects any element that can be selected by one of the selectors in that list.

參數:一個列表(list),包含各種選取器(CSS selector)。

行為:選取任何在參數列表中的元件。

注意事項:


選取所有親元件是 .parent1 或 .parent2 的 .child 元件:

:is(.parent1, .parent2) .child {
  color: skyblue;
}

由 mdn 提供的最佳優化範例——比如以下又臭又長的樣式:

ol ol ul,
ol ul ul,
ol menu ul,
ol dir ul,
ol ol menu,
ol ul menu,
ol menu menu,
ol dir menu,
ol ol dir,
ol ul dir,
ol menu dir,
ol dir dir,
ul ol ul,
ul ul ul,
ul menu ul,
ul dir ul,
ul ol menu,
ul ul menu,
ul menu menu,
ul dir menu,
ul ol dir,
ul ul dir,
ul menu dir,
ul dir dir,
menu ol ul,
menu ul ul,
menu menu ul,
menu dir ul,
menu ol menu,
menu ul menu,
menu menu menu,
menu dir menu,
menu ol dir,
menu ul dir,
menu menu dir,
menu dir dir,
dir ol ul,
dir ul ul,
dir menu ul,
dir dir ul,
dir ol menu,
dir ul menu,
dir menu menu,
dir dir menu,
dir ol dir,
dir ul dir,
dir menu dir,
dir dir dir {
  list-style-type: square;
}

可以簡化成以下:

:is(ol, ul, menu, dir) :is(ol, ul, menu, dir) :is(ul, menu, dir) {
  list-style-type: square;
}

簡直是魔法 🪄

支援度(2024/6)

caniuse: css :has() selector

caniuse: css :is() selector

參考文章