The details and summary elements

How often have you had to write some JavaScript to create an interactive widget that shows and hides some content? You might’ve even downloaded a whole JavaScript library to achieve such an effect. Well, it’s time writing service to rejoice! HTML5 provides a way to create this toggle feature with just a few lines of HTML and no JavaScript in sight (depending on the browser, of course, but we’ll come to that later). And so we introduce to you the <details> element.
Here is what the spec has to say about <details>:

The details element represents a disclosure widget from which the user can obtain additional information or controls.
— W3C HTML specification

Essentially, we can use <details> to create an accordion-like widget that the user can toggle open and closed. Inside <details>, we can put any sort of content we want.

Browser support

Before we go any further, you should know that currently, only Chrome supports the <details> element. Opera will support it soon, but in the meantime we’ll have to use some polyfills. So fire up Chrome and let’s take a peek.

Using <details>

There are two relevant elements here: <details> and, optionally, <summary>. <details> is the wrapper for all the content we want to show and hide, and <summary> contains the — well, the summary and title of the section. Technically we don’t need the <summary>. If absent, the browser will use some default text (in Chrome: “details”). Let’s have a look at some markup:

There is no closed attribute. It’s the default, so by omitting open, you imply closed.

The <summary> element

We’ve briefly seen <summary> in action. Since it is phrasing content, we can use inline elements such as <span> or <strong> inside it. Why thought would we do this? Perhaps for an extra styling hook or as the spec suggests: a label for a form element. At least it would be handy if it worked properly when implemented:

Normally, clicking anywhere on the summary reveals the content of the <details> element. But in this example, clicking the summary doesn’t reveal the content because you’re actually clicking the <label>, which then focuses the <input> element — even though it’s hidden by the collapsed <details> element.
Clearly this needs addressing, what do you think should happen? Maybe any browser vendors reading this can take a look :)

Example uses

So when could you use <details>? FAQs immediately spring to mind. People often use accordions for FAQs anyway, so they’re a great candidate for <details>.
Also consider a table of contents. It could be a fixed area that scrolls with the content. Something like this perhaps?
You could use <details> to toggle the comments section of a blog, member profiles, details of a download, complex forms, or in web applications as shown in this example from the spec:
An example of the <details> element from the specIn fact, just looking around WordPress as I write, I see plenty of opportunities to use <details>. Let us know your thoughts and ideas in the comments.

Styling

How can we style this thing? Well, to style the disclosure widget itself in WebKit, you can apply some CSS to the pseudo-class ::-webkit-details-marker. You can see a little demo here:

We can also position the disclosure widget (to an extent). Here it is floated right. That’s about all we have initially.
So how do we replace the disclosure widget with a custom icon? Using an attribute selector, you can detect whether the <details> element is open or closed and apply an appropriate background image. We do something similar in this example, except that instead of using a background image, we use the :after pseudo-element:

The above example uses literal “+” and “-” characters as the disclosure widget. Depending on your styling, you might need to use :before instead of :after, but both pseudo-elements allow using an image.
The details[open] attribute selector creates some interesting possibilities. And because we’re nice doctors, here’s a more polished example as seen in the screenshot below:
Styled <details> element in ChromeIt would be interesting (though not necessarily good design) if you could use CSS transitions to animate the <details> opening and closing, but we can’t just yet.

Accessibility

Unfortunately, at the time of writing, <details> is not accessible via the keyboard. Steve Faulkner writes:

Bottom line is, currently no keyboard support and no usable information exposed to assistive technology.

Try it yourself. If you open a <details> element with your mouse, you can then keyboard through the content, but you should also be able to toggle the details open and shut with the keyboard. So it’s not ideal, but I’m sure the Chrome developers will sort this out soon (won’t you guys?).

Fallbacks

Before anyone exclaims that it doesn’t work in IE6, we know. Thanks to some clever people, we can provide elegant fallbacks though. As listed in this very handy collection of cross-browser polyfills, here are two fallbacks, both of which require jQuery:

Update: Thanks to Mathias for the comment. The above code is not 100% reliable as if returns false in some versions of Chrome. Instead, consider using this Modernizr snippet.

Why this type of interaction?

Not to look a gift horse in the mouth, but why is this widget in HTML5? Well, like so many other features of HTML5, creating these widgets is just easier with HTML5. Date pickers, sliders, progress indicators, and now accordions can be implemented easily and without JavaScript. Who knows what’s next? Native tabs would be nice :)

