Categories
HTML5 Specs

Remove the Hidden attribute

My change proposal for Issue 95 is about removing the hidden attribute[1]:

The HTML5 specification states the following about this attribute[2]:

All HTML elements may have the hidden content attribute set. The hidden attribute is a boolean attribute. When specified on an element, it indicates that the element is not yet, or is no longer, relevant. User agents should not render elements that have the hidden attribute specified…

The hidden attribute must not be used to hide content that could legitimately be shown in another presentation. For example, it is incorrect to use hidden to hide panels in a tabbed dialog, because the tabbed interface is merely a kind of overflow presentation — one could equally well just show all the form controls in one big page with a scrollbar. It is similarly incorrect to use this attribute to hide content just from one presentation — if something is marked hidden, it is hidden from all presentations, including, for instance, screen readers.

The hidden attribute section provides one example: a game screen is hidden until a person has logged in.

Rationales for Keeping the Attribute

The HTML5 editor, Ian Hickson, wrote the following rationale as reason for rejecting this change in the associated bug[3]

Rationale: hidden=”” is a key part of HTML5’s accessibility story and represents one of the main accessibility improvements over HTML4 for dynamic applications.

A counter-proposal has been provided to keep the attribute. The rational given is[4]:

Authors of web documents and applications often need to temporarily hide certain content from readers and users.

Via a combination of script and CSS, such functionality is possible to build today, and there are hundreds of such implementations extant on the web. It’s clear that hidden=”” Solves Real Problems.

Attempting to implement such functionality with JavaScript and CSS is fundamentally more difficult and error-prone than hidden=””. hidden=”” is literally the simplest thing that could possibly work, and thus we Avoid Needless Complexity in its design.

By making it as easy as possible to author, and by defining uniform UA behavior (unlike bolt-on scripts which emulate this functionality), we preserve our Priority of Constituencies.

Bolt-on emulations of hidden=”” can fail to correctly hide content in a media-independent way, resulting in a degraded experience for users of aural browsers and other AT tools. hidden=”” thus promotes Accessibility more than bolt-on alternatives.

In addition, the Accessibility TF discussed the change proposal[5], and among the benefits discussed were the following:

  • Not so strong on keeping the hidden attribute.
  • Hidden does what the ARIA equivalent does, and seems useful.
  • Could live without it given we will get it in aria.
  • It’s like display:none but without the nasty side effects.
  • It is slightly different from aria-hidden…
  • HTML5 hidden applies to ALL elements
  • Not sure this has an accessibility impact…
  • There is some impact (but not a lot).

The Accessibility Task Force also provided a general statement regarding this element and others:

RATIONALE: The F2F believes these elements are actually useful for accessibility. We note that features similar to the elements in question are today created using elements with different semantics actuated by style and script, whereas we prefer native elements.

Response

I took a best guess effort at summarizing the rationales for keeping the hidden attribute.

  • It provides accessibility support where none existed in HTML4
  • Implementing the hidden functionality with JavaScript and CSS is difficult and error-prone
  • It’s the simplest thing that can work
  • It works with all media
  • It is semantically meaningful

I say “best guess” at summarizing, because the discussion points from the Accessibility TF seem to indicate that some members of the discussion don’t think the hidden attribute is particularly useful.

I do agree with the counter proposals that the hidden attribute is easy to use. From the example in the specification—set the value to true, to hide the element’ contents, false, to display the contents—you can’t get a simpler attribute. I also agree that HTML4 did not have an equivalent functionality built into the specification. However, I do not agree with the other statements given.

The Existing Behavior with JavaScript and CSS, Media, and Simplicity

The HTML5 specifications defines the rendering for the hidden attribute to be equivalent to setting the element’s display property to “none”[6]. You’d get the same effect with the following code:

document.getElementById("elem").style.display="none";

Or the following code:

document.getElementById("elem").setAttribute("style","display:none");

As you would setting the hidden attribute:

document.getElementById("elem").hidden=true;

You could even absolutely, positively, completely ensure the accessibility of the effect, using the following:

[aria-hidden="true"]
{
   display: none;
}
...
document.getElementById("elem").setAttribute("aria-hidden","true");

If any user agents do render content when the element’s display property is set to “none”, it’s the fault of the user agent, not the CSS or aria-hidden attribute. If user agents have problems with display being set to “none”, they will continue to have problems with the hidden attribute because the two are equivalent.

As for simplicity, both approaches are again, exactly equivalent.

The Semantics of Irrelevance

The hidden attribute was once named the irrelevant attribute, supposedly because the attribute is used to mark the contents of whatever element it is attached as “irrelevant”. The attribute was renamed because, a) the irrelevant term was confusing, and b) techs misspell words like “irrelevant”.

Is the content truly irrelevant, though? Consider the definition for the attribute:

Elements in a section hidden by the hidden attribute are still active, e.g. scripts and form controls in such sections still execute and submit respectively. Only their presentation to the user changes.

An irrelevant element is not one that is active, receiving events, participating in the web page, or form submission. The only truly irrelevant page component is one that doesn’t exist. If people want a truly irrelevant page section, they should use the DOM to create and remove the element, as needed. There is nothing about the behavior associated with removing an element from user agent rendering that is made more meaningful using a single-purposed HTML attribute, rather than using a simple combination of CSS property and ARIA attribute. Both have to do with the presentation of the element.

Presentation with the hidden attribute isn’t an incidental purpose, it is the primary purpose of the attribute. Rather than separate presentation and structure, it firmly welds the two.

Accessibility

The hidden attribute is no more accessible than setting the element’s CSS display property to “none”, because the two are equivalent.

However, the hidden attribute can be detrimental to accessibility because there’s nothing in the HTML5 specification that describes the precedence of settings. The ARIA documentation states that ARIA settings, such as aria-hidden, take precedence over settings such as display=”none”. Does the aria-hidden attribute have precedence, then, over the hidden attribute? How about when hidden is set to true, but a CSS stylesheet sets the display property of the element to “block”?

Introducing hidden introduces a redundancy, yet the documentation for hidden does not take such redundancy into account when defining the attribute.

Costs

The costs for an attribute such as hidden, are not as high as a more complex object, such as the details element. However, there are costs. Lint tools and validators now have to ensure conforming use of the attribute, HTML editing tools and WYSIWYG applications have to incorporate the new functionality, libraries have to be modified, books updated, design themes modified, and so on.

Web developers and designers have to spend time trying to figure out when to use CSS, and when to use the hidden attribute. I can imagine the many discussions about ‘irrelevant” content, and what does “irrelevant” mean in one context or another. It is an esoteric concept, and as such adds unnecessary complexity.

If the attribute provided something useful, it might be worth the costs. However, the hidden attribute provides absolutely nothing that we don’t already have.