Interaction · Complete runnable example

Native details FAQ

A practical FAQ built from native disclosure controls that work without JavaScript.

Live example

This preview runs in an isolated document. Clipboard writes and saved preferences may be blocked, and printing requires the standalone file. A dialog affects only the example. Reset reloads the original example state.

When to use it

Use native disclosure elements when readers should choose which answers to expand. The browser supplies the core open and close behavior, so the content remains available if scripts do not run.

Try the important details

  1. Tab to a question and press Enter or Space to open and close its answer.
  2. Open several answers and resize the preview to check text wrapping.
  3. Download the example and disable JavaScript. The questions still work.

How it works

  • Each details element has a descriptive summary as its first child.
  • The CSS gives the summary a visible focus indicator and comfortable pointer target.
  • The example lets answers open independently. No custom role or click handler duplicates native behavior.

The complete source

The preview, copied text, and downloaded file use this same document.

HTML

<!doctype html>
<!--
MIT License

Copyright (c) 2026 MRHTML

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-->
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta
      http-equiv="Content-Security-Policy"
      content="default-src 'none'; style-src 'unsafe-inline'; script-src 'unsafe-inline'; img-src data:; connect-src 'none'; form-action 'none'; object-src 'none'; base-uri 'none'"
    />
    <title>MRHTML | A native FAQ</title>
    <style>
      :root {
        color-scheme: light;
        --paper: #f6f5f0;
        --white: #fff;
        --ink: #172437;
        --muted: #546171;
        --line: #c9ced4;
        --blue: #204cbb;
        --soft: #e9eefb;
        font-family: Arial, Helvetica, sans-serif;
      }
      * {
        box-sizing: border-box;
      }
      body {
        margin: 0;
        background: var(--paper);
        color: var(--ink);
        line-height: 1.65;
      }
      main {
        width: min(72rem, calc(100% - 3rem));
        margin: 0 auto;
        padding: clamp(2rem, 6vw, 4.5rem) 0;
      }
      h1,
      h2,
      h3,
      p {
        margin: 0;
      }
      a {
        color: var(--blue);
        text-underline-offset: 0.25em;
      }
      a:focus-visible,
      button:focus-visible,
      summary:focus-visible,
      input:focus-visible {
        outline: 3px solid var(--blue);
        outline-offset: 4px;
      }
      .eyebrow {
        color: var(--blue);
        font-size: 0.72rem;
        font-weight: 700;
        letter-spacing: 0.15em;
        text-transform: uppercase;
      }
      h1 {
        font-size: clamp(2.3rem, 6vw, 4.2rem);
        letter-spacing: -0.055em;
        line-height: 1.08;
        max-width: 15ch;
        overflow-wrap: anywhere;
      }
      .intro {
        color: var(--muted);
        font-size: 1rem;
        max-width: 40rem;
        margin-top: 1.3rem;
      }
      .footer-note {
        margin-top: 2.5rem;
        border-top: 1px solid var(--line);
        padding-top: 1.25rem;
        color: var(--muted);
        font-size: 0.8rem;
      }
      [hidden] {
        display: none !important;
      }
      @media (max-width: 420px) {
        main {
          width: calc(100% - 2rem);
        }
      }
      @media (prefers-reduced-motion: reduce) {
        *,
        *::before,
        *::after {
          scroll-behavior: auto !important;
          animation: none !important;
          transition: none !important;
        }
      }

      .faq-layout {
        display: grid;
        grid-template-columns: 0.85fr 1.3fr;
        gap: clamp(2rem, 7vw, 5rem);
        align-items: start;
      }
      .intro-panel {
        position: sticky;
        top: 2rem;
      }
      .intro-panel h1 {
        margin-top: 1.3rem;
      }
      .intro-panel .intro {
        font-size: 0.95rem;
        max-width: 23rem;
      }
      .side-note {
        margin-top: 2rem;
        display: flex;
        gap: 1rem;
        border-top: 1px solid var(--line);
        padding-top: 1rem;
        font-size: 0.8rem;
        color: var(--muted);
        max-width: 23rem;
      }
      .side-note span:first-child {
        color: var(--blue);
        font-size: 1.4rem;
        line-height: 1.4;
      }
      .faq-list {
        border-top: 2px solid var(--ink);
      }
      details {
        border-bottom: 1px solid var(--line);
      }
      summary {
        cursor: pointer;
        list-style: none;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 1.5rem;
        min-height: 5.5rem;
        padding: 1.4rem 0.25rem;
        font-weight: 700;
        font-size: 1rem;
        line-height: 1.5;
      }
      summary::-webkit-details-marker {
        display: none;
      }
      summary:hover {
        color: var(--blue);
      }
      .plus {
        position: relative;
        display: inline-block;
        flex: 0 0 2rem;
        width: 2rem;
        height: 2rem;
        border: 1px solid #99a5ba;
        border-radius: 50%;
        background: var(--white);
      }
      .plus::before,
      .plus::after {
        content: '';
        width: 0.65rem;
        height: 1px;
        background: var(--blue);
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
      }
      .plus::after {
        transform: translate(-50%, -50%) rotate(90deg);
      }
      details[open] .plus {
        background: var(--soft);
        border-color: var(--blue);
      }
      details[open] .plus::after {
        display: none;
      }
      .answer {
        padding: 0 3.8rem 1.5rem 0.25rem;
        color: var(--muted);
        font-size: 0.92rem;
      }
      .answer p + p {
        margin-top: 1rem;
      }
      .answer ul {
        padding-left: 1.25rem;
        margin: 1rem 0;
      }
      .answer li + li {
        margin-top: 0.5rem;
      }
      .answer code {
        font-size: 0.9em;
        overflow-wrap: anywhere;
        color: #204c91;
      }
      .afterword {
        background: var(--soft);
        border: 1px solid #c2cceb;
        border-radius: 0.75rem;
        padding: 1.4rem;
        margin-top: 1.5rem;
      }
      .afterword h2 {
        font-size: 0.95rem;
      }
      .afterword p {
        font-size: 0.83rem;
        color: var(--muted);
        margin-top: 0.5rem;
      }
      @media (max-width: 720px) {
        .faq-layout {
          grid-template-columns: 1fr;
        }
        .intro-panel {
          position: static;
        }
        .side-note {
          margin-top: 1.5rem;
        }
        .answer {
          padding-right: 0.25rem;
        }
      }
    </style>
  </head>
  <body>
    <main>
      <div class="faq-layout">
        <header class="intro-panel">
          <p class="eyebrow">MRHTML / Clear answers</p>
          <h1>A little clarity goes a long way.</h1>
          <p class="intro">
            A calm, useful FAQ built from native HTML. Open the questions that
            matter to you and keep the rest out of the way.
          </p>
          <p class="side-note">
            <span aria-hidden="true">↗</span
            ><span
              >No JavaScript required.<br />Use Tab to choose a question, then
              Enter or Space to open it.</span
            >
          </p>
        </header>
        <div>
          <section class="faq-list" aria-label="Frequently asked questions">
            <details open>
              <summary>
                What makes this FAQ work without JavaScript?<span
                  class="plus"
                  aria-hidden="true"
                ></span>
              </summary>
              <div class="answer">
                <p>
                  Each question uses a native <code>details</code> element with
                  a <code>summary</code> label. The browser handles opening,
                  closing, focus, and keyboard activation.
                </p>
                <p>
                  The CSS controls the spacing and visual indicator. The content
                  stays in the HTML, so the answer is still available when
                  scripts are blocked or disabled.
                </p>
              </div>
            </details>
            <details>
              <summary>
                Can I leave more than one answer open?<span
                  class="plus"
                  aria-hidden="true"
                ></span>
              </summary>
              <div class="answer">
                <p>
                  Yes. Every question is independent, so readers can compare
                  answers without repeatedly closing and reopening them. There
                  is no custom accordion state to synchronize.
                </p>
                <p>
                  The first answer starts open because its
                  <code>details</code> element has the
                  <code>open</code> attribute. Remove that attribute if you
                  prefer all answers to begin closed.
                </p>
              </div>
            </details>
            <details>
              <summary>
                How do I adapt the questions to my own project?<span
                  class="plus"
                  aria-hidden="true"
                ></span>
              </summary>
              <div class="answer">
                <p>
                  Duplicate a complete <code>details</code> block, write a clear
                  question in <code>summary</code>, and replace the content
                  inside <code>.answer</code>.
                </p>
                <ul>
                  <li>Use a question someone would actually ask.</li>
                  <li>Put the direct answer in the first sentence.</li>
                  <li>
                    Add a short list or second paragraph when the details help.
                  </li>
                  <li>
                    Keep important purchase terms or safety information visible
                    outside a collapsed FAQ too.
                  </li>
                </ul>
                <p>
                  There are no fixed answer heights. Longer text expands
                  naturally, including on a narrow screen or with larger text
                  settings.
                </p>
              </div>
            </details>
            <details>
              <summary>
                Does this need extra ARIA roles or custom keyboard
                handlers?<span class="plus" aria-hidden="true"></span>
              </summary>
              <div class="answer">
                <p>
                  No extra role or keyboard handler is needed for the native
                  disclosure controls. Adding a separate button,
                  <code>role="button"</code>, or manually maintained expanded
                  state to each summary would duplicate browser behavior.
                </p>
                <p>
                  The decorative plus sign is hidden from assistive technology.
                  Visible focus outlines make it clear which question is ready
                  to open.
                </p>
              </div>
            </details>
            <details>
              <summary>
                Will changing the colors affect readability?<span
                  class="plus"
                  aria-hidden="true"
                ></span>
              </summary>
              <div class="answer">
                <p>
                  It can. Start with the custom properties at the top of the
                  stylesheet, then check the contrast of question text, answer
                  text, borders, and keyboard focus indicators against their
                  backgrounds.
                </p>
                <p>
                  The MRHTML example uses ink on warm paper, a blue accent, and
                  generous line spacing. No animation is required to understand
                  the open and closed states.
                </p>
              </div>
            </details>
          </section>
          <aside class="afterword">
            <h2>Make the answer worth opening.</h2>
            <p>
              Replace these sample questions with real product, service, or
              documentation answers. Native controls provide the interaction;
              your content provides the value.
            </p>
          </aside>
        </div>
      </div>
      <footer class="footer-note">
        An original MRHTML example. Native details, useful answers, no
        dependencies.
      </footer>
    </main>
  </body>
</html>