FreeFeaturedFAQ

FAQ Accordion

Accessible accordion with auto-generated FAQPage schema.

#faq#accordion#schema#seo#accessibility

Live preview

See it in action.

Fully interactive, drag, click, scroll inside the frame, toggle to mobile.

About this section

A spec-compliant disclosure accordion using native <details>/<summary>. Auto-emits FAQPage JSON-LD for rich-result eligibility on Google. Block-driven content.

Install in 90 seconds

  1. 01

    Create /sections/modblo-faq-accordion.liquid.

  2. 02

    Paste the code and save.

  3. 03

    Add the section, then add Question blocks.

The Liquid

modblo-faq-accordion.liquid
{%- comment -%} modblo. FAQ Accordion (with FAQPage schema) {%- endcomment -%}
<section class="modblo-faq" data-section-id="{{ section.id }}"
  style="--modblo-bg: {{ section.settings.bg }}; --modblo-fg: {{ section.settings.fg }};">
  <div class="modblo-faq__inner page-width">
    {%- if section.settings.eyebrow != blank -%}
      <p class="modblo-faq__eyebrow">{{ section.settings.eyebrow }}</p>
    {%- endif -%}
    {%- if section.settings.heading != blank -%}
      <h2 class="modblo-faq__heading">{{ section.settings.heading }}</h2>
    {%- endif -%}

    <div class="modblo-faq__list">
      {%- for block in section.blocks -%}
        <details class="modblo-faq__item" {{ block.shopify_attributes }} {% if forloop.first and section.settings.open_first %}open{% endif %}>
          <summary>
            <span>{{ block.settings.question }}</span>
            <svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true">
              <path d="M4 6l4 4 4-4" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
          </summary>
          <div class="modblo-faq__answer">{{ block.settings.answer }}</div>
        </details>
      {%- endfor -%}
    </div>
  </div>
</section>

{%- comment -%} FAQPage JSON-LD for SEO {%- endcomment -%}
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {%- for block in section.blocks -%}
      {
        "@type": "Question",
        "name": {{ block.settings.question | json }},
        "acceptedAnswer": {
          "@type": "Answer",
          "text": {{ block.settings.answer | strip_html | json }}
        }
      }{% unless forloop.last %},{% endunless %}
    {%- endfor -%}
  ]
}
</script>

<style>
  .modblo-faq { background: var(--modblo-bg, #fff); color: var(--modblo-fg, #0b0b0c); padding: clamp(64px,10vw,128px) 0; }
  .modblo-faq__inner { max-width: 800px; margin: 0 auto; padding: 0 24px; }
  .modblo-faq__eyebrow { text-transform: uppercase; letter-spacing: .18em; font-size: 12px; opacity: .65; font-weight: 600; margin: 0 0 12px; }
  .modblo-faq__heading { font-size: clamp(28px,4vw,44px); letter-spacing: -.025em; margin: 0 0 32px; }
  .modblo-faq__list { display: grid; gap: 12px; }
  .modblo-faq__item {
    background: color-mix(in oklab, var(--modblo-fg) 3%, transparent);
    border: 1px solid color-mix(in oklab, var(--modblo-fg) 8%, transparent);
    border-radius: 14px; padding: 0 20px;
    transition: background .2s ease, border-color .2s ease;
  }
  .modblo-faq__item[open] {
    background: color-mix(in oklab, var(--modblo-fg) 5%, transparent);
    border-color: color-mix(in oklab, var(--modblo-fg) 14%, transparent);
  }
  .modblo-faq__item summary {
    list-style: none; cursor: pointer;
    display: flex; align-items: center; justify-content: space-between; gap: 16px;
    padding: 18px 0; font-weight: 600; font-size: 16px;
  }
  .modblo-faq__item summary::-webkit-details-marker { display: none; }
  .modblo-faq__item svg { transition: transform .25s cubic-bezier(.16,1,.3,1); flex: none; }
  .modblo-faq__item[open] svg { transform: rotate(180deg); }
  .modblo-faq__answer {
    padding: 0 0 18px;
    font-size: 15px; line-height: 1.6; opacity: .82;
  }
</style>

{% schema %}
{
  "name": "FAQ Accordion",
  "tag": "section",
  "settings": [
    { "type": "text", "id": "eyebrow", "label": "Eyebrow", "default": "FAQ" },
    { "type": "text", "id": "heading", "label": "Heading", "default": "Questions, answered." },
    { "type": "checkbox", "id": "open_first", "label": "Open first item by default", "default": true },
    { "type": "color", "id": "bg", "label": "Background", "default": "#ffffff" },
    { "type": "color", "id": "fg", "label": "Foreground", "default": "#0b0b0c" }
  ],
  "blocks": [{
    "type": "qa",
    "name": "Question",
    "settings": [
      { "type": "text", "id": "question", "label": "Question", "default": "How does shipping work?" },
      { "type": "richtext", "id": "answer", "label": "Answer",
        "default": "<p>Free standard shipping on orders over $75. Express options at checkout.</p>" }
    ]
  }],
  "max_blocks": 24,
  "presets": [{
    "name": "FAQ Accordion",
    "blocks": [{ "type": "qa" }, { "type": "qa" }, { "type": "qa" }]
  }]
}
{% endschema %}

Theme editor settings

SettingTypeDefault

Eyebrow

eyebrow

textFAQ

Heading

heading

textQuestions, answered.

Open first item

open_first

checkboxtrue

Background

bg

color#ffffff

Foreground

fg

color#0b0b0c

SEO & accessibility notes

  • Emits valid schema.org FAQPage JSON-LD, eligible for rich results.
  • Uses native <details>/<summary>, keyboard and screen-reader accessible by default.
  • Strip-html'd answer text in JSON-LD prevents schema validation errors.