1. 场景还原
在实际开发中,我们可能会遇到控制前面兄弟元素样式的场景。例如下面的HTML,我们需要在不修改HTML内容的前提下将内容1前面的标题1设置为天蓝色,直接给.title设置样式肯定不行,会影响标题2的颜色,在CSS选择器中也没有提供前面兄弟选择符,此时应该怎么做?
<h2 class="title">标题1</h2>
<div class="content">内容1</div>
<h2 class="title">标题2</h2>
<p>内容2</p>
如果项目对兼容性要求不高,可以用2022年才开始支持的新的关联伪类:has():
下面的CSS代码表示选择具有 title 类的元素,并且这些元素的下一个相邻兄弟元素是一个具有 content 类的元素。
.title:has(+ .content) {
color: skyblue;
}
此时的标题1就设置成了天蓝色,标题2并未受影响
2. :has伪类介绍
兼容性
:has伪类是Safari浏览器在2022年才开始支持的,Chrome105 版本以后也支持,IE全版本均不支持,请勿使用在需要兼容IE的实际项目中,具体兼容版本可以参考链接:https://caniuse.com/?search=%3Ahas
语法
:has()伪类的通用语法支持各种类型的选择器和复杂的选择器组合。其基本语法如下:
选择器1:has(选择器2) {
}
选择器1: 是你想要选择的前面元素的选择器。
选择器2: 是你想要选择的后面元素的选择器。
可以这样理解:如果选择器1匹配到选择器2,则能匹配到选择器1
例如下面的CSS代码表示如果<a>元素(选择器1)里面有(匹配)<img>元素(选择器2),则<a>元素(选择器1)就匹配
a:has(img) {
display: block;
}
:has()伪类支持所有CSS选择符(选择符放在最前面),例如:
a:has(> img) {
display: block;
}
表示子元素是<img>元素的<a>元素会被匹配 ,实现了父选择器的效果
:has()伪类的优先级为0,优先级由括号里的选择器决定。
示例
下面是一些:has()伪类示例,请结合实际应用场景使用:
1. 选择包含至少一个 <li> 元素的 <ul> 元素:
ul:has(li) {
/* 样式 */
}
2. 选择包含类名为 .highlight 的子元素的父元素:
div:has(> .highlight) {
/* 样式 */
}
3. 选择包含 <span> 或 <a> 元素的父元素(OR):
div:has(span, a) {
/* 样式 */
}
4. 选择同时包含 <span> 和 <a> 元素的父元素(AND):
div:has(span):has(a) {
/* 样式 */
}