CSS是一种强大的语言,但一直以来有许多事情它都无法做到。 然而,现在,随着CSS:has() 伪类的引入,它现在将能够轻松地执行大多数这些动作。 这是CSS中引入的最令人激动、最令人期待的功能之一。
因此,让我们来了解一下:has() 选择器。
需要
根据CSS规则,子元素的目标是基于父元素的(从右到左)。在下面的例子中,<button> 是<div> 元素内的目标元素,CSS属性background: red 应用于<button> 。
div button {
background: red;
}
现在,如果我们想针对包含<button> 元素的<div> 元素,该怎么办? 那么,我们现在可以借助:has() 选择器来实现这个目标。
描述:has() 的最简单方法是作为一个父选择器。 如果我们希望根据内容或子元素来定位父元素,我们可以使用:has() 。
语法
:has() 代表一个元素,如果作为参数传递的选择器与<target> 元素内的元素匹配。
<target>:has<selector>
例子
让我们考虑同样的例子来理解:has() 选择器。在下面的例子中,使用:has() 选择器,我们的目标是拥有<button> 元素的<div> 。
div:has(button) {
background: red
}
这里,<div> 是目标元素,<button> 是选择器,这意味着CSS属性background:red 只有在包含<button> 元素时才会应用到<div> 。
现实世界的情况
所以,假设我们有一个产品列表,其中一些产品是有优惠的。 假设我们想对有优惠的产品应用一些额外的样式。
<div class="Container">
<div class="product">
<h1>Product 1</h1>
<h3>$130</h3>
<button class="buy">Buy</button>
</div>
<div class="product">
<h1>Product 2</h1>
<h3>$130</h3>
<button class="buy">Buy</button>
</div>
<div class="product">
<h1>Product 3</h1>
<h3>$100</h3>
<button class="offer">Apply offer</button>
</div>
</div>
如上面的代码所示,我们有3个产品,其中一个有优惠,现在,我们需要对这个特定的产品应用一些额外的CSS。 一般来说,我们使用JQuery或JavaScript来实现这种情况,如下图所示。
<script>
const products = document.getElementsByClassName("product");
for (let i = 0; i < products.length; i++) {
let isOffer = products[i].getElementsByClassName("offer");
if (isOffer[0]) {
products[i].style.border = "2px solid green";
products[i].style.boxShadow = "5px 5px 10px lightgreen";
}
}
</script>
令人兴奋的是,我们可以避免使用任何JavaScript或JQuery,并通过使用:has() 选择器来简化上述代码。
.product:has(button.offer) {
border: 2px solid green;
box-shadow: 5px 5px 10px lightgreen;
}
在这里,如果作为参数传递的选择器button.offer 与product 里面的元素相匹配,那么上述CSS就会被应用。
只有Product 3 符合这个条件,如下图所示。
限制条件
尽管:has() ,但也有一些限制。
- 我们不能用
:has(),也不能用:has()。
:has(.x:has(.y)) { … }
- 我们不能在
:has()中使用psudeo元素。
:has(::after) { … }
- 使用
:visited将永远是假的。
:has(:visited) { … }
浏览器兼容性
要检查浏览器的兼容性。
- 目前,只有最新版本的Safari默认支持
:has()选择器。 - 我们可以通过启用实验性网络平台功能,在最新版本的Chrome上启用
:has()。 - 我们可以在最新版本的Firefox上使用
layout.css.has-selector.enabled标志启用:has()。