参考文章: The Power of :has() in CSS
语法
:has(<direct-selector>) {
/* ... */
}
CSS 函数式伪类 :has() 表示一个元素,如果作为参数传递的任何相对选择器在锚定到该元素时,至少匹配一个元素。这个伪类通过把可容错相对选择器列表作为参数,提供了一种针对引用元素选择父元素或者先前的兄弟元素的方法。这是 MDN 的解释。
样式问题
在过去的几年里,我们无法使用 CSS 或某个元素来基于父元素的直接子元素对父元素进行样式设置。在必须这样做的情况下,我们需要使用一些 JavaScript,并根据 HTML 结构切换类的开关。:has() 伪类解决了这个问题。
假设你有一个h1元素,它是博客列表页面上的一篇文章或类似内容的标题,然后紧接着它的是h2元素。这个h2可能是文章的子标题。如果这个h2存在、重要,并且直接跟在h1之后,你可能希望突出显示这个h1。
<h1>这是h1标题</h1>
<h2>这是h2标题</h2>
在以前,你可能需要编写一个 JavaScript 函数来实现这个功能。
const h1Elements = document.querySelectorAll('h1');
h1Elements.forEach((h1) => {
const h2Sibling = h1.nextElementSibling;
if (h2Sibling && h2Sibling.tagName.toLowerCase() === 'h2') {
h1.classList.add('highlight-content');
}
});
而现在你可以这么写
h1:has(+ h2) {
color: blue;
}
这个 CSS 检查任何 h1,并使用兄弟组合器检查紧随其后的 h2,并将文本颜色设置为蓝色。
:has() 实际案例
下面的例子是使用:has()来查看图形或图像是否有figcaption元素,如果有,它会应用一些背景和边界半径突出图像。
HTML
<section>
<figure>
<img src="https://placedog.net/500/280" alt="My aunt sally's dog is a golden retreiver." />
<figcaption>My Aunt Sally's Doggo</figcaption>
</figure>
</section>
CSS
figure:has(figcaption) {
background: #c3baba;
padding: 0.6rem;
max-width: 50%;
border-radius: 5px;
}
浏览器兼容性
Can I use :has() 可以看到 :has() 支持现代化浏览器
注意事项
在使用 :has() 时需要牢记以下几点,这些要点参考自 MDN:
- 伪类接受其参数中最具体选择器的特异性。
- 如果浏览器不支持
:has()伪类本身,则整个选择器块将失败,除非:has()出现在一个宽容的选择器列表中,比如在:is()和:where()中。 :has()伪类不能嵌套在另一个:has()中。- 伪元素在
:has()中也不是有效选择器,伪元素也不是:has()的有效锚点。
结束语
利用 CSS 的强大功能,包括像 :has() 伪类这样的高级特性,使我们能够打造出卓越的网络体验。CSS 的优势在于其层叠和特异性等,最棒的部分在于,它让我们能够充分利用其潜力。通过拥抱 CSS 的能力,我们可以推动网页设计和开发向前发展,释放出新的可能性,创造出开创性的用户界面。