Native HTML: Accordion
Tags: html, css, a11y, design
Published: 2019-01-04 12:31:27

If you cast your mind back 10 years to when JQuery was king you might remember how ubiquitous [JQuery UI](https://jqueryui.com/) was, it meant sites suddenly had more functionality and elements. One of those elements was the humble [accordion](https://jqueryui.com/accordion/).

[![JQuery Accordion](https://thepracticaldev.s3.amazonaws.com/i/r6f8fo80on4h08z06h6z.png)](https://jqueryui.com/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](https://thepracticaldev.s3.amazonaws.com/i/oxef0yka39f44l4qkwxe.png)

## Details Element

As always let's start by taking a look at what Mozilla have to say on their [`<details>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/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>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/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>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary) element.

>The **HTML Disclosure Summary element (`<summary>`)** element specifies a summary, caption, or legend for a [`<details>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/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.

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

{% codesandbox 210wx5y71r %}

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.

```css
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;
}
```

```html
<details>
  <summary>Summary</summary>
  <main>Text to hide away.</main>
</details>
```

{% codesandbox 206xlm397j %}

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 ❤❤🦄❤🦄❤❤