{"slug": "hidden-until-found", "title": "Hidden until found", "summary": "The HTML `hidden=\"until-found\"` attribute allows developers to hide collapsible content while keeping it accessible to browser find-in-page, assistive technologies, and search engines. When a user searches for text within a collapsed element, the browser automatically expands it and fires a `beforematch` event, enabling developers to sync widget state without JavaScript workarounds. This approach solves a key accessibility gap in common accordion and tab patterns that use `display: none`, which removes content from find-in-page and the accessibility tree entirely.", "body_md": "# Hidden until found\n\nUse hidden=\"until-found\" for collapsible content so that browser find-in-page, assistive tech, and search engines can still reach the text and auto-expand it.\n\n## What it is\n\n`hidden=\"until-found\"`\n\nis a value of the global `hidden`\n\nattribute defined in the HTML Standard. An element marked this way renders as if hidden — it takes up no visible space — but the browser’s find-in-page (Ctrl/Cmd+F), the fragment-directive scroll-to-text, and `scrollIntoView()`\n\nstill walk through it. When a match is found inside, the browser fires a `beforematch`\n\nevent on the element, removes the `hidden`\n\nattribute, and scrolls the match into view.\n\nThe browser’s user-agent stylesheet applies `content-visibility: hidden`\n\nto elements in the until-found state, and the find-in-page algorithm has a specific exception for that state — when a match would land inside the subtree, it walks the element, removes the `hidden`\n\nattribute, and scrolls into view. **Applying content-visibility: hidden directly in author CSS does not get you the same behaviour.** Per the CSS Containment specification, contents in that state are skipped from rendering\n\n*and*are not visible to screen readers, find-in-page, or other tools. The reachability is a property of the HTML attribute, not the CSS property.\n\n## Why it matters\n\n`display: none`\n\nremoves content from the accessibility tree and from find-in-page entirely. Accordion or tab patterns that hide panels with`display: none`\n\nare invisible to a user who knows the exact phrase they want.- Find-in-page is a primary accessibility tool. Keyboard users, screen-reader users, users with cognitive disabilities, and anyone skimming a long document rely on it to locate content directly.\n- Search engines and AI crawlers vary in how they treat content hidden with\n`display: none`\n\n.`hidden=\"until-found\"`\n\nkeeps the text in the DOM and reachable, which is the honest signal: this is real content, just collapsed by default.\n\n## How to implement\n\nMark each collapsed panel and listen for `beforematch`\n\nso your widget state stays in sync:\n\n```\n<button aria-expanded=\"false\" aria-controls=\"panel-1\">Shipping</button>\n<div id=\"panel-1\" hidden=\"until-found\">\n  We ship worldwide within 48 hours…\n</div>\njs\nconst panel = document.getElementById('panel-1');\npanel.addEventListener('beforematch', () => {\n  const button = document.querySelector('[aria-controls=\"panel-1\"]');\n  button.setAttribute('aria-expanded', 'true');\n  // remove any matching collapsed class on the button or panel\n});\n```\n\n**Prefer <details>/<summary> where you can.** For the everyday “click a heading to expand a panel” pattern, the native disclosure element gives you focus management, keyboard handling, and find-in-page reachability with zero JavaScript. Reach for\n\n`hidden=\"until-found\"`\n\nwhen you need a custom widget that `<details>`\n\ncannot model — a search-driven FAQ, a complex tab strip, an off-screen mega-menu that must still be findable.## Common mistakes\n\n- Using\n`display: none`\n\non accordion panels and then wondering why users cannot find the content they remember reading. Switch the closed state to`hidden=\"until-found\"`\n\n. - Substituting\n`content-visibility: hidden`\n\nin author CSS as a “CSS equivalent” of the attribute. It is not — author-applied`content-visibility: hidden`\n\nhides content from find-in-page and screen readers in exactly the way the attribute is meant to avoid. - Using\n`hidden=\"until-found\"`\n\nfor content that should be permanently hidden — error messages, off-screen utility nodes, suppressed admin tools. Use plain`hidden`\n\nor`display: none`\n\ninstead. - Forgetting to update\n`aria-expanded`\n\nand the visual chevron state in the`beforematch`\n\nhandler. The panel opens but the button still claims it is collapsed. - Treating it as a layout primitive. The element still participates in DOM order and document outline — it is hidden, not removed.\n\n## Verification\n\n- Open the page in Chrome or Edge. Press Ctrl/Cmd+F and search for a phrase that lives inside a collapsed panel. The browser should auto-scroll and reveal it.\n- Repeat with a panel that uses\n`display: none`\n\n. The search should fail, confirming the regression you are avoiding. - Tab through the widget with a screen reader (VoiceOver, NVDA, JAWS) and confirm the panel announces correctly once expanded.\n- Inspect the element in DevTools after a match — the\n`hidden`\n\nattribute should be gone, the`beforematch`\n\nlistener should have fired, and`aria-expanded`\n\nshould read`true`\n\n.", "url": "https://wpnews.pro/news/hidden-until-found", "canonical_source": "https://specification.website/spec/accessibility/hidden-until-found/", "published_at": "2026-05-31 17:50:00+00:00", "updated_at": "2026-06-04 07:31:07.254820+00:00", "lang": "en", "topics": ["ai-tools", "ai-products"], "entities": [], "alternates": {"html": "https://wpnews.pro/news/hidden-until-found", "markdown": "https://wpnews.pro/news/hidden-until-found.md", "text": "https://wpnews.pro/news/hidden-until-found.txt", "jsonld": "https://wpnews.pro/news/hidden-until-found.jsonld"}}