Summary

In this article, we’ve demonstrated how to use the <details> and <summary> elements. <details> is a new element and uses the <summary> element to create an interactive disclosure widget natively in the browser.
Currently, <details> only works in Chrome, but hopefully this will change sooner rather than later. There is only one specific CSS trick we can use — ::-webkit-details-marker — but we can use plenty of other CSS to style it up. Let us know in the comments if you’ve got any experience or ideas about the <details> element.

Category

Tags

Translations

This article was written by Tom Leadbetter. Tom is a designer/frontend web developer based in Liverpool, UK. He is football (soccer) mad, loves gaming and other geeky bits n bobs. Stalk him on Twitter.

59 Responses on the article “The details and summary elements”

To check for native <details> support you may want to use a more robust feature test. WebKit had implemented the IDL attributes (so 'open' in document.createElement('details') === true) long before it actually supported <details>. Other browsers may have similar issues in the feature, resulting in false positives.

Details might have been useful a decade ago, but the state of the art today surpasses whatever functionality ends up being cobbled together to support this element.

Works without JS? Well so does CSS, and you can use newer CSS effects now to create the same functionality.

People have JS turned off? I’m not sure this is a viable concern nowadays. Seriously, how many people do have JS turned off? And if you design a site correctly, those few still have access to all the data.

How many years will we need to go through while the browser companies experiment with pseudo elements to allow web authors/developers the ability to style the details element, and then how long before this is standardized so we don’t need five variations of proprietary prefixes?

Well, I guess the answer to Shelley is “about one” (year). :-) No doubt it’ll soon be supported by Firefox (and we already know about Opera)… Safari won’t be long behind and we’re already covering pretty much everything but IE. Considering that in about a year we will have IE 10 it is possible that it might be included in that too, so…

It’s a very cool addition to the html5 spec, though it does make me wonder about the semantic value of these new tags. It pretty much tells you nothing at all about its contents, it merely describes browser behavior. And while such functional shortcuts are pretty handy, there must be a better way to mark them in our html than using html tags, no?

Another random question: is the detail a sectioning element or do we need extra wrappers for that?

I know that it isn’t a necessity, but when I look at this I think about an average user, and my first thought is that I would ad in the cursor: pointer; property in the CSS so that the user understands that this is a click-able element.

The more I think about details/summary the less I like them. HTML is supposed to be a mark-up language of semantics, and I can’t see what details/summary provides semantically that article/h1 does not.

On that basis, it would have been better for the article element to have taken an attribute which gave it the details/summary behaviour than to have minted two new elements.

But even then, adding UI behaviour to elements in mark-up feels like a layering violation. Behaviour bindings should be defined elsewhere, possibly exploiting XBL.

I wouldn’t be surprised if the details and summary elements are one day viewed in much the same way as the font element is today.

I wonder what would happen if I used <deatils> now, and then after a few months FF and Opera would have native support for it, so they would add elements like arrows which weren’t expected during creating a website.

Do you have any solution? Something to reduce arrows that are not displayed yet?

I’m encouraging every developer who is reasoned and interested in the future of the web, clean code separation, separation of concerns, etc, to boycott HTML5.

This idea is straight out of 1995. And while I do see semantic value in summary/details elements, I see nothing but the definition of behavior and presentation in the way it’s being automatically implement, and worse, with the addition of the “open” attribute being written into the spec.

Other browsers can make their own notation or even give up on this automatically implement behaviour (I’m for!). I think that “Matthew J. Sahagian” is right.

By the way, there is no need to add new pseudo class. It can be implemented just as the same as list-style property. And I’m sure that if there was default style for this element, people would reset it, because everyone wants to have custom styles. I know that pseudo class means more opportunities, but in my opinion it’s unnecessary. Don’t forget the KISS principle :)

I think there should be left just tags (details and summary), styled like lists, and if someone wants, he could implement behaviour in JS, optionally. Who agrees with me?

That was in article, I wondered what will happen after the other browsers add their own support for “details” and “summary”. And the answer is: nothing good.

In my opinion those elements are useless unless browsers decide which way do they choose to implement it. Now I can’t even predict how my site will look in Firefox two months later. I’m sure they’ll change approach described in this article.

I had submitted a bug request and a change proposal to remove details/summary from the HTML5 specification for two reasons.

The first is that details/summary is more behavior than semantics.

The second is that the state of art for providing this kind of behavior using JavaScript and CSS is beyond anything that can be provided with details summary. Throw in ARIA and we’re not already all set, we’re ready to use the technology right now.

