:has()
是CSS的一个伪类选择器。它指定一个元素,该元素至少有一个与作为参数传递的相对选择器匹配的元素。它可用于检查父元素是否包含具有特定参数的子元素,这意味着我们可以用它来选择特定元素的父元素。
例如,p:has(span)
表示内部有一个 span
的段落选择器。您可以使用此元素设置父段落本身或其中的任何内容的样式。和 :not() 有点相似,后文也写了与之混合使用的例子。
:has 选择器介绍
:has 选择可以根据一个相对选择器来选中某个元素,如
div:has(p) 表示当 div 中有 p 时,选中 div
div:has(>p) 表示当 div 有子元素 p 时,选中 div
div:has(+p) 表示当 div 后面紧跟一个 p 时,选中 div
div:has(~p) 表示当 div 后续有 p 类型兄弟元素时,选中 div
举例
基础has写法
<div><p>div -- p</p></div>
<div><p class="active">div -- p.active</p></div>
<div><p>div -- p</p></div>
div:has(.active) {border: 1px solid #000;}
我们通过 div:has(.active)
选择器,意思是,选择 div 下存在 class 为 .active
的 div 元素。
注意,这里选择的不是 :has()
内包裹的选择器选中的元素,而是使用 :has()
伪类的宿主元素。
可以看到,由于第二个 div 下存在 class 为 .active
的元素,因此第二个 div 被加上了 border。
嵌套结构的父元素选择
<div><span>div span</span></div>
<div><ul><li><h2><span>div ul li h2 span</span></h2></li></ul></div>
<div><h2><span>div h2 span</span></h2></div>
div:has(>h2 >span) {margin-left: 24px;border: 1px solid #000;}
这里,要求准确选择 div 下直接子元素是 h2,且 h2 下直接子元素有 span 的 div 元素。注意,选择的最上层使用 :has()
的父元素 div。
这里体现的是嵌套结构,精确寻找对应的父元素。
同级结构的兄元素选择
<div class="has-test">div + p</div>
<p>p</p>
<div class="has-test">div + h1</div>
<h1>h1</h1>
<div class="has-test">div + h2</div>
<h2>h2</h2>
<div class="has-test">div + ul</div>
<ul>ul</ul>
我们想找到兄弟层级关系中,后面接了 <h2>
元素的 .has-test
元素,可以这样写:
.has-test:has(+ h2) {margin-left: 24px;border: 1px solid #000;}
这里体现的是兄弟结构,精确寻找对应的前置兄元素。
这样,一直以来,CSS 没有实现的父选择器,借由 :has()
开始,也能够做到了。
与:not() 一起使用
还是以上文第一个例子来说
<div><p>div -- p</p></div>
<div><p class="active">div -- p.active</p></div>
<div><p>div -- p</p></div>
之前是给中间的div加了一个框,现在反过来,不给中间的div加框,给上下两个div加框。
div:has(p:not(.active)){border: 1px solid #000;}
通过和 :not()
一起使用,就能到刚刚想要的效果。
:has()
这个选择器,能够极大程度的提升开发体验,解决之前需要比较多 JavaScript 代码才能够完成的事。
css中 :has() 伪类选择器用法:等您坐沙发呢!