CSS 函数式伪类 :has() 表示一个元素,如果作为参数传递的任何相对选择器在锚定到该元素时,至少匹配一个元素。这个伪类通过把可容错相对选择器列表作为参数,提供了一种针对引用元素选择父元素或者先前的兄弟元素的方法。
现在,随着CSS的:has()选择器得到广泛支持,我们终于可以大展身手。在这篇文章中,我将分享一些有趣的CSS:has()选择器用法
相邻兄弟元素的选择
之前我们只能通过 +(选择元素的下一个同级元素), ~(选择一个元素的所有下一个同级元素) 选择器进行下一个同级元素的选择,那么如何进行向前的元素选择呢?没错,就是它:has()
<div class="shelf">
<div class="book"></div>
<div class="book"></div>
<div class="book"></div>
<p class="frame"></p>
<div class="book"></div>
<div class="book"></div>
<div class="book"></div>
</div>
// 前一个兄弟元素
.book:has(+ .frame) {
opacity: 1;
}
// 前面所有兄弟元素
.book:has(~ .frame) {
opacity: 1;
}
为了更清晰地解释,我们可以这样理解:.book + .frame选择器用于匹配.book元素的下一个同级元素.frame,而.book:has(+ .frame)选择器则表示匹配.book元素拥有一个为.frame的下一个兄弟元素,也就是匹配.frame元素的前一个兄弟元素.book。
单选
我们在常见的问卷调查中常用单选和多选功能,我们可以使用:has()来实现更多复杂的交互。
<div class="question">
<div class="question-header">当前文章的主题是什么?</div>
<div class="list">
<div class="answer">
<input type="radio" name="option" id="option-0" data-correct="false" />
<label for="option-0">响应式设计</label>
</div>
<div class="answer">
<input type="radio" name="option" id="option-1" data-correct="true" />
<label for="option-1">CSS :has 选择器</label>
</div>
<!-- 其他选项 -->
</div>
</div>
我们用 data-correct属性表示是否正确,如果答案错误,那么我们添加红色,正确答案会呈绿色闪烁。
// 错误答案被选择时
.question:has(input[data-correct='false']:checked) {
// 错误时标题变为红色
.question-header {
box-shadow: inset 0 7px 0 0 var(--wrong);
background-color: var(--wrong-bg);
}
// 正确答案闪烁
input[data-correct="true"] + label {
animation: flash 1s infinite alternate;
}
}
如果答案正确,那么我们添加为绿色
.question:has(input[data-correct='true']:checked) {
.question-header {
box-shadow: inset 0 7px 0 0 var(--correct);
background-color: var(--correct-bg);
}
}
代码演示
多选
多选功能的代码结构相似,这里就不再重复展示了。您可以参考下面的演示代码查看相关内容,设计的重点是:只有同时选择了所有正确答案才会显示绿色,否则标记为红色。其次,在选择了正确答案后,将错误答案标识为不可选。我们将根据这两点进行设计和分析。
由于答案可能有多个,因此我们通过属性 data-correct="true1" 和 data-correct="true2" 来标识它们。如何表示“并且”关系?其实很简单,可以参考以下代码示例。
.question:has(input[data-correct='true1']:checked).question:has(
input[data-correct='true2']:checked
).question:not(:has(input[data-correct='false']:checked)) {
.question-header {
box-shadow: inset 0 7px 0 0 var(--correct);
background-color: var(--correct-bg);
}
// 禁用错误答案选项
.answer:has(input[data-correct='false']) {
opacity: 0.5;
cursor: not-allowed;
label {
pointer-events: none; // 禁用
}
}
}
代码演示
以上就是本文所展示的内容,旨在抛砖引玉。如有错漏还请大家指正。