An additional reason could also be that we’re bloating our browsers by inserting n number of needless elements.

However, I could not generate enough interest in the HTML WG, so the change proposal failed.

I’ll also add that the state of the art for a details/summary behavior not only allows us complete control over the behavior (slow sliding versus instant collapse/expansion, and what happens when JS is turned off), but also on appearance. And with a lot less consternation, too.

1) To counter you, saying that details / summary is more behaviour than semantics is like saying the same for SELECT element, or any of range, date/time inputs, as they as well incorporate certain behaviour.
2) The fact that we can mimic this type of behaviour with ordinary HTML/CSS/JS doesn’t mean such behaviour shouldn’t be built in.

Either the HTML vocabulary should expand more to include other interface elements, such as tabs, tree view, tree grid etc, or an entirely new language must appear for the likes of HTML based applications.

@Felicija, it’s a simple answer — don’t use those now. Instead wait a bit :) HTML5 is far for completion and so is CSS3. Yet people use both and write a bit more code. Sure, it’s gonna take some time for browsers to clear out differences, but those differences will be eventually resolved.

I noticed something. “Details” element is nothing but jQuery .toggle() function automatically implemented. But what if someone wants to get slide effect (99% of cases)? He would have to write special JS which overwrites default browsers behaviour. Does it make sense? It’s pathetic.

So it’s not helpful. Only makes mess. Why don’t they just make jQuery built-in? :)
How do you think, will they create as much HTML5 elements as there are jQuery functions? It would make life easier! :D

As soon as you start developing something serious, and you run out of HTML vocabulary.

Sure, I can do tabs i at least 10 different ways, but there is no single straightforward way that I can choose and make it just work.

And since one can’t truly encapsulate and bundle stuff ala shadow dom or binary of sort; nor can one extend the doctype definition so it’s understood by the browsers and add elements if needed; nor anything else that will allow further and proper reusage of components — one has to wait for the standards.

As for completion of standards, I was referring not only to the standard itself, but the accompanying standards as well. Sure, we have details / summary elements in the standard. We have context menus and other for that matter. Yet, we have scarce support in browsers, as specs on certain aspects are yet to be reviewed and implemented.

And since we are both as stubborn as possible and we could argue on this and whether the Aston or the Jag is the true gents car and no one is going to step back, I suggest we wait and see what happens.

@Felicja, now that’s an odd statement. If one desires to overwrite browser behaviour, one has to simply stop the event default behaviour with a well built in method. e.g. event.preventDefault(). No further overwriting necessary.

And it makes perfect sense — the standard covers the basics and devs take care for the rest.

In addition, built in jQ won’t get us anywhere. Too much “magic” happens inside jQ that not so many devs are aware of. And it is that magic that makes some devs go “we don’t need no details, we need $.toggle()” ;)

I already mentioned this in the article on NetTuts related to this, which is actually how I stumbled upon this thread.

The select element, as well as other standard input elements, despite having a default (and often times not very customizable) standard appearance and behavior is not the analogous issue in my opinion.

The fact for example that a checkbox can be “checked” or that an option can be “selected” is indicative of the data which the markup is defining. These elements and attributes actually say something about the available data as well as what is currently selected, I.e. They represent more than presentation, but an actual state of data.

Unfortunately the “open” attribute does not represent the same thing. I am find with the existence of a details and summary element. In my opinion those are OK as far as semantics are concerned. What I am not OK with is the definition of an attribute which has PURELY presentational value.

The open attribute does not say anything about the state of the data, but the presentation of it, namely whether or not it is visible.

In addition to this, I think it’s a very poor decision to make the toggle button a pseudo element.

We could have used pre-existing attributes for this. Indeed, similar to forms, the toggle button could simply be an anchor with a “for” attribute defined containing the “id” of the details element.

This would make a lot more sense in my opinion. Similar to anchors they are “contextual” links — which is fine if you want to define default behavior and style for (as we already do with other anchors).

<style>
details { display: none; }
</style>

<article>
<summary>
This is a summary of the article <a class="toggle" for="details-1">read more</a>
</summary>
<details id="details-1">
Here are the details
</details>
</article>

Firstly, the toggle button now becomes much more easily accessible, but can be equally easily styled using a simple common re-usable class (and no, I’m not saying write the class into the spec, just the click behavior).

This would represent a common behavior we’ve come to know with labels, where definining the for attribute focuses the input with the same “id”.

In addition we would be able to target such anchors globally with some pretty simple jQuery or equivalent.

This prevents the precedent as well that we will suddenly begin using pseudo-selectors for what rightfully should be elements.

I don’t see how this is not semantic markup. Every article in scientific or technical journals begins with a one paragraph (or so) abstract. That is followed by the body of the article. The / tags do that. The summary is the ‘abstract’ and the rest of the details would be the article. I can implement that right now with a (hypothetical) PhysRev.css that would make the article look like something from Physical Review. How is this not semantic?

A blog engine could provide only the summary to an RSS feed, and provide full details for an ‘article view’.

Show/hide is just one of several possible implementations. / is semantic.

I like the details tag but my primary intended use is actually for a works cited page, it is amazing how big those can get when you properly reference stuff. Details lets me shrink it down so the user can skim authors / publication dates (what I put in the summary) without as much scrolling, and expand the ones they are interested in.

The accessibility problem is one that I discovered, and I currently work around it by adding a standard html button that toggles the detail open or closed.

I emulate details for non chrome browser, and actually right now am emulating it for chrome as well because I can’t figure out how to trigger off the DOM changing state. This is necessary so that if the details are opened the “normal” way, the accessibility button can be triggered to change along with it.

It looks from the spec like proper implementation involves adding and deleting the open attribute when the details are displayed or collapsed, but I can not find a details specific event to attach a script function to nor can I find a generic event that driggers when a node experiences a DOM change.

Is triggering an event when details are toggled something the W3C just did not think about, or am I missing it?

@Felicja – I can use many of jQuery’s animation functions (like toggle, hide, etc.) because the way jQuery implements them is by applying style attributes to the node.

The environment I am working in, by choice, does not allow in-line style. I use CSP to enforce it, which means many jQuery functions don’t work in browsers that enforce CSP (Content Security Policy).

I do use jQuery, just not the animations, and I set class attributes set to a class defined in an external style sheet. HTML5 stuff though like the media nodes and even details allows me to provide a richer web site that even works well for paranoid people who have scripting completely disabled.

With how annoying hover ads are becoming, I frequently surf with JavaScript disabled or at least with NoScript enforcing.

That’s why I really love solutions that do not depend upon JavaScript to implement.

My emulation does not currently work in Internet Explorer (tested in IE8) but seems to work everywhere else (including tablets), but I have written some JavaScript that emulates details for browsers that do not natively support it, including accessibility considerations.

It is still a work in progress, I need to fix it in IE and I need to provide easy function for applying emulation to details added after the script has loaded (IE for things fetched via Ajax) and there are probably bugs, but it does a decent job other than for IE.

The only detail (pun intended) that strikes me and which is very irritating is why Chrome went with ::-webkit-details-marker, instead of simply :before.

The native user agent styling for ::-webkit-details-marker is not visible and cannot be revealed in any way. Just as the example snippets in this post demonstrate, the 99% use-case of web developers will be to override the marker with custom styling, and of course, they will use :before for that.

— But yet, you first need to figure out which kind of weird hidden user agent pseudo style is causing the default marker to appear, and after you’ve done so, you still have no clue at all what the actual default styles of the user agent are.

This aspect of the vendor implementation puts the summary element into a similarly poor position as the <legend> element of fieldsets, which equally receives countless of inconsistent default styles across user agents that are beyond human understanding and are impossible to normalize in a reliable way.

In short, I do not understand why anyone thought it would be a good idea to introduce an entirely new pseudo element that is specific to summary elements, while the standard:before would have resolved the problem in a much more elegant, reliable, predictable, and customizable way.

Given that Chrome is still the only native implementation, I hope that browser vendors are still able to correct that and will do so (and most probably vastly simplify their implementations at the same time). Even though that might cause pain for some existing sites (including me), it would definitely be appreciated and for the better.

If your willing to use a child div inside your details elements you can start an animation. This will be more effective if you set the animation height to the height of your smallest content and much more effective if all your details elements are of a similar height.

Hi Bruce. Before I go further, I just want to say I’m a fan of your writing. I enjoy your direct and meaningful course of thinking about all things web.

— onward —

There might be accessibility issues (maybe usability as well) in doing so, but I wanted to know how to style the highlight only because I found the browser default not appropriate in an experimental situation where it just didn’t look right. I’ve since been informed that to accomplish what I was looking to do, I needed to target the summary element, not the details one (strangely?).