CSS伪类:focus-within与:has(:focus)的差异探究
:focus-within 与 :has(:focus) 的差异对比
:focus-within 和 :has(:focus) 同属CSS Level 4规范草案,不存在“:focus-within必须在:has()实现前使用”的依赖关系,二者的核心差异如下:
1. 匹配范围是否包含自身元素
- :focus-within 既会匹配自身获得焦点的元素,也会匹配后代元素获得焦点的情况(尽管名称里的“within”容易让人误以为只针对后代);
:has(:focus)仅匹配后代元素获得焦点的父元素。如果要实现和:focus-within完全一致的效果,需要结合:focus使用,比如CSS嵌套语法下的&:focus, &:has(:focus),非嵌套场景则用:is(.selector:focus, .selector:has(:focus)),这种写法语义上比:focus-within更清晰。
2. Shadow DOM支持的争议
MDN文档提到:focus-within的作用范围“包括影子树中的后代元素”,但CSS规范明确指出:focus-within针对的是扁平树中的后代(包含文本节点等非元素节点),且实际测试中无法复现:focus-within对Shadow DOM后代的匹配效果,这一点存在文档与规范的矛盾,暂未成为稳定的差异点。
示例:跳转链接的显示控制
HTML代码
<div class="skip-link">Skip to the <a href='#main'>content</a> or <a href='#footer'>footer</a>.</div>
使用:focus-within实现
.skip-link { transform: translateY(-100%); &:focus-within { transform: translateY(0%); } }
使用:has(:focus)实现等价效果
.skip-link { transform: translateY(-100%); &:focus, &:has(:focus) { transform: translateY(0%); } }
目前已明确的核心差异仅为上述自身元素匹配的问题,Shadow DOM相关的表现尚未形成统一结论。
内容的提问来源于stack exchange,提问作者Tigerrrrr
相关产品推荐
相关产品推荐

