I made a poll on Twitter the other day asking the #lazyweb how they would mark up an FAQ section — or a list of questions and their corresponding answers. I specifically asked for markup suggestions. Turns out, people mark questions and answers up differently. I got some interesting insight from the responses I got that partly changed the way I would approach building an FAQ section, and some validation for the way I always have built them. The discussion was too interesting to not summarize in an article. The different possible markup approaches as well as useful resources are discussed below.
Hey #lazyweb, I got a small Friday poll for you:— Sara Soueidan (@SaraSoueidan) August 31, 2018
How do you mark up a list of questions and answers? (Think: FAQ)
I’m talking about semantic markup, so forget about accordions for a second and assume there is no JS for that.
Would you use:
An FAQ can be thought of as a list of questions with answers, or a series of questions and answers.
A series of questions and answers: <hx> + <div>
A series of questions and answers can be marked up by using a series of headings for the questions, and paragraphs (probably wrapped in a
<div>) for each answer. This is one of the most commonly used code patterns.
<h3>How would you mark up a series of questions and answers?</h3> <div> I would probably use headings, each followed by an answers most likely wrapped in a semantic-less wrapper. </div> <h3>How would you mark up a series of questions and answers?</h3> <div> I would probably use headings, each followed by an answers most likely wrapped in a semantic-less wrapper. </div> <h3>How would you mark up a series of questions and answers?</h3> <div> I would probably use headings, each followed by an answers most likely wrapped in a semantic-less wrapper. </div>
The whole series of questions and answers would then also be wrapped in a container, or each pair of question and answer can be wrapped in an
<article>, and they can easily be scripted to add accordion behavior by potentially replacing the heading text content with a toggle
The enhancement of the markup to an interactive accordion is outside the scope of this article. Refer to the Further Resources section below for links to learn more about adding accordion interactivity to basic markup.
<h3> <button aria-controls="myID-1" aria-expanded="false"> <span>How would you mark up a series of questions and answers?</span> </button> </h3> <div id="myID-1" hidden > I would probably use headings, each followed by an answers most likely wrapped in a semantic-less wrapper. </div>
The way you might approach turning it into an accordion might be slightly different, but the requirements for making an accordion accessible should still be applied, so, in essence, the final result wouldn’t be too different.
Advantages of this approach:
- The markup is simple and can be easily converted into an interactive accordion. ✔
- Assistive technology users are able to navigate the FAQ using the headings. ✔
A list of questions with answers: <ul> or <dl>
If you think about FAQs as a list of questions with answers, you’ll probably want to use HTML lists to mark them up.
I’d probably not use an ordered list (
<ol>) because the order of the questions is usually irrelevant. That leaves us with unordered lists (
<ul>) and definition lists (
What both lists have in common is the semantics of a list — meaning that the questions and answers would be conveyed to assistive technologies as a list of items.
An unordered list of questions with answers: <ul> <li> + <hx> <div>
If you use an unordered list, each list item would contain both the question and the question’s corresponding answer.
The semantics of an unordered list item
<li> would not be enough to represent and distinguish the question and/from the answer. So I’d consider wrapping the question in a heading. This does feel odd, as I’ve never thought that an
<li> as a container to a heading, but this code has some important benefits.
I’d next wrap the content of the answer in a
<div> so that I can easily toggle it when I want to add accordion functionality to the FAQ.
<ul> <li> <h3>What is a bird’s favorite sleeping spot?</h3> <div> <p>Their owner’s shoulders and foreheads. They like to get warmth from a hooman’s neck and face.</p> <p> They also like always reminding you that they’re the boss.</p> </div> </li> </ul>
Advantages of this approach:
- Assistive technologies (ATs) will announce the number of items, so their users will get an overview of how many questions there are. ✔
- AT users will be able to navigate the FAQ list using the headings. ✔
A definition list
A definition list is similar to ordered and unordered lists. What distinguishes it from other lists is that it is made up of key/value pairs.
The HTML <dl> element represents a description list. The element encloses a list of groups of terms (specified using the <dt> element) and descriptions (provided by <dd> elements). Common uses for this element are to implement a glossary or to display metadata (a list of key-value pairs).— MDN
I have always used definition lists (
<dl>) to mark up FAQs. I like the fact that a
<dl> has a series of terms (
<dt>) and descriptions (
<dd>). A question would be a term. The answer would be its description.
This approach got the most votes in my poll. This may partially be due to the fact that the specification mentions questions and answers as an example usage for definition lists:
Term-description groups may be names and definitions, questions and answers, categories and topics, or any other groups of term-description pairs.
Markup for a
<dl>-based FAQ would look like so:
<dl> <dt>Your question here?</dt> <dd> <p>You answer here. It can be anything and as long as you want, and contain any type of content.</p> </dd> <dt>Your question here?</dt> <dd> <p>You answer here. It can be anything and as long as you want, and contain any type of content.</p> </dd> </dl>
Converted to an interactive accordion, and similar to what we’ve seen before, it would look like this:
<dl> <dt><button aria-controls="myID-1" aria-expanded="false">Your question here?</button></dt> <dd id="myId-1" hidden > <p>You answer here. It can be anything and as long as you want, and contain any type of content.</p> </dd> <dt><button aria-controls="myID-2" aria-expanded="false">Your question here?</button></dt> <dd id="myId-2" hidden > <p>You answer here. It can be anything and as long as you want, and contain any type of content.</p> </dd> </dl>
I’ve never hit any road blocks styling definition lists, but that’s probably because none of my projects required any styles that were not possible using the default markup. But many developers have, as the Twitter thread shows.
Most styling limitations were due to the fact that it was invalid HTML to have a
<div> as a child of the
<dl>. This, in turn, meant that it would be difficult to group and style pairs of terms and descriptions.
Today, it is perfectly valid to add a
<div> as a child to a
<dl>. That said, Steve Faulkner points out that “this can cause issues for screen readers as the pattern changes the way the semantics are represented in some browsers.” Check out his test cases and results for more context and details.
Notes about this approach:
- Some assistive technologies (ATs) will announce the number of items, so users of those technologies get an overview of how many questions there are. This, however, is unfortunately not consistent across all tech.
- AT users will not be able to navigate the questions like they could with headings.
Even though I will not be using them for marking up FAQs from now on after the discussions I had as a result of this poll, I would still use definition lists for other, more proper use cases. For example, I’ve used them before within articles where I list a set of available attributes or properties and then elaborate on each one and describe what it does.
The native HTML accordion: <details> + <summary>
The– W3C HTML specification
<details>element represents a disclosure widget from which the user can obtain additional information or controls.
<details>, we can put any sort of content we want.
<details> has a friend called
<summary>. When present inside
<details>, the first
<summary> element child represents the summary or legend of the
Essentially, we can use
<details> to create an accordion-like widget that the user can toggle open and closed. The
<summary> element, when present, acts as the content of the toggle for the accordion.
Before doing the Twitter poll, I’d never considered using
<summary> to mark up FAQs. I’ve always thought of the semantics of these elements too literally: a summary is, well, a summary of the content of the details. Since the summary of an answer is derived from that answer itself then it is also an answer; and then a question could not be a <summary> because the question is not an answer. Confused yet?
I had a discussion about this with my friend Scott O’Hara after tweeting the poll. We both made valid points, but the main reason we were confused and were disagreeing is that I was talking about
<summary> as a “summary” whereas Scott was referring to the
<summary> element as, well, a generic “toggle” element.
Turns out, and I‘ve finally made my peace with the fact, that
<summary> don’t literally represent content and summary of that content. The spec editors settled for these names out of a bunch of other options they had. Because naming things is hard.
Because expressing perfect meaning in a single small, easy-to-spell word is hard, so we approximate.— 🌺Taudry Hepburn🌺 (@tabatkins) August 31, 2018
I remember there being a lot of possibilities when naming that - <spoiler> was my favorite. 😀
I would have preferred
<panel> as truly generic names. But if
<summary> are just meant to be generic names, then using them to mark up FAQs starts to make a tiny bit more sense.
I think of it as: the "summary" is a short description of what you will see if you expand the details. A question in a FAQ is a summary of what the answer will cover.— Amelia Bellamy-Royds (@AmeliasBrain) August 31, 2018
But yeah, I like toggle/panel more. Someone should have got you on the committee. But it's too late now.
So, marking an FAQ up using
<summary> is pretty simple:
<details> <summary>Why is naming things so hard?</summary> <p>Because it just is.</> </details> <details> <summary>Why is naming things so hard?</summary> <p>Because it just is.</> </details>
… and it comes with some nice advantages, and some limitations:
- You get the accordion behavior (collapsible panels) baked in by default. ✔
- The accordion is mostly fully accessible (ATs and keyboard) by default. Scott O’Hara wrote and shared the results of his tests with popular screen readers. Make sure to read his post before deciding to use
<details>as an accordion, as there are some things you’ll need to be aware of:
<details>element and its
<summary>are fairly easily styled. (Some specific browser handling is required but nothing too complex.) ✔
- You can’t currently animate the opening and closing of the details panel. But you can work around it by animating the content inside the
- Opera Mini, IE and Edge currently don’t support
<summary>degrade gracefully to show their content by default, without the interactive behavior, which, in my opinion, is a perfectly acceptable fallback experience.
So, why does this all even matter?
Because semantic HTML matters and is essential for creating truly inclusive and functional Web sites that work across the widest range of apps possible.
Sure, there are different ways for doing one thing, but as long as all these different ways offer true accessibility, then we have the freedom to choose whichever technique we like.
It’s always necessary, in my opinion, to consider what content would render and look like in foreign environments, or in environments that are not controlled by our own styles and scripts. Writing semantic HTML is the first step in achieving truly resilient Web sites and applications.
If you need to learn more about creating accordions that are accessible, I recommend checking these resources out:
- Accessible ARIA Accordions by Scott O’Hara.
- Collapsible Sections by Heydon Pickering.
- Accordion accessibility expectations by Dave RUpert.
- Accordion WAI-ARIA Authoring Practices
Thank you for reading.
Huge thanks to everyone who contributed to the Twitter thread with insightful content, as well as to my friend Scott O’Hara, who has taught me, and still teaches me, so much about accessibility.