The hidden Attribute
The hidden Attribute
Section titled “The hidden Attribute”The hidden attribute indicates that an element is not yet, or is no longer, relevant. Hidden elements are removed from the rendering and the accessibility tree, making them completely invisible to both visual users and assistive technologies.
Syntax
Section titled “Syntax”<element hidden>Content</element><element hidden="hidden">Content</element><element hidden="until-found">Content</element>Values
Section titled “Values”| Value | Description |
|---|---|
| Boolean (no value) | Element is completely hidden |
"hidden" | Same as boolean (explicitly hidden) |
"until-found" | Hidden but findable with browser’s find-in-page |
Examples
Section titled “Examples”Basic Hidden Elements
Section titled “Basic Hidden Elements”Hidden Until Found (New Feature)
Section titled “Hidden Until Found (New Feature)”Hidden vs CSS Display
Section titled “Hidden vs CSS Display”Dynamic Show/Hide Pattern
Section titled “Dynamic Show/Hide Pattern”How It Works
Section titled “How It Works”HTML Behavior
Section titled “HTML Behavior”The hidden attribute is implemented in browsers as:
[hidden] { display: none !important;}This means:
- Element is not rendered
- Takes no space in layout
- Not in accessibility tree
- Can be overridden by CSS with higher specificity
Semantic Meaning
Section titled “Semantic Meaning”hidden indicates irrelevance, not just invisibility:
<!-- Good: Content not currently relevant --><div hidden> <p>This feature is not available in your region.</p></div>
<!-- Bad: Just styling (use CSS instead) --><div hidden> <p>Fancy animation that will show later</p></div>hidden vs CSS Display
Section titled “hidden vs CSS Display”When to Use hidden Attribute
Section titled “When to Use hidden Attribute”✓ Semantic hiding: Content is irrelevant to current context ✓ Programmatic control: Show/hide based on application state ✓ Accessibility: Remove from accessibility tree ✓ Progressive enhancement: Works without CSS
<article> <h2>Article Title</h2> <p>Preview text...</p> <div hidden> <p>Full article content that requires login...</p> </div></article>When to Use CSS display: none
Section titled “When to Use CSS display: none”✓ Styling decisions: Responsive design, animations
✓ Reusable classes: .hidden, .mobile-only
✓ Complex selectors: :hover, :focus, media queries
/* Responsive hiding */@media (max-width: 768px) { .desktop-only { display: none; }}
/* Interactive hiding */.dropdown-menu { display: none;}.dropdown:hover .dropdown-menu { display: block;}The until-found Value
Section titled “The until-found Value”How until-found Works
Section titled “How until-found Works”- Content is hidden initially
- User searches with Ctrl+F (Cmd+F)
- Browser finds matching text
- Element is automatically revealed
beforematchevent is fired
<div hidden="until-found"> <h2>Secret Section</h2> <p>This content is hidden but searchable!</p></div>
<script> document.querySelector('[hidden="until-found"]') .addEventListener('beforematch', (e) => { console.log('Content revealed by search!'); // You can style the revealed content e.target.style.borderColor = '#3b82f6'; });</script>Use Cases for until-found
Section titled “Use Cases for until-found”- Long documentation: Hide advanced sections
- FAQ pages: Initially collapse answers
- Search-optimized content: Allow users to find hidden content
- Progressive disclosure: Show content when needed
Best Practices
Section titled “Best Practices”1. Use for Semantic Hiding
Section titled “1. Use for Semantic Hiding”<!-- Good: Indicates irrelevance --><div hidden> <p>This feature requires Premium subscription</p></div>
<!-- Bad: Just for styling --><div hidden class="will-animate-in"> <p>Welcome message</p></div>2. Don’t Rely on hidden for Security
Section titled “2. Don’t Rely on hidden for Security”<!-- DON'T DO THIS --><div hidden> <p>Admin API Key: sk_live_abc123...</p></div>3. Combine with ARIA for Accessibility
Section titled “3. Combine with ARIA for Accessibility”<button aria-expanded="false" aria-controls="details" onclick="toggle()"> Show Details</button>
<div id="details" hidden> <p>Additional information...</p></div>
<script> function toggle() { const details = document.getElementById('details'); const button = event.target; const isHidden = details.hasAttribute('hidden');
if (isHidden) { details.removeAttribute('hidden'); button.setAttribute('aria-expanded', 'true'); } else { details.hidden = true; button.setAttribute('aria-expanded', 'false'); } }</script>4. Prefer hidden Over display: none for Conditional Content
Section titled “4. Prefer hidden Over display: none for Conditional Content”// Good: Semantic and clearif (user.isLoggedIn) { loginButton.hidden = true; logoutButton.hidden = false;}
// Also good: CSS classesif (user.isLoggedIn) { loginButton.classList.add('hidden'); logoutButton.classList.remove('hidden');}5. Test Accessibility
Section titled “5. Test Accessibility”Hidden elements should not be:
- Focusable with keyboard
- Announced by screen readers
- Navigable with Tab key
// Verify element is truly hiddenconst el = document.getElementById('hidden-element');console.log(el.hidden); // trueconsole.log(getComputedStyle(el).display); // "none"JavaScript API
Section titled “JavaScript API”Setting and Removing
Section titled “Setting and Removing”const element = document.getElementById('myElement');
// Set hiddenelement.hidden = true;element.setAttribute('hidden', '');element.toggleAttribute('hidden');
// Remove hiddenelement.hidden = false;element.removeAttribute('hidden');
// Check if hiddenif (element.hidden) { console.log('Element is hidden');}until-found with JavaScript
Section titled “until-found with JavaScript”// Set until-foundelement.setAttribute('hidden', 'until-found');
// Listen for revealelement.addEventListener('beforematch', (event) => { console.log('Element revealed!'); // Element is automatically shown by browser});Accessibility Considerations
Section titled “Accessibility Considerations”Screen Readers
Section titled “Screen Readers”Hidden elements are:
- Not announced by screen readers
- Not in the accessibility tree
- Not navigable with screen reader shortcuts
<!-- Not accessible to screen readers --><div hidden> <button>Click me</button></div>Alternative Accessibility Hiding
Section titled “Alternative Accessibility Hiding”If you need to hide visually but keep accessible:
/* Visually hidden but screen reader accessible */.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0;}<button> <span class="sr-only">Close dialog</span> <span aria-hidden="true">×</span></button>Common Pitfalls
Section titled “Common Pitfalls”Browser Support
Section titled “Browser Support”| Feature | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
hidden (boolean) | 6+ | 4+ | 5.1+ | 12+ |
hidden="until-found" | 102+ | 🚫 | 🚫 | 102+ |
beforematch event | 102+ | 🚫 | 🚫 | 102+ |
Related Attributes
Section titled “Related Attributes”aria-hidden- Hide from screen readers only (element still visible)inert- Make element non-interactive but visiblearia-expanded- Indicate if controlled content is expanded