文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

一篇带你了解全新的的 CSS 选择器 :Has()

2024-12-13 16:29

关注

你有没有想过使用CSS选择器来检查父元素中是否存在特定的元素?例如,如果一个卡片组件中有图片,就给它添加一个display:flex。这以前在CSS中是无法实现的,而全新的 CSS 选择器:has就可以帮助我们选择包含特定元素的父元素。下面来看看这个全新的 CSS 选择器吧!

:has 选择器概述

在CSS中,我们无法根据元素中是否存在特定的元素来设置父元素的样式,要想实现这一点,就必须创建CSS类,并根据需要进行类的切换。来看下面的例子:

这里有两种卡片:包含图片和不包含图片。在CSS中需要这样做:


.card {
display: flex;
align-items: center;
gap: 1rem;
}


.card-plain {
display: block;
border-top: 3px solid #7c93e9;
}
<!-- 有图片的卡片 -->
<div class="card">
<div class="card-image">
<img src="awameh.jpg" alt="">
div>
<div class="card-content">
卡片内容
div>
div>

<!-- 没有图片的卡片 -->
<div class="card card-plain">
<div class="card-content">
卡片内容
div>
div>

这里创建了一个类card-plain,专门用于没有图片的卡片,在没有图片时就不需要flex布局。如果使用 CSS 中的父选择器 :has 就不需要再写这个类,只需要使用它来检查卡片中是否包含.card-image即可:

.card:has(.card-image) {
display: flex;
align-items: center;
}

​根据 CSS 规范,:has 选择器可以检查父元素是否包含至少一个元素,或者一个条件,例如输入是否获取到焦点。

:has 选择器不仅可以检查父元素是否包含特定的子元素,还可以检查一个元素后面是否跟有另一个元素:

.card h2:has(+ p) { }

这将检查 

 元素是否直接跟在 

 元素之后。

我们也可以将它与表单元素一起使用来检查输入是否获取到了焦点:

form:has(input:focused) {
background-color: lightgrey;
}

:has 选择器使用示例

下面来看看一些使用:has选择器实现页面效果的案例吧!

1、样式

当处理章节时有两种情况,一种是只包含,另一种包含和链接。

根据是否有链接来定义不同的样式:

<section>
<div class="section-header">
<h2>Latest articlesh2>
<a href="/articles/>See all
div>
section>
.section-header {
display: flex;
justify-content: space-between;
}

.section-header:has(> a) {
align-items: center;
border-bottom: 1px solid;
padding-bottom: 0.5rem;
}

这里使用了:has(> a),它表示只选择直接子元素。

2、卡片布局

有两种类型的卡片操作:一种只有一个操作(链接),另一种具有多个操作(保存、分享等)。

当图片具有多个操作时需要给这些操作添加display: flex,可以这样来实现:

<div class="card">
<div class="card-thumb>cool.jpg"/>

<div class="card-content">
<div class="card-actions">
<div class="start">
<a href="#">Likea>
<a href="#">Savea>
div>
<div class="end">
<a href="#">Morea>
div>
div>
div>
div>
.card-actions:has(.start, .end) {
display: flex;
justify-content: space-between;
}

3、卡片圆角

根据是否有图片来重置卡片组件的border-radius。

.card:not(:has(img)) .card-content {
border-top-left-radius: 12px;
border-top-right-radius: 12px;
}

.card img {
border-top-left-radius: 12px;
border-top-right-radius: 12px;
}

.card-content {
border-bottom-left-radius: 12px;
border-bottom-right-radius: 12px;
}

实现效果如下:

4、过滤组件

有一个具有多个选项的组件,当它们没有被选中时,不显示重置按钮。当选中其中一个选项时,显示重置按钮。

可以使用 :has选择器轻松实现这个功能:

.btn-reset {
display: none;
}

.multiselect:has(input:checked) .btn-reset {
display: block;
}

5、显示或隐藏表单元素

有时可能需要根据之前的选择来显示特定的表单字段。在下面的例子中,当下拉框选中“other”字段时,就展示 other reason 输入框:

使用 CSS :has 选择器就可以检查选择菜单是否选择了 other 字段,并在此基础上显示 other reason 输入框:

.other-field {
display: block;
}

form:has(option[value="other"]:checked) .other-field {
display: block;
}

6、导航栏

有一个带有子菜单的导航栏,当鼠标悬停在菜单项上时展示子菜单:

我们需要做的就是根据是否展示子菜单来显示或隐藏右侧的箭头。可以使用:has 选择器轻松实现这一点,这里只需检查li元素中是否包含ul即可:

li:has(ul) > a:after {
content: "";
}

7、强制警报

在某些仪表板中,可能需要用户必须注意重要警报。在这种情况下,拥有页内警报可能还不够。例如,在这种情况下,可能会为元素添加红色边框和暗红色背景色。这样会增加用户快速注意到警报的可能性。

CSS :has 就可以检查.main元素是否有警报。如果有,将以下样式添加到中:

.main:has(.alert) .header {
border-top: 2px solid red;
background-color: #fff4f4;
}

8、切换配色方案

可以使用 CSS :has 来更改网站的配色方案。例如,如果有多个使用 CSS 变量构建的主题,可以通过