Warning:
This wiki has been archived and is now read-only.

Correct Hidden Attribute Section v2

From HTML WG Wiki
Jump to: navigation, search


Correct the hidden Attribute Section

Summary

Authors sometimes want to provide a label or description to users of Assistive Technology, and to do so without any visual encumbrance or default visual indicator. They can already do this with CSS display:none and visibility:hidden, and should be able to do the same with the simpler @hidden attribute. The ARIA spec allows aria-describedby and aria-labelledby to reference hidden elements, so this change will correct the hidden attribute sectionto bring it into conformance with the ARIA specification and ARIA functionality. In addition, this would make the behavior of @hidden consistent with the long-implemented behavior of CSS display:none and visibility:hidden with HTML <label> and aria-labelledby.

Rationale

Use Cases

Web authors often wish to provide a description of a complex element only to screen reader users, while hiding the description from all other users. Being able to provide such a description without any forced visual encumbrance or default visual indicator is a frequently-cited accessibility requirement.

Example 1

Consider the following markup:

<pre role=img aria-describedby=foo >
  )\._.,--....,'``.    fL
 /,   _.. \   _\  ;`._ ,.
`._.-(,_..'--(,_..'`-.;.'
</pre>
<p id=foo hidden>An ASCII art rendition of a cat in prone position.</p>

This example contains an ASCII art rendition of a cat inside a <pre> element. A description of the art is provided for AT users. By using aria-describedby to point at a @hidden element, the web page author avoids any forced visual encumbrance or default visual indicator.

Example 2

<input aria-labelledby="foo" type=text><input type=image src="search.png" alt="Go!">
<div id="foo" hidden>Search</div>

In this example, a short plain-text string is used to label the text input, and that label is hidden from view. For visual users, the text box followed by a looking glass icon is a well-known visual pattern for a search function. The hidden label makes this clear to users who cannot see the text box or graphic.

Example 3

 <input aria-labelledby="foo" type="text" onmouseover="showFoo();" onmouseout="hideFoo();">
 <input src="go.gif" type="image" alt="Go!">
 <div id="foo" hidden><img src="decorative-image.gif" alt="">Search</div>

This example shows a variation of Example 2 where the label has a decorative image, and is shown to visual users onmouseover. Since the image gives no real information, it has null alt text. The hidden label is used to give the screen-reader user more information via the accessibility API, so that he does not need to navigate to the tooltip. The accessible name in the accessibility API tells him exactly what that text is for, where a popup tooltip would require more cognitive overhead. However, the popup tooltip, with it's pretty graphic, is shown to improve the experience of signted users who are exploring the input. Since the screen-reader user does not use a mouse, and does not trigger the mouseover, he gets an experience that works for him, and the sighted user gets one that works for her. (Caveat: This is not a great piece of UI design for exploring an input by a sighted user. It is offerred as a simple example of where one might want to flatten the text for some users.)

The @hidden attribute is a mechanism for hiding elements in HTML. Given this, authors are likely to use it to hide content. The WAI-ARIA specification allows aria-describedby to point at non-visible content, so it is reasonable for authors to expect such markup to function properly. Because authors rarely run their content through conformance checkers, authors are likely to point at @hidden content from aria-describedby whether or not we forbid them from doing so. Therefore it is incumbant to document what can, and what cannot be achieved through these techniques.

Feedback from Browser Implementers

Two people working for browser implementers have suggested that exposing hidden elements in the accessibility tree is feasible, and similar to the work already under way to expose hidden child elements of the <canvas> element:

I don't think Apple has a strong stance either way on using @aria-describedby to point to @hidden elements, but I believe we could reasonably expose full semantics of hidden content pointed to by aria-describedby, this is more or less the same as the work we'd have to do to expose <canvas> children as an accessible tree.

Maciej Stachowiak, Apple

In addition, this is the behavior that is specified for @aria-describedby in the ARIA User Agent Accessibility Guidelines (see below), and it is currently implemented in Safari.

In firefox, the reason that @hidden elements are "stringified" when

exposed through aria-describedby is because they don't have CSS boxes. This is also why we have problems currently when exposing the contents of a <canvas>. In both cases the accessibility code "fails" because it tries to use the CSS boxes which aren't there. Hence the fallback to

stringify.


Exposing the rich semantics of contents inside a <canvas> in Firefox

will take a lot more than changing what object <canvas> inherits from. Whatever solution we come up with for that can hopefully be reused to expose the rich contents of @hidden elements exposed through

aria-describedby.


We now have two implementations which say that exposing the rich

contents of @hidden elements pointed to using aria-describedby is

implementable. And is implementable without changes from AT vendors.

Jonas Sicking, Mozilla

There are similar constructs in Internet Explorer. For example, an aria-labelledby that references an element with CSS visibility:hidden or display:none will populate the accessible name for that element in IE9. Similarly, the accessible name of an input element will be populated with the text of it's associated label element, even if that label element is hidden with CSS visibility:hidden or display:none. This has been true in IE since IE 5 or 6. Having @hidden behave differently sets up a confusing situation for developers of both web applications and assistive technologies.

Compatibility and interoperability with ARIA 1.0

As Richard Schwerdtfeger succinctly stated on April 9, 2012,

The HTML 5 reference to aria-describedby is inaccurate as hidden text is loaded into the accessible description string in an accessible object even though no accessible object representing the text description is exposed in the accessibility API.

Because of how APIs work, any hidden content referenced by an ARIA attribute is rendered as a plain-text string. The ARIA Can Only Refer To Hidden Content With Specific Restrictions change proposal explains this in detail:

The issue of whether or not hidden content could be referenced by ARIA attributes has actually been discussed by the ARIA Working Group, as recently as March 2012.

The outcome of the ARIA WG's latest discussions has resulted in changes to the Draft ARIA Implementation Guide which speaks specifically to this Issue:

5.1.2. Excluding Elements from the Accessibility Tree

The following elements are not exposed via the accessibility API and user agents MUST NOT include them in the accessibility tree

  • Elements, including their descendents, that have host language semantics specifying that the element is hidden, such as CSS display:none or visibility:hidden or HTML 5 hidden attribute.

The net effect of this is that any hidden content referenced by an ARIA attribute will be left to render as string text only, as it is forbidden by ARIA Processing rules, as well as the various Accessibility APIs (AAPIs), to take on any other role...

For this reason, any text that is hidden but referenced by an ARIA attribute will have limited, but not zero, value to screen reader users with AAPI aware tools.

So, to the question of "Should HTML5 permit ARIA attributes to reference (point to) content that is hidden from the visual view-port of sighted users?" the answer is, it already can.

UAIG says that hidden elements are not exposed via the accessibility API, and this may be the cause of confusion. The intention was to forbid hidden elements from being exposed *as separate accessibility objects in the accessibility api object tree*. This was not intended to forbid mapping text from hidden objects to properties of other objects in the accessibility api tree. We will add an issue to UIAG to add a note to this effect.

However, section 5.6.1.3. Text Alternative Computation of UIAG states explicitly that authors can provide plain-text strings for the accessible name and description via aria references to hidden elements, and that browsers are to process them as plain-text strings for these fields.

1.Skip hidden elements unless the author specifies to use them via an aria-labelledby or aria-describedby being used in the current computation. By default, users of assistive technologies won't receive the hidden information, but an author will be able to explicitly override that and include the hidden text alternative as part of the label string sent to the accessibility API.

In addtion, UAIG Section 5.5.1. State and Property Mapping Table describes the use of aria-describedby and aria-labelledby in name and description calculation, and makes no mention of special treatment based on hidden state.

WAI-ARIA State or Property

MSAA UIA Express

MSAA IAccessible2

UIA

ATK/AT-SPI

Mac OS X

aria-describedby

Use in calculating the accessible Description as described in [#mapping_additional_nd Name Computation]. Expose in accDescription property.

Use in calculating the accessible Description as described in [#mapping_additional_nd Name Computation]. Expose in accDescription property.

If the object is in the accessibility tree, expose pointer to the accessible object in IA2_RELATION_DESCRIBED_BY

Expose reverse relations as described in [#mapping_additional_relations Relations].

Use in calculating the accessible Description as described in Name Computation.

Expose pointer to the accessible object in DescribedBy property.

Use in calculating the accessible Description as described in Name Computation. Expose pointer to the accessible object in RELATION_DESCRIBED_BY

Expose reverse relations as described in [#mapping_additional_relations Relations].

Use in calculating the accessible Description as described in Name Computation. Expose in string AXDescription (reserved for non-visible accessible name or calculated description)

aria-labelledby

Use in calculating the accessible name as described in Name Computation. Expose in accName property.

Use in calculating the accessible name as described in Name Computation. Expose in accName property.

Expose a reference to the accessible object in IA2_RELATION_LABELLED_BY

Expose reverse relations as described in [#mapping_additional_relations Relations].

Use in calculating the accessible name as described in Name Computation. Expose in Name property.

Expose a reference to the accessible object in the LabeledBy property.

Use in calculating the accessible name as described in Name Computation.

Expose a reference to the accessible object in RELATION_LABELLED_BY

Expose reverse relations as described in [#mapping_additional_relations Relations].

Use in calculating the accessible name as described in [#mapping_additional_nd Name Computation]. Expose in string AXTitle (reserved for visible name)

Accessibility API mappings

When aria-labelledby and aria-describedby reference an element that IS NOT hidden, the following things happen:

  1. An Accessible Object is created in the Accessibility API tree for both the referencing and the referenced elements.
  2. In APIs that support such relationships, a relationship is created with bi-directional pointers between the objects. This can be used by AT products to find the referenced element and navigate to it.
  3. A DOM relationship is created between the referencing and referenced elements. DOM-based AT products, or browsers themselves, can use this to build UI that allows users to navigate to the description.
  4. The text of the referenced element is used in Name Calculation
  5. the AriaProperties or ObjectAttributes are populated with the string aria-describedby=IDREF or aria-labelledby=IDREF, where IDREF is the ID of the referenced element.

When aria-labelledby and aria-describedby reference an element that IS hidden, the following things happen:

  1. The text of the referenced element is used in Name Calculation
  2. the AriaProperties or ObjectAttributes are populated with the string aria-describedby=IDREF or aria-labelledby=IDREF, where IDREF is the ID of the referenced element.

Name calculation is what is at issue in this CP. It happens whether the referenced items are hidden or not. When the referenced items are hidden, then the relationships for navigation are not created. Again, this is ALREADY TRUE for CSS display:none and visibility:hidden, and has been true in browser implementation for years.

The structure of the referenced element is flattened in name calculation because properties where it is placed are of type string. In MSAA, for example, each accessible object is a COM object with properties of type string for the name and description. For more information, see the MSDN documentation for IAccessible, the AccDescription property, and the AccName property.

Details

Remove

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.

Elements that are not hidden should not link to or refer to elements that are hidden.

For example, it would be incorrect to use the href attribute to link to a section marked with the hidden attribute. If the content is not applicable or relevant, then there is no reason to link to it.

It would similarly be incorrect to use the ARIA aria-describedby attribute to refer to descriptions that are themselves hidden. Hiding a section means that it is not applicable or relevant to anyone at the current time, so clearly it cannot be a valid description of content the user can interact with.

Add

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, visible or interactive. User agents should not render elements that have the hidden attribute specified. User agents should not create accessible objects in the platform accessibility API tree for elements that have the hidden attribute specified. User agents should use the text-children of the hidden element to create a plain-text string, and use that string to fill in name and description properties in the objects created for the referring element, which does not have the hidden attribute specified. Note that it is not possible to store complex markup structures in these API properties, which are typed for plain-text strings. See the HTML to Platform Accessibility APIs Implementation Guide for more details.

Elements that are not themselves hidden must not hyperlink to elements that are hidden. Aria-flowto and aria-owns attributes on elements that are not themselves hidden, similarly, must not reference hidden elements.

For example, it would be incorrect to use the href attribute to link to a section marked with the hidden attribute. Since the content is not rendered, linking to it would result in behavior the user does not expect, either dropping the user at a location with no rendered content, or failing to navigate.

However, hidden elements may be used to provide descriptive plain text if such flattened content provides a good user experience by using aria-describedby and aria-labelledby and HTML labelling elements such as <label>, <legend>, <caption>, and <figcaption>. This technique should not be used for longer content that has structured text (e.g., headings, anchors, list markup, table markup, etc.), as accessible name and description calculation [WAI-ARIA] will flatten the referenced elements to plain text, losing interactivity and semantic structure.

<p class="note"\>Note hidden labels and descriptions will not be exposed as objects in the accessibility tree, but may be used as part of accessible name and description calculation [WAI-ARIA]. Note the calculation will flatten the labelling and describing elements to plain text strings, losing interactivity and semantic structure. Authors must only use hidden labels and descriptions to label and describe elements when the calculated plain text strings are appropriate accessible names or descriptions.

For example the following would conform to this particular requirement because although <label> includes a sub-element, it still flattens to an appropriate accessible name for the <input>.</p>

  <input id=f type=checkbox checked>
  <label hidden for=f>
    I do <strong>not</strong> want to receive marketing materials.
  </label>


<p class="note">Additionally at the time of this writing, some screen reader products will read both the accessible name and accessible description, so authors should take care with the length of text provided via this method.</p>

Remove

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.

Impact

Positive Effects

  • Makes the behavior of references from aria-describedby to elements with the @hidden attribute consistent with long-implemented browser behavior for references to content hidden with CSS display:none and visibility:hidden using <label> and aria-labelledby. This is a good example of documenting the web as it is.
  • Provides a simple, consistent way for UAs to hide content from sighted users while exposing it to AT via the accessibiltiy API.
  • Allows authors to provide in-place information to AT users in scenarios where doing so provides the best user experience.
  • Has no impact on scenarios where navigating to another location for additional information provides the best user experience.
  • Provides an intuitive way for authors to hide content from sighted users. If you want your description to not be visible, put a hidden attribute on it, just like other contents that you don't want to be visible by default.
  • Corrects the HTML5 specification with what in reality, ARIA actually says and does.
  • Authors are told to not use a technique that does not work, e.g., hidden cannot support HTML-rich, structured content such as headings, paragraphs, list markup, table markup, anchor text, or inline content (such as <span>).

Negative Effects

  • See Risks.

Conformance Classes Changes

  • No change.

Risks

  • Some authors will misunderstand the limitations of what can be achieved using ARIA, and will point aria-describedby to hidden structured text. Browsers will flatten that structure to a string and populate the accessible name and description fields in the accessibiltiy API, which can cause a poor user experience for screen reader users. There have not been many reports of problems with this the exisiting <label> and aria-labelledby functionality with CSS display:none and visibility:hidden, but since descriptions are often longer, it may be more of a problem with descriptions.

References