The hidden attribute in HTML

by Ahmad El-Alfy published on

The hidden attribute allows us to hide HTML elements from the page. When it was introduced, it worked in a very simple way: it set the CSS display property to none.

Many people voiced concerns because here we are, mixing styles with markup again. To be fair, this was at a time before the rise of frameworks and the change in people's mindsets where separation of concern became a less debatable issue. There were also others who opposed the attribute because it can be easily overridden by CSS. A solution to avoid hidden elements from showing unintentionally is adding this snippet to your stylesheet to ensure it overrides other rules used on the same element.

[hidden] {
display: none !important;

There are differing opinions on using the !important declaration, as some authors considered it code smell. Later, the use of !important in utility classes became more accepted.

A modern way to mitigate the use of !important is the use of CSS Cascade Layers. CSS layers is implemented by using the @layer directive, allowing us to define specific layers for our styles. This allow us to control the specificity and ordering of the CSS rules without resorting to !important. This approach promotes a more maintainable and scalable codebase, reducing the reliance on !important declarations and making it easier to manage styles across different components and elements. All we need to do is to add the previous snippet in the utility layer and moving that layer to be the last. This way we can ensure that their styles take precedence without the need for !important.

Let's take an example where we need to toggle the display of an element. We can do that by setting its display property to none using JavaScript and inline CSS. This is a common approach that many follow to hide an element instantly. To show the element again we can change the display back to whatever value we want.

// Hide the element = 'none';

// Show the element again by setting the display to another value = 'block';

The problem with setting the display to something other than none is that we could be dealing with an element that has different display values according to the media size for example (e.g. block, flex ... etc). In that case, setting it to a specific value can introduce some troubles if the display types don't match.

Another approach would be to use the removeProperty method, available on the elements style property, which removes specific inline styles.

// Show the element again by removing the inline declared property'display');

One argument in favor of the hidden attribute is its semantic value. It clearly indicates that an element using the attribute is intended to be hidden from display. Another argument is that we can hide content in HTML without needing CSS. So without having to set inline styles, we can add and remove the attribute on the element as we want.

// Hide the element
el.hidden = true;
// We can also use addAttribute
el.setAttribute('hidden', '');

// Show the element
el.hidden = false;
// We cal also use removeAttribute

The future of hidden attribute

Initially, the hidden attribute was considered a boolean attribute. If the attribute was present on an HTML element, it would be effective regardless of its value:

<div hidden>This element will be hidden</div>
<div hidden="hidden">This element is also hidden</div>
<div hidden="false">This one is hidden as well</div>

The specification has changed recently, and the hidden attribute is now an enumerated attribute. This means it can have specific named values. The new value introduced in the specification is until-found, which triggers a new state called the "Until Found" state.

If the hidden attribute is present without a value, or with any value other than until-found, it will behave as it did before. However, if the value is until-found, the element will be in the "Until Found" state. In this state, the element will be hidden until it is found by the user agent.

The hidden until found state

The hidden until found state was created to solve a common problem. Let's look at tabs and accordions for example. These UI components contain elements that are undiscoverable until a certain action is done (e.g clicking a button). This makes the content unavailable to screen readers, search engines, and the built-in find-in-page feature in browsers.

Unlike the standard "hidden" state, which completely hides the content by setting its display property to none, the "hidden until found" state uses the content-visibility property to hide content while still making it discoverable by search engines, find-in-page functionality, and linking. Consider the following example (currently only supported in Chrome and Edge).

In this example, try using the browser's search feature (find-in-page) and type the word "banana." After the first result is highlighted, attempting to navigate to the next result will reveal the "Introduction" section. Following that, the subsequent sections will become visible in sequence. Note that after an element is revealed, the attribute is removed keeping the element visible. Clicking the "Reset Display" button will hide the sections again, enabling you to retry the process. Additionally, clicking any of the links will automatically display the corresponding sections.

Note that this example doesn't rely on JavaScript, except for the functionality used to reset the display. Instead, the behavior is achieved purely with HTML. As the corresponding sections are "found," the hidden attribute is automatically removed from the elements, triggering their visibility.

Browser support

Presently, this functionality is accessible in Chrome and Edge. While Firefox has expressed an intention to incorporate it, there are no indications of similar developments from Safari yet. Currently, the feature is marked as "Experimental," indicating that its functionality may undergo changes in the future.

Wrapping up

The anticipated enhancements to the hidden attribute are poised to positively influence and enhance the user experience for those utilizing the find-in-page feature in browsers. The behavior showcased in this demo by Joey Arhar aligns with our expectations when searching for keywords that match content on a page, reinforcing the potential benefits of these improvements.


Special thanks

Many thanks to Saptak Sengupta and Eric Bailey for their invaluable reviews of this post; their insightful feedback greatly enhanced the final result. A special acknowledgment goes to Manuel Matuzovic for accepting my contribution to this year's Advent calendar and his patient support until I completed this blog. Thanks for offering a platform where we can share our thoughts and discussions about HTML.

About Ahmad El-Alfy

Ahmad El-Alfy is a dedicated frontend developer with 15 years of experience in the web development field. He holds a genuine enthusiasm for Web Standards and Accessibility, as well as a keen interest in the ongoing developments within the web platform. He recently became a Google Developer Expert in Web Technologies.