loading...
Cover image for Native HTML: Accordion

Native HTML: Accordion

link2twenty profile image Andrew Bone ・3 min read

If you cast your mind back 10 years to when JQuery was king you might remember how ubiquitous JQuery UI was, it meant sites suddenly had more functionality and elements. One of those elements was the humble accordion.

JQuery Accordion

But that was a decade ago and we no longer need javascript libraries to do our heavy lifting, the platform has come a long way. So today we'll be looking at <details> and <summary>, which are the modern-day equivalent of an accordion. Support is actually great with only one, notable, holdout.

Details Support

Details Element

As always let's start by taking a look at what Mozilla have to say on their <details> page.

The HTML Details Element (<details>) creates a disclosure widget in which information is visible only when the widget is toggled into an "open" state. A summary or label can be provided using the <summary> element.

A disclosure widget is typically presented onscreen using a small triangle which rotates (or twists) to indicate open/closed status, with a label next to the triangle. If the first child of the <details> element is a <summary>, the contents of the <summary> element are used as the label for the disclosure widget.

Reading this we learn the <details> element has two states, open and closed, and that it expects a <summary> element as its first child, but doesn't require one.

Summary Element

Now we can have a look at the description of the <summary> element.

The HTML Disclosure Summary element (<summary>) element specifies a summary, caption, or legend for a <details> element's disclosure box. Clicking the <summary> element toggles the state of the parent <details> element open and closed.

We don't really learn much extra here, which is because the two elements are so closely linked, other than clicking on the summary text will toggle the details.

Using it

Let's look at using it.

<details>
  <summary>Read more</summary>
  Some text to be hidden. 
</details>

There we have it, it's not the nicest looking element in it's standard form but it certainly does the job.

Styling it

I started this post with a throwback to JQuery UI's accordion so it seems only fitting that we style our <details> block to look similar.

details {
  overflow: hidden;
  margin-top: 0.125em;
  border: 1px solid #dddddd;
  background: #ffffff;
  color: #333333;
  border-radius: 3px;
}

details summary {
  display: block;
  cursor: pointer;
  padding: .5em .5em .5em .7em;
  background: #ededed;
  color: #2b2b2b;
  border-radius: 3px 3px 0 0;
}

details:not([open]) summary:hover,
details:not([open]) summary:focus {      
  background: #f6f6f6;
  color: #454545;
}

details[open] summary {
  border: 1px solid #003eff;
  background: #007fff;
  color: #ffffff;
}

details main {
  padding: 1em 2.2em;
}
<details>
  <summary>Summary</summary>
  <main>Text to hide away.</main>
</details>

There are some caveats though;

Unfortunately, at this time there's no built-in way to animate the transition between open and closed.

Also, the accordion did a couple of things differently, only one item could be opened at a time, a limitation we could fix with JS, and keyboard navigation was more akin to a radio group rather than tabbing through.

Wrapping up

So there we have it another Native HTML element and another opportunity to use less JavaScript.

As always if you disagree with anything I've said let me know why, I'd love to hear your differing opinions. Also, feel free to suggest other elements I should take a look at.

Thank you for reading ❤❤🦄❤🦄❤❤

Posted on by:

link2twenty profile

Andrew Bone

@link2twenty

A British Front-end developer, that is passionate about web accessibility.

Discussion

pic
Editor guide
 

I'm really enjoying this series so far, Andrew. Looking forward to learning more native HTML elements. As of writing this, I have recognized none of the HTML elements you have mentioned in your posts. It's great to learn something new in HTML. It's a breath of fresh air from all the JavaScript I have in my life right now.

 

Thank you that means a lot 🙂

 

Wrap it in a custom HTML tag:

<m-accordion>
    <details>
        <summary>Summary</summary>
        <p>Details about this thing</p>
    </details>
    <details>
        <summary>Summary</summary>
        <p>Details about this thing</p>
    </details>
</m-accordion>
Enter fullscreen mode Exit fullscreen mode

That gives you the option to style <details> in accordion differently (e.g. M- clears all details styles, but adds some when inside accordion) and this also gives you the parent element needed to control the one at a time open state.

 

All I can say is, this is beautiful. So elegant. So simple. Perfect for my needs! I have been wrestling with CSS for hours.

I taught myself HTML in 1997. Haven't designed a website since 2003, when CSS was brand new. No clue about all this new stuff. Thank you, thank you, thank you! I'm going to use this for the lyrics to my songs (I'm a songwriter/composer).

Again, thank you!

 

This is a really good post. Very interesting series.

 

Unfortunately, at this time there's no built-in way to animate the transition between open and closed.

I don't see that as a problem :) Animations in functional parts of a UI are a UX-smell.

 

I agree that it's not a show-stopper but I would like the option to add a slide out animation. Generally, I don't like it when content appears, seemingly, from nowhere.

 

I absolutely love this...thanks a million....makes my job sooo much easier. Hurrah for no Javascript! I am using it for a new Shopify store :)

 

An aside for any new readers

dev.to now uses this method to hide and show comments