CSS :has() 交互指南
1. 什么是 :has()?
:has() 常被称为 “父级选择器”。它允许你根据一个元素内部是否包含某些子元素(或符合某种条件的后代元素)来给该元素本身设置样式。 本文将会探讨此问题,并介绍 :has() 的一些常见用法。
1.1 痛点
假设我们有一个 <figure> 标签,当它包含
<figcaption> 标签时,我们希望给
<figure> 添加一个样式。我们应该如何实现呢?
1 | <figure> |
当有说明文字时,我希望图片显示以下效果:
- Paddding
- Background
- Shadow
在 CSS 中,唯一可行的方法是给 <figure>
标签手动添加一个类名(class),然后通过该类名来选择其中的
<figcaption>。
1 | figure.with-caption { |
如果 HTML 是由后台编辑器或 Markdown
引擎动态生成的,你很难手动给包含标题的图片(figure)精准地加上
.with-caption 这个类。
1.2 解决办法
有了 CSS :has() 选择器,就好办多了。你可以像下面这样写 CSS:
1 | figure:has(figcaption) { |
1 | <figure> |
而这仅仅是使用 CSS :has() 的冰山一角。
复习 CSS 选择器
在我们深入之前,先来复习一下 CSS 选择器。
2.1 相邻兄弟选择器
要选择元素的下一个同级元素,我们可以使用相邻兄弟选择器 (+)。用于选择紧接在另一个元素后的元素,且二者有相同的父元素。
1 | .book { |
2.2 通用兄弟选择器
要选择元素的下一个同级元素,我们可以使用通用兄弟选择器 (~)。用于选择紧接在另一个元素后的元素,且二者有相同的父元素。
1 | .book { |
2.3 前一个兄弟选择器
借由 :has(),我们现在可以实现选择 “后面紧跟 B 的 A 元素”,从而间接实现了前一个兄弟选择器的功能。
以下代码实现如下功能:选中一个 .book 元素,前提是它的紧后方(+)紧跟着一个 .frame 元素。
1 | .book { |
基于上述,我们可以选择某个特定元素前的所有元素。以下代码实现选择 .frame 元素之前所有 .books 元素。
1 | .book { |
2.5 :not 伪类
:not() 伪类选择器在排除某个元素时非常有用。比如,当我们想要选择所有不包含 .blue 的 .book 元素时,可以这样写:
1 | .book:not(.blue) { |