Saltar al contenido principal

Catálogo · Contenido

FAQ

Lists the questions visitors ask with their answers, in groups, as native disclosures that work without a script.

Encaja mejor en: cualquier sitio — a list of questions with their answers, on a help page, a landing page or the foot of a product page

Esta página todavía no está traducida; el texto está en inglés. Leer esta página en inglés

Example

The questions of a bike rental shop, in two groups. The first answer is open, and the links under the lead jump to each group.

Questions about renting a bike

What to know before you pick up your bike at Marea Bikes in Cádiz.

Booking and pickup

How do I book a bike?

Book on the Marea Bikes website or at our shop. Choose the day, the size and the type of bike, and pay online or when you pick it up. We send a confirmation by e-mail with your pickup time.

What do I need to bring?

Bring three things to the shop:

  • A photo ID.
  • The confirmation e-mail, on paper or on your phone.
  • A card for the €100 deposit, which we release when you return the bike.
Can I cancel a booking?

Yes, free of charge until 24 hours before pickup. After that, Marea Bikes keeps the price of the first day.

On the road

Can I ride outside Cádiz?

Yes, anywhere in the province of Cádiz. For a trip outside it, ask us before you book: the insurance of a Marea Bikes bike covers the province only.

What if the bike breaks down?

Call the number on the tag of your key. In the city centre we fix or swap the bike within two hours, at no cost, unless the damage is not from normal use.

Not here? Write to the shop

On a site the list takes the width of its container, and each answer stops at a comfortable line length.

Known issues

In a browser before Chrome 97, Firefox 148 or Safari 26.2, a link to an answer lands on its closed question: the answer is one click away, but it does not open by itself. In Safari 26.2 the page does not scroll well to the answer found with Find in page.

Closed answers print only where the browser supports ::details-content (Chrome 131, Firefox 143, Safari 18.4). An older browser prints a closed question without its answer: open the questions before you print.

Code

Copy the markup

Bundler
import "@luz-ds/catalog/components/faq.css";
HTML
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@luz-ds/catalog@0.3.0/dist/components/faq.min.css" integrity="sha384-m1FP6KJs/RtOCSvuxpyMHSpdpfzKoGkqbqzJ0s4TSjTWAiZi584APY4HqMvX9xkV" crossorigin="anonymous">

A <luz-faq> around a title, a lead, the groups and, last, a line for the visitor who did not find the answer. Each question is a <details> and each answer is a <div> with its own id. The title is yours to level: use the heading that fits your page, and the next level for the groups.

HTML
<luz-faq>
  <h2 class="luz-faq__title">Questions about renting a bike</h2>
  <p class="luz-faq__lead">What to know before you pick up your bike.</p>
  <nav class="luz-faq__nav" aria-label="In this FAQ">
    <ul>
      <li><a href="#booking">Booking and pickup</a></li>
      <li><a href="#road">On the road</a></li>
    </ul>
  </nav>
  <section class="luz-faq__group" aria-labelledby="booking">
    <h3 class="luz-faq__group-title" id="booking">Booking and pickup</h3>
    <details class="luz-faq__item">
      <summary class="luz-faq__question">Can I cancel a booking?</summary>
      <div class="luz-faq__answer" id="faq-cancel">
        <p>Yes, free of charge until 24 hours before pickup.</p>
      </div>
    </details>
    <details class="luz-faq__item">
      <summary class="luz-faq__question">What do I need to bring?</summary>
      <div class="luz-faq__answer" id="faq-bring">
        <p>Bring a photo ID and the confirmation e-mail.</p>
      </div>
    </details>
  </section>
  <section class="luz-faq__group" aria-labelledby="road">
    <h3 class="luz-faq__group-title" id="road">On the road</h3>
    …
  </section>
  <p class="luz-faq__more">Not here? <a href="/contact/">Write to the shop</a></p>
</luz-faq>

Variants and options

Only the list of questions is needed. The title, the lead, the groups, the links to the groups and the last line are optional parts.

Part or optionEffect
<luz-faq>
The block, as wide as its container. A tag that no script defines
.luz-faq__title, .luz-faq__lead
Optional. The title in the heading face, and a lead under it in secondary text. Any heading level, any element for the lead
.luz-faq__nav
Optional, for a long FAQ with groups: a <nav> with a list of links to the group titles, as a row of tags that wraps. Give it an aria-label
.luz-faq__group, .luz-faq__group-title
Optional, for a FAQ with several topics: a <section> named by its title, which is a real heading, shown as a small centred label in capitals (not in Arabic, which has no capitals). A short FAQ has no groups
.luz-faq__item, .luz-faq__question
One question: a <details> and its <summary>, between hairlines, in bold and at the size of its answer, with a plus that becomes a minus when it opens
.luz-faq__answer
The answer, in reading text, with any HTML inside: paragraphs, lists, links, code. Its id is the link to it
.luz-faq__more
Optional, last: a line in secondary text for a visitor who did not find the answer, with a link to support
name
On the <details>, the browser’s own attribute: with the same name on all of them, opening a question closes the one that was open. Without it, several can stay open
open
On one <details>, the browser’s own attribute: that question is open when the page loads. Use it for the most common doubt only
--luz-faq-measure
On the tag, the widest an answer or a lead gets. Default 65ch

How it works

CSS from @luz-ds/catalog. No JavaScript: <luz-faq> is a tag that no script ever defines.

  • Every answer is in the HTML the server sends, so a reader, a search engine and a tool that does not run scripts all get it.
  • Put the id on the .luz-faq__answer, never on the <details>. A link to an id on the <details> lands on its <summary>, which is already in view, so the browser opens nothing. A link to an id inside the hidden answer opens the question, and the answer keeps the question above it when the page scrolls.
  • The browser’s Find in page also opens a question whose answer holds the words it found.
  • The whole question is the control, at least a large control high, not only the plus. Its text can be selected, so a visitor can copy it to quote it.
  • The state is the shape of the marker: a plus when closed, a minus when open. The open question also takes the brand colour, so it reads apart from its answer, and a question under the pointer takes the same colour, with no underline. The marker folds with a short ease, and with reduced motion it changes without it.
  • Long words break, and code or a table inside an answer scrolls inside it: the page never scrolls sideways.
  • On paper every answer prints, open or closed, and the markers do not.

Without JavaScript

Nothing changes: all of it works. Opening, closing, the exclusive group, the link to an answer and Find in page are the browser’s.

Keyboard and ARIA

Tab reaches each question in order. Enter or Space opens or closes it. There are no arrow-key shortcuts between questions.

  • The control: the <summary> is the control and the browser gives it its role and its state. Add no aria-expanded, no aria-controls and no role: they repeat what the element already says.
  • Headings: the questions are not headings. A heading inside a <summary> is not announced as one in every screen reader. The group titles are the headings of the list, so a reader can move through the topics by headings.
  • Groups and links: a group is a <section> named by its title with aria-labelledby. The links to the groups go in a <nav> with an aria-label.
  • Keep links and buttons out of a question: the question is itself the control. Links belong in the answer.
  • The FAQ has not been tested with a screen reader.

Contrast and focus are in the Design tab.

Design

When to use

Use it for a list of several questions that visitors really ask, which you can answer in a few sentences each: opening hours, prices, how to book, what a product does not do.

  • It fits a landing page, a help page or the foot of a product page, in a site of any kind.
  • Group the questions when there are several topics; leave the groups out of a short list.

When not to use

Do not use it for one disclosure: a single <details>, or the accordion of core, is enough and carries no list around it.

  • Do not put a long guide in an answer. Answer in a few sentences and link to the page that explains it.
  • Do not use it to hide content the visitor needs on every visit: show that on the page.
  • Do not use it to stuff a page with keywords. A question nobody asks helps nobody.

Do and don't

Do Write the question as the visitor would say it, and start the answer with the answer: yes, no, a number, a date.
Don't Name a topic instead of asking, and answer with a pointer: “as said above” means nothing to a visitor who opened only this question.

Writing the content

An answer can be read alone, in a search result, in a quote or in a link, so write each one to stand on its own.

  • Write each question in natural language, one doubt per question, as the visitor would ask it. Never write one only to carry a keyword.
  • Answer in the first sentence. Then add the context, the steps or the exceptions.
  • Make every answer understandable alone: no “this”, “the above” or “as said before”. Use the concrete names: the product, the file, the element.
  • Give facts, conditions and examples, and link to the page that explains the subject in depth instead of copying it.
  • Keep the answers up to date and consistent with the rest of the site. A figure that appears elsewhere is written once.
  • Use a list for steps and a short code block for a command. Keep sentence case in the questions, with the question mark.

Structured data of type FAQPage is your call, and the component adds none. Search engines show rich results for FAQs on a few kinds of sites only, and no markup makes a page appear in an AI answer. Add it if it applies to your site, and promise nothing with it.

Contrast and focus

The questions, answers and links sit on the page surface.

PartColour on backgroundLightDarkHigh contrastNeeds
Question and answer
--luz-text-primary on --luz-surface-page
15.8:1
15.1:1
21.0:1
4.5:1
Open or hovered question, links to the groups
--luz-brand-primary on --luz-surface-page
5.6:1
7.7:1
14.1:1
4.5:1
Link to a group, hovered
--luz-brand-primary on --luz-surface-hover
5.1:1
6.4:1
13.5:1
4.5:1
Lead, group title, last line
--luz-text-secondary on --luz-surface-page
6.2:1
7.5:1
19.3:1
4.5:1
Marker, closed
--luz-text-primary on --luz-surface-page
15.8:1
15.1:1
21.0:1
3:1
Marker, open
--luz-brand-primary on --luz-surface-page
5.6:1
7.7:1
14.1:1
3:1
Focus ring on a question
--luz-focus-ring on --luz-surface-page
5.6:1
7.7:1
21.0:1
3:1

Measured from the token values of each mode, rounded down. Needs is the WCAG 2.2 AA minimum: 4.5:1 for text, 3:1 for the marker and focus rings. On a surface other than the page, measure again.

  • Focus: the question has core’s 2 px --luz-focus-ring outline, 2 px outside its box.
  • Open or closed is never told by colour alone: the marker changes shape, from a plus to a minus.
  • The hairlines between questions (--luz-divider) are decoration: the text of each question, not a border, says where it is.
  • In forced colours the marker takes the system’s text colour and stays visible.

Tokens it uses

The 21 tokens that the rules of catalog’s components/faq.css read, by family. Each family links to its page, with the values in every mode. In Figma they are variables with the same names: see Tokens in Figma.

Spacing and sizing
--luz-control-lg, --luz-space-2xl, --luz-space-2xs, --luz-space-lg, --luz-space-md, --luz-space-sm, --luz-space-xl, --luz-space-xs
Typography
--luz-font-body, --luz-font-heading, --luz-font-sans, --luz-text-lg, --luz-text-sm
Radius
--luz-radius-sm
Motion
--luz-duration-fast, --luz-easing-standard

Keyboard and ARIA are in the Code tab.