Kodokon kodokon.com

现代选择器::has、:is、:where、进阶 :nth-child

利用近期的函数式伪类,基于内容进行选择、在不抬高特异性的情况下对选择器分组,并瞄准复杂的模式。

9 分钟 · 3 题

在 Kodokon 中打开本课

:is():where() 都能对选择器分组,但它们在一个决定性的点上分道扬镳:特异性:is(nav, .menu, #main a) 采用其最强参数的特异性(这里是那个 ID),即便实际匹配的是 nav:where() 的特异性为,无论其参数是什么。实际后果::where() 是重置样式和设计系统默认样式的理想工具,任何简单的类选择器随后都能毫不费力地覆盖它们。

CSS
:where(h1, h2, h3, h4) {
  margin-block: 0;
  line-height: 1.2;
}

:is(article, aside, section) :is(h2, h3) {
  font-family: var(--font-heading);
}

.prose :is(ul, ol) li + li {
  margin-top: 0.5em;
}
分组并控制特异性

:has() 终于反转了阅读方向:选择器瞄准的是宿主元素,而非它所包含的内容。.card:has(> img) 选中那些以图片作为直接子元素的卡片。与状态伪类结合,它让信息无需 JavaScript 就能向上流动:在字段无效时为其标签设置样式、在某个字段获得焦点时为整个表单设置样式、在复选框被勾选时为表格行设置样式。

CSS
.field:has(input:invalid:not(:focus)) label {
  color: #dc2626;
}

.card:has(> img) {
  padding-top: 0;
}

tr:has(input[type="checkbox"]:checked) {
  background: #eef2ff;
}
基于内容或内部状态进行选择

关于 :nth-child(),有两项技能需要夯实。其一,读懂 An+B 公式:2n(偶数)、2n+1(奇数)、-n+3(前三个)、n+4(从第四个到末尾);"从第 2 个到第 5 个"这个区间通过组合 :nth-child(n+2):nth-child(-n+5) 来写。其二,较新的 of S 语法::nth-child(2n of .visible) 只在匹配 .visible 的子元素当中计数,而 .visible:nth-child(2n) 会对所有子元素计数然后再过滤——一旦有其他元素穿插其间,两者就是截然不同的结果。

CSS
tr:nth-child(odd) {
  background: #fafafa;
}

li:nth-child(-n + 3) {
  font-weight: 600;
}

li:nth-child(n + 2):nth-child(-n + 5) {
  border-top: 1px solid #e5e7eb;
}

.row:nth-child(2n of .visible) {
  background: #eef2ff;
}
An+B 公式与 of S 语法

知识检测

确认你已牢记本课的重点内容。

  1. :where(#main, .nav, a) 的特异性是多少?
    • ID 的特异性,即 (1,0,0)
    • 三个参数之和
    • 零,无论参数是什么
    • 实际匹配的那个参数的特异性
  2. .card:has(> img) 选中什么?
    • 作为卡片直接子元素的图片
    • 含有图片作为直接子元素的卡片
    • 在 DOM 中位于图片之后的卡片
    • 作为卡片后代的所有图片
  3. 在一个只有部分 li 元素带有 .visible 的列表中,li:nth-child(2n of .visible) 做什么?
    • 瞄准列表中同时带有 .visible 类的偶数位 li 元素
    • 瞄准每隔一个 li,且只在 li.visible 元素中计数
    • 瞄准偶数位 li 元素,然后给它们添加 .visible