本篇依然来自于我们的 《前端周刊》 项目!
由团队成员 嘿嘿 翻译,他的文章风格稳健而清晰,注重结构与逻辑的严谨性,善于用简洁的语言将复杂技术拆解成易于理解的知识点~
欢迎大家 进群 与他探讨,并持续追踪全球前端领域的最新动态!

我第一次发现这个功能是在 Firefox 139 发布说明 中,我当时心想:噢,有意思 。然后我发现 Chrome 早在 2022 年就已经支持了。写到一半的时候,又看到 它已经在 Safari Technology Preview 125 中上线。嗯,这就是现状。
已经有一些不错的文章和教程在介绍 hidden=until-found
,于是我决定记下一些要点,方便以后查阅。
它让隐藏内容"可被搜索"
简而言之:在 HTML 元素上加上 hidden=until-found
,就能让该元素中隐藏的内容在浏览器的页面内搜索中被找到。
HTML
<div hidden="until-found">
<!-- 隐藏内容 -->
</div>
你会看到(或者更准确地说,不会看到)内容被隐藏了:
本质上是 content-visibility: hidden
浏览器会把这个属性当作提示,从而在用户代理样式(user agent styles)上隐式地设置 content-visibility: hidden
来隐藏内容。

如果我们按下 Ctrl
+ F
来启用页面内搜索,输入一个查询词,匹配的内容就会显示出来,并高亮该匹配词。

我们为什么需要它
当我深入研究时,我自己也在问这个问题。最典型的示例来自 Chrome for Developers 文档,用作一个"伪手风琴(accordion)"。也就是一组可点击展开/收起的面板。
但既然现在我们已经有了 [<details>](https://css-tricks.com/using-styling-the-details-element/)
元素,这不是已经解决了吗?毕竟它就是一个语义化的披露控件,用来 披露内容 。实际上,浏览器在 <details>
元素的 ::details-content 部分也会设置 content-visibility: hidden
来隐藏内容。

我敢说 <details>
在 2022 年时并没有像今天这样广泛支持。它现在实际上是 Interop 2025 的一部分,其中提到的一个功能就是页面内搜索的能力。Chrome 已经支持它,Firefox 最近也上线了(大概是 hidden=until-found
发布的一部分),Safari 预计也会在 Interop 2025 中支持。Chrome 文档的例子实际上是一种绕过 <details>
不完全支持的做法,而如今 <details>
已经逐步补齐。
那么,为什么要有 hidden=until-found
?
我不确定。肯定有某些场景需要以一种可访问的方式隐藏内容,同时仍然让它能被搜索。但我一时想不到。比如说,我们还有 popover
,不过它用的是 display: none
,会把内容彻底从页面内搜索中移除。

浏览器支持和 polyfill
我们已经知道 Chrome 和 Firefox 都支持该功能,不过 Safari 还没有。但既然 <details>
的可搜索内容已经被列入 Interop 2025(Firefox 也因此增加了支持),我觉得 Safari 很快也会跟上。(事实证明没错,它已经在 Safari Technology Preview 125 中上线。)
那么问题来了:在此之前,hidden=until-found
值得用吗?如果我们追求一致的跨浏览器体验,就得在 content-visibility: hidden
与 content-visibility: auto
之间来回切换。
Nathan Knowler 很专业地解释了其中的困境。我们无法在某个元素上直接用 content-visibility: hidden
,因为那样会把它从页面内搜索中移除。而 hidden=until-found
的作用与 content-visibility: hidden
一样,但仍然保持可搜索。换句话说,我们没法用 content-visibility
来 polyfill 这个功能。
感谢 Nathan,他深入探索,提出了一个利用 Shadow DOM 的解决方案:检测 HTML 属性、检查支持情况,并在必要时回退其属性,以一种既可访问又不完全移除搜索能力的方式来隐藏内容。
样式(Styling)
对一个本来不可见的东西来说,似乎没什么可说的样式问题。但注意,页面内搜索功能会高亮匹配的内容。

看起来我们可能会迎来一个新的 ::search-text
伪元素,它允许我们选中匹配的搜索内容并设置高亮颜色,这在 CSS Pseudo-Elements Module Level 4 规范 中目前还是 Editor's Draft 状态。
那如果有多个匹配呢?当前匹配和之后的匹配会有不同的高亮样式。

根据规范,我们大概可以把 ::search-text
与 :current
伪类组合,来选中当前匹配:::search-text:current
。
如果你以为还能把 ::search-text
和 :past
、:future
伪类混合使用,那恐怕要失望了。规范明确说这是无效的。但它也没有完全关上大门:
:past
和:future
伪类保留供将来使用。任何与::search-text
的不支持组合 必须 被视为无效。
还有别的吗?
没有太多了,但我很喜欢 Christian Shaefer 在 "Rethinking Find-in-Page Accessibility" 文章结尾的提示:我们需要考虑在搜索匹配后 接下来会发生什么。目前,在关闭或取消页面内搜索后,内容依然保持可见。也许我们还需要另一个 HTML 提示来解决这个问题。
参考链接
以下是我研究过程中用到的一些资料:
- "Making collapsed content accessible with hidden=until-found"(Joey Arhar)
- "Polyfilling hidden until-found"(Nathan Knowler)
- "Hidden until found"(James McGrath)
- "The
[hidden=until-found](https://github.com/WICG/display-locking/blob/main/explainers/hidden-content-explainer.md)
HTML attribute and the[beforematch](https://github.com/WICG/display-locking/blob/main/explainers/hidden-content-explainer.md)
event"(WICG explainer) - "Announcing Interop 2025"(WebKit Blog)
- Bugzilla Ticket #1761043
- MDN content update(GitHub)
[[::search-text]](https://drafts.csswg.org/css-pseudo-4/#selectordef-search-text)
(CSS Pseudo-Elements Module Level 4)