You don’t need JavaScript to implement a dropdown. You can create an accessible dropdown using just the html <details> element. This post will cover how I implemented a dropdown menu for an app I recently created called Congress Connect. I first learned about this element at a BrooklynJS meetup almost a year ago. There was a really cool talk, and the slides are excellent, and I highly recommend reading them if you are interested in learning more than this post covers.

How it works

To implement the dropdown, start with the <details> tag.

According to MDN, the (<details>) creates a disclosure widget in which information is visible only when the widget is toggled into an “open” state.

Inside that, nest the <summary> tag, which holds the visible label of the information that can be viewed. Below that, include the content that you’d like to disclose. Here’s an example:

<details>
  <summary>Voting Record</summary>
  <p>
    Here is the information that shows after the summary element is clicked!
  </p>
</details>

Here’s a demo from Congress Connect

Here’s a snippet of the code to give you another example:

<>
  <details>
    <summary>Voting Record</summary>
    {member.roles
      .filter(x => x.congress === "116")
      .map(role => (
        <ul>
          <li>Bills sponsored: {role.bills_sponsored}</li>
          <li>Bills cosponsored: {role.bills_cosponsored}</li>
          <li>Missed votes: {role.missed_votes_pct}%</li>
          <li>Votes with party: {role.votes_with_party_pct}%</li>
        </ul>
      ))}
  </details>
</>

You can checkout the full implementation here.

Other notes of interest

  • To implement an accessible dropdown, you don’t need to rely on aria attributes.
  • <details> is semantic HTML, so its screen reader friendly.
  • The child element, <summary>, is focusable out of the box.
  • This element supported in Safari, Chrome, and Firefox. Sorry, no IE Edge.
  • You can also use <details> for accordians and popovers.
  • The author of the original <details> talk that inspired me to use it in my own work recently published slides for another talk on the powers of the <dialog> element: