CSS最新的强大:has() 父层选取器来了!
:has() 伪类是个非常好用的选取器,能够做到许多原本需要使用JS 才能达到的事,他的规范在很久之前就有制定,但是碍于浏览器性能的影响一直没有被支援,直到今年2022 ,随着Safari 开始支援:has() 的使用,未来各大浏览器跟着开放支援也只是时间的问题,所以是时候来认识这个强大的工具了!
1. :has() 伪类的用法
在css中,伪类是添加到选择器的关键字,用于指定所选元素的特殊状态。
用白话文来说,就是指:若某元素匹配某选择器,就可以让它做到某些我们指定要它做的事情。
以下举出一些简单好理解的例子:
a:has(img) { display: block; }这个例子表示,如果有任何<a>元素里面包含<img>的话,则这个<a>元素会吃到display: block; 的样式。
除了可以直接选取tag 之外,:has() 也支援所有的CSS 字符,以下用> 举个例子:
a:has(> img) { display: block; }这个例子表示,如果有任何<a>元素里面有直接的子元素<img>的话,则这个<a>元素会吃到display: block; 的样式,那如果<a>只是有其他非直接子元素的更远后代包含<img>的话就不会发挥作用。
再来,:has()也支援复杂选择器,例如:
article:has(h5, p) { background-color: #f0f3f9; }这个例子表示,假设有<article>元素当中包含了<h5>或<p>,则该<artical>背景色会变为#f0f3f9。
那如果想要的选择条件从或变为且呢?那就改为这样:
article:has(h5):has(p) { background-color: #f0f3f9; }这样的写法就会变为,同时包含了<h5>与<p>的<article>才会改变背景色。
以上举了少数几个:has() 能够使用的写法,那么当实际使用时可以怎么运用呢?接着来举例运用场景。
2. :has() 伪类的运用
• 元素表单必填栏位加上" * "
<form>
<item>
<label>用戶名</label>
<input required>
</item>
<item>
<label>備註</label>
<input>
</item>
</form>这时我们可以利用:has() 来帮第一个输入条件加上必填的星号:
label:has(+input:required)::before{
content: '*';
color: red;
}在这边我们运用了"+" 来指定与<label>同层级的第一个顺位,且有":required" 条件的<input>,让符合以上条件的input 的label 加上一个::before 伪元素来制作红色的"*"。
如果是以前的做法,可能会需要将要加上必填符号的<label>另外加上新的class name 之类的,那使用:has() 就不需要这么麻烦。
• Navbar 子选项hover 时改变<body> 背景色
从这个架构我们得到了三个基本选项的navbar:
<nav class="menu">
<a href="#" class="L1">選項1</a>
<a href="#" class="L2">選項2</a>
<a href="#" class="L3">選項3</a>
</nav>现在我们想让每个选项hover 时,整个<body>背景色都会随着改变成三种不同的颜色,我们可以这么做:
*这边先略过基本的Menu 样式设定,直接切入重点叙述如何让选项 hover 时改变整个<body> 的色彩*
body:has(.L1:hover) {
background-color: #3f7fab;
}
body:has(.L2:hover) {
background-color: #9b6acf;
}
body:has(.L3:hover) {
background-color: #57936d;
} 可以看到上面的CSS 写法就是利用:has() 让.L1 .L2 .L3 hover 时,<body>去做个别情境下的换色,就这么简单!
但以往想做到这样子的效果,会需要使用到JS ,现在只要短短几行就可以在CSS 解决了,是不是很值得欢呼!
3. :has() 伪类的浏览器兼容

目前:has() 在浏览器的兼容上还不是那么广泛,但是相信在未来一年的时间,一定会更加普及,到时候就可以随心所欲地使用了。
来自:https://www.tpisoftware.com/tpu/articleDetails/2883
本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!