As you may or may not have heard, Firefox 49 supports the HTML5 <details> and <summary> elements. Both full keyboard support and support for assistive technologies is also available right from the start.

What are they?

<details> and <summary> allow to dynamically show and hide blocks of content. For example, when composing a list of frequently asked questions, each question could be wrapped in an details-summary-block, with the summary being the question, and the details following in the rest of the details block. The user can then show and hide the details by just clicking or pressing on the summary content.

Previously, to achieve the same goal, web developers would have had to use a <button> element and bind some JavaScript to it that would show or hide some other adjacent block of text by modifying certain CSS properties. And as things go, these turned out to not always be accessible. Either developers used a clickable <div> or <span> element without proper keyboard support, or forgot to add the proper WAI-ARIA semantics, or both, turning these kinds of dynamic content into a challenge.

Well, no more, as the HTML5 specification addresses these issues with the <details> and <summary> elements.

An example

This can be very easily demonstrated. Navigate to the below heading, which is going to be announced by screen readers as a button, with a collapsed state, and then press Space, or use the mouse or your finger (when on a touch screen) to click or press on it. Then, the button will change to an expanded one, and there will be another new paragraph below that heading. You can press on the button again to collapse that paragraph again and make it disappear.

Press me to show what I’m wearing underneath

Hahah, thought you’d find something naughty here, eh? Well, sorry to disappoint, it’s just a silly rambling of mine. Go ahead and go back up to close me again.


The code for this is pasted below.

<details><summary><h3>Press me to show what I'm wearing underneath</h3></summary>
<p>Hahah, thought you'd find something naughty here, eh? Well, sorry to disappoint, it's just a silly rambling of mine. Go ahead and go back up to close me again.</p></details>

The content inside the <details> element can be all kinds of elements like lists, tables, sub headings if need be etc. Just remember to keep the proper heading structure when you do it. The fact that I used a heading up there is totally optional, too. It just fits in the heading structure of the blog.


Hope these elements will now help to create more accessible collapsible content blocks! Other browsers like Chrome and Safari also support these elements, and we’re hoping that Microsoft Edge will follow lead soon as well!


Also on:

Over the weekend, I gave a presentation at the German Multimediatreff. I talked about how to make things more accessible by combining HTML5 and WAI-ARIA in smart ways, using HTML5 where available and appropriate, and enhancing the user experience where HTML5 still has gaps in the implementation. This is a recap of what I showed.

The premise

The base for my talk is my third easy ARIA tip, where I enhanced a form with some basic local form validation to help users fill it out and avoid errors upon submission. If you are not or no longer familiar with what I did there, stop reading here and go read that post again as a recap. If you are caught up, let’s move on!


Since then, a lot of time has passed, and we’re now much better equipped with native markup magic that HTML5 supplies us. Thankfully, Firefox and also other browsers implement most, if not all, these features now, so we can move ahead with our changes. To remind you, WAI-ARIA is there to enhance, not substitute, native markup, so whereever possible, we should use native markup when available. These changes are:

  1. Strip all JavaScript: Let’s start clean and see how far the new native markup stuff gets us!
  2. Throw out all aria-required="true" instances and replace them with the HTML5 required attribute. This gives us automatic flagging of a required field not only via accessibility APIs, but also through visual indicators. Also, a required field is automatically flagged as invalid if it is empty.
  3. For the field ‘name’, add a pattern attribute containing a regular expression that defines a valid name consist of some characters, one space, and some more characters. This will cover most cases, and if you’d like something more complex, consider me giving you some homework. 😉
  4. The field “email” gets the type “email”, the field “website” gets the type “url” set. This gives us proper validation of e-mail addresses and URLs respectively right upon entry. Moreover, on mobile devices with a virtual keyboard, the most common extra keys are usually provided right out of the box.

In addition, for a better error message, I am using the non-standard x-moz-errormessage attribute on the “name” field to tell users that the name was entered wrong rather than the standard “patterns don’t match” error message the browsers usually throw at users in the instance of them having entered a wrong value.

In addition, the name field contains (already in the ARIA example) a title attribute that tells users that a name must consist of at least two words.

Filling out this form now gives us validation upon submission. Firefox sets focus back to any invalid field it finds when users press the “submit” button. In addition, an error message is displayed describing the problem.

…and back

Our original example, however, was better in that it provided validation right at the point when an entry lost focus. Since this is a dynamically created alert box that is not yet a native HTML5 element, we have to resort to WAI-ARIA again to make this work the same, but using the HTML5 validation benefits. So, let’s enhance our example:

  1. Bring back the first two functions from the original ARIA version unchanged. These remove any existing alert box, and they create a new alert with the given message.
  2. Adjust the function that is called in the onblur handler of the “name” and “email” fields (see below):
    1. First, we have to adjust the function name to something that doesn’t clash with a reserved word. I used testIfEntryIsValid.
    2. Now, get rid of the search string and error message parameters. These are no longer needed because the validation is done by the browser, and we simply use the HTML5 form constraints API to ask the browser for the relevant info. Also, the browser provides us with the appropriate error message, so no need to generate one ourselves here.
    3. In the if clause, simply ask if the call to the checkValidity() method of the element we obtained in the line above gives us a “true” or “false” result. If true, simply remove the old alert. If false, create an alert and use the element’s validationMessage property as the message parameter. The browser will handle the rest for us.
    4. Remove the lines that set aria-invalid. These are no longer needed, since the browser’s constraint validation will provide the invalid or valid states automatically.
  3. For the “name” and “email” fields, add back onblur handlers pointing to the above function and simply pass in the field’s ID.

Testing this example, it shows that we’ve got our original functionality back. In addition, if we ignore the intermediate error messages, the browser’s validation mechanism will throw us back to any of the wrongly filled out fields upon a submission attempt. Note that not all browsers do this last step. Safari on the Mac, for example, will submit the form even if it contains invalid entries.

In summary

The new version of our form is much improved over the version we had originally. It still contains some WAI-ARIA where it makes sense, since there is no native HTML5 alert box yet. But the rest is HTML5. The JavaScript code is a bit less bloated since we don’t have to do our own validation any more, and we benefit from all the builtin constraint validation mechanisms.

Feedback is welcome! But before you throw things at me for my sloppy JavaScript, please keep in mind that this is just a proof of concept. If you would like to re-use this technique, I encourage you to put your best knowledge to use and put in better handling of events or such, appropriate for your web application. 🙂

The example pages can be found (in English and German) at this address. Happy hacking!