使用 :has() 作为 CSS 父选择器及其他更多内容
内容提要
CSS选择器 level 4中定义了:has()伪类,可以根据元素内部情况应用CSS样式。:has()可与其他伪类和组合器结合使用,实现各种功能,如根据图像有无为元素应用不同布局,根据表单输入栏状态为表单应用不同样式等。还可用于表单状态样式、CSS Grid布局和暗模式切换。
延伸解读
从“不可能”到“已实现”::has() 的性能突破
过去二十年,父选择器因循环计算和性能问题被搁置。:has() 在 CSS 选择器 Level 4 中定义后,WebKit 团队通过开发特定的缓存和过滤优化,并利用现有 CSS 引擎策略,证明了即使面对大型 DOM 和大量 :has() 选择器,也能实现高性能。这为其他浏览器跟进奠定了基础。
浏览器支持现状与使用建议
Safari 15.4 于 2022 年 3 月率先支持 :has(),Chrome 105 于同年 8 月跟进,Firefox 仍在开发中。文章建议使用 @supports selector(:has(img)) 进行特性查询,并提醒目前并非所有伪类都能在 :has() 内工作,如动态媒体伪类 :playing 等,且某些表单失效状态可能无法更新。
超越父选择器:与组合器结合的灵活性
:has() 不仅能选择包含特定后代的父元素,还能与子代组合器(>)和同级组合器(+、~)结合。例如,a:has(> img) 仅当 img 是 a 的直接子元素时生效;h2:has(+ p) 可选择后面紧邻段落的标题。这些组合让选择器能精确匹配 DOM 结构,实现以往需要 JavaScript 的样式逻辑。
无 JavaScript 的状态样式与主题切换
利用 :has() 和表单伪类(如 :focus-visible、:invalid、:checked),可以纯 CSS 实现表单状态样式和暗模式切换。例如,form:has(:focus-visible) 可在任意输入框聚焦时改变整个表单背景;body:has(input[type="checkbox"]:checked) 可切换主题变量。这减少了 JavaScript 依赖,提升了性能和用户体验。
Q&A
:has()伪类在CSS中有什么作用?
:has()伪类可以根据元素内部的情况应用CSS样式,允许开发者根据子元素的存在与否来改变父元素的样式。
如何使用:has()实现无JavaScript的表单状态样式?
可以使用:has()结合表单输入伪类,如:focus-visible,来为表单应用样式,而无需JavaScript。
:has()如何与CSS Grid布局结合使用?
:has()可以用于根据元素是否包含图像来调整CSS Grid中元素的占用空间,例如让包含图像的卡片占用更多的网格区域。
:has()与其他选择器的结合使用有什么优势?
:has()可以与子组合器、同级组合器等结合使用,提供更灵活的选择器功能,能够实现复杂的样式应用。
:has()的引入对CSS选择器有什么影响?
:has()的引入被视为CSS选择器的一场革命,开启了新的可能性,使得开发者能够更灵活地控制样式。
目前哪些浏览器支持:has()伪类?
截至2022年,Safari和Chromium浏览器已支持:has(),而Firefox的实现正在开发中。