details and summary

Two elements do the whole job with no script, right up until somebody hits print.

#html #accessibility #small-print

faq.html
<details>
  <summary>How long does delivery take?</summary>
  <p>Two to three business days.</p>
</details>
HTML

That’s an accordion. It’s in the tab order and it opens and closes with a click, Enter or Space. It even announces its expanded state without an aria-expanded anywhere. The browser owns that state, not you.

I built this by hand on four projects, with a click handler and a class toggle and an ARIA attribute I sometimes remembered, before I finally sat down and read what the element already did.

The open attribute makes it start expanded. The browser adds and removes it as people click. That makes details[open] your styling hook.

The disclosure triangle is the one part that differs by browser. Firefox draws it as a list marker, so list-style: none on the summary gets rid of it. Chrome and Safari draw their own and want summary::-webkit-details-marker { display: none; } instead. Write both if you want a marker of your own.

The catch is printing. A closed <details> is closed on paper too, and so a page of FAQs prints as a column of questions with nothing under them. No stylesheet fixes that because the browser doesn’t render a closed one’s contents, whatever you set their display to. So it takes a few lines of script after all.

print.js
window.addEventListener('beforeprint', () => {
  document.querySelectorAll('details').forEach((details) => {
    details.open = true;
  });
});
JavaScript

That leaves everything open once the print dialog closes. If that bothers you, remember which ones you opened and close them again on afterprint.

Which is the general shape of these. The platform gives you the behavior and leaves you the one edge case it couldn’t guess.

Read similar posts

View posts by tag

#accessibility #agency #ai #careers #cross-browser-compatibility #css #culture #debugging #documentation #ecommerce #forms #git #html #images #javascript #performance #php #privacy #scss #security #shopify #small-print #tooling #typography #wordpress