Starting Point
v0.33.1

Search documentation

Search for a page and jump to it.

Start typing to search...
Go to Page
escClose

Tailwind CSS Accordion

Use the accordion component to stack sections that expand and collapse in place, like the questions of an FAQ or the steps of a setup guide. For a single independent section, use a collapsible.

<div class="accordion w-full max-w-lg">
  <div class="accordion-item">
    <h3>
      <button id="acc-shipping" class="accordion-trigger" aria-expanded="true">
        What are your shipping options?
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
      </button>
    </h3>
    <div class="accordion-panel expanded" data-sp-toggle="#acc-shipping">
      <div class="accordion-content">
        We offer standard (5-7 days), express (2-3 days), and overnight
        shipping. Free shipping on international orders.
      </div>
    </div>
  </div>
  <div class="accordion-item">
    <h3>
      <button id="acc-returns" class="accordion-trigger">
        What is your return policy?
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
      </button>
    </h3>
    <div class="accordion-panel" data-sp-toggle="#acc-returns">
      <div class="accordion-content">
        Returns accepted within 30 days. Items must be unused and in original
        packaging. Refunds processed within 5-7 business days.
      </div>
    </div>
  </div>
  <div class="accordion-item">
    <h3>
      <button id="acc-support" class="accordion-trigger">
        How can I contact customer support?
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
      </button>
    </h3>
    <div class="accordion-panel" data-sp-toggle="#acc-support">
      <div class="accordion-content">
        Reach us via email, live chat, or phone. We respond within 24 hours
        during business days.
      </div>
    </div>
  </div>
</div>

Usage

Add the accordion class to the wrapper and compose each section from an item, a trigger, and a panel. The panel points at its trigger with data-sp-toggle. Opening a section closes the others.

ClassDescription
accordionAdd to the wrapper, which carries the data-sp-* options
accordion-itemAdd to each section, drawing the divider to the next one
accordion-triggerAdd to the <button>, wrapped in a heading
accordion-panelAdd to the collapsing element, where expanded starts it open
accordion-contentAdd to the inner wrapper holding the section's content
<div class="accordion">
  <div class="accordion-item">
    <h3>
      <button id="section-1" class="accordion-trigger">Section title</button>
    </h3>
    <div class="accordion-panel" data-sp-toggle="#section-1">
      <div class="accordion-content">Section content.</div>
    </div>
  </div>
</div>

You can include an icon in the trigger, most commonly a chevron as its last child, which is sized and styled for you. The trigger's aria-expanded follows the state, so in-aria-expanded:rotate-180 rotates it while the section is open:

<button id="section-1" class="accordion-trigger">
  Section title
  <svg class="in-aria-expanded:rotate-180" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>
</button>

Examples

Multiple open sections

Add data-sp-multiple and sections open independently.

<div class="accordion w-full max-w-lg" data-sp-multiple>
  <div class="accordion-item">
    <h3>
      <button
        id="acc-notifications"
        class="accordion-trigger"
        aria-expanded="true"
      >
        Notification Settings
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
      </button>
    </h3>
    <div class="accordion-panel expanded" data-sp-toggle="#acc-notifications">
      <div class="accordion-content">
        Choose which updates you want to receive and how: email, push, or in-app
        notifications.
      </div>
    </div>
  </div>
  <div class="accordion-item">
    <h3>
      <button id="acc-privacy" class="accordion-trigger">
        Privacy & Security
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
      </button>
    </h3>
    <div class="accordion-panel" data-sp-toggle="#acc-privacy">
      <div class="accordion-content">
        Control who can see your profile and activity, and manage two-factor
        authentication.
      </div>
    </div>
  </div>
  <div class="accordion-item">
    <h3>
      <button id="acc-billing-m" class="accordion-trigger">
        Billing & Subscription
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
      </button>
    </h3>
    <div class="accordion-panel" data-sp-toggle="#acc-billing-m">
      <div class="accordion-content">
        Update your payment method, view invoices, and manage your subscription
        plan.
      </div>
    </div>
  </div>
</div>

Initially open

Author the expanded class on a panel to start it open, and mirror aria-expanded="true" onto its trigger so state-driven styling, like the rotated chevron, paints correctly before JavaScript loads.

<div class="accordion w-full max-w-lg">
  <div class="accordion-item">
    <h3>
      <button id="acc-open-trial" class="accordion-trigger">
        Is there a free trial?
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
      </button>
    </h3>
    <div class="accordion-panel" data-sp-toggle="#acc-open-trial">
      <div class="accordion-content">
        Yes, every plan starts with a 14-day free trial. No credit card
        required.
      </div>
    </div>
  </div>
  <div class="accordion-item">
    <h3>
      <button id="acc-open-refund" class="accordion-trigger" aria-expanded="true">
        Can I get a refund?
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
      </button>
    </h3>
    <div class="accordion-panel expanded" data-sp-toggle="#acc-open-refund">
      <div class="accordion-content">
        Contact us within 30 days of purchase and we refund you in full, no
        questions asked.
      </div>
    </div>
  </div>
</div>

Accordion icons

The chevron is plain markup, so swap it for another icon, move it in front of the title, or leave it out. Nothing moves on its own: in-aria-expanded:rotate-180 on the svg is what turns it while the section is open.

<div class="accordion w-full max-w-lg">
  <div class="accordion-item">
    <h3>
      <button id="acc-icon-chevron" class="accordion-trigger" aria-expanded="true">
        Chevron
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
      </button>
    </h3>
    <div class="accordion-panel expanded" data-sp-toggle="#acc-icon-chevron">
      <div class="accordion-content">
        The classic indicator: a chevron as the trigger's last child, rotating
        as the section opens.
      </div>
    </div>
  </div>
  <div class="accordion-item">
    <h3>
      <button id="acc-icon-plus" class="accordion-trigger">
        Plus and minus
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="M5 12h14"/><path d="M12 5v14" class="transition-opacity duration-200 in-aria-expanded:opacity-0"/></svg>
      </button>
    </h3>
    <div class="accordion-panel" data-sp-toggle="#acc-icon-plus">
      <div class="accordion-content">
        A plus whose vertical line fades away as the icon turns, leaving a
        minus while the section is open.
      </div>
    </div>
  </div>
  <div class="accordion-item">
    <h3>
      <button id="acc-icon-lead-chevron" class="accordion-trigger">
        <span class="flex items-center gap-2">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4 shrink-0 text-muted-foreground transition-transform duration-200 in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
          Leading chevron
        </span>
      </button>
    </h3>
    <div class="accordion-panel" data-sp-toggle="#acc-icon-lead-chevron">
      <div class="accordion-content">
        The same chevron wrapped in a flex span before the title instead of at
        the end.
      </div>
    </div>
  </div>
  <div class="accordion-item">
    <h3>
      <button id="acc-icon-lead-plus" class="accordion-trigger">
        <span class="flex items-center gap-2">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4 shrink-0 text-muted-foreground transition-transform duration-200 in-aria-expanded:rotate-180"><path d="M5 12h14"/><path d="M12 5v14" class="transition-opacity duration-200 in-aria-expanded:opacity-0"/></svg>
          Leading plus and minus
        </span>
      </button>
    </h3>
    <div class="accordion-panel" data-sp-toggle="#acc-icon-lead-plus">
      <div class="accordion-content">
        The plus and minus morph works in the leading position too.
      </div>
    </div>
  </div>
  <div class="accordion-item">
    <h3>
      <button id="acc-icon-none" class="accordion-trigger">No icon</button>
    </h3>
    <div class="accordion-panel" data-sp-toggle="#acc-icon-none">
      <div class="accordion-content">
        No indicator at all. The trigger is just text.
      </div>
    </div>
  </div>
</div>

Disabled

Add disabled to a trigger to lock its section.

<div class="accordion w-full max-w-lg">
  <div class="accordion-item">
    <h3>
      <button id="acc-history" class="accordion-trigger">
        Can I access my account history?
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
      </button>
    </h3>
    <div class="accordion-panel" data-sp-toggle="#acc-history">
      <div class="accordion-content">
        Yes, you can view your complete account history including all
        transactions, plan changes, and support tickets in the Account History
        section of your dashboard.
      </div>
    </div>
  </div>
  <div class="accordion-item">
    <h3>
      <button id="acc-premium" class="accordion-trigger" disabled>
        Premium feature information
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
      </button>
    </h3>
    <div class="accordion-panel" data-sp-toggle="#acc-premium">
      <div class="accordion-content">
        This section contains information about premium features. Upgrade your
        plan to access this content.
      </div>
    </div>
  </div>
  <div class="accordion-item">
    <h3>
      <button id="acc-email" class="accordion-trigger">
        How do I update my email address?
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
      </button>
    </h3>
    <div class="accordion-panel" data-sp-toggle="#acc-email">
      <div class="accordion-content">
        You can update your email address in your account settings. You'll
        receive a verification email at your new address to confirm the change.
      </div>
    </div>
  </div>
</div>

Bordered accordion

Wrap the accordion in a border and inset the items.

<div class="accordion w-full max-w-lg rounded-lg border">
  <div class="accordion-item px-4">
    <h3>
      <button id="acc-billing-b" class="accordion-trigger" aria-expanded="true">
        How does billing work?
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
      </button>
    </h3>
    <div class="accordion-panel expanded" data-sp-toggle="#acc-billing-b">
      <div class="accordion-content">
        We bill monthly or annually, with a discount for annual plans. Your card
        is charged at the start of each cycle.
      </div>
    </div>
  </div>
  <div class="accordion-item px-4">
    <h3>
      <button id="acc-security-b" class="accordion-trigger">
        Is my data secure?
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
      </button>
    </h3>
    <div class="accordion-panel" data-sp-toggle="#acc-security-b">
      <div class="accordion-content">
        All data is encrypted in transit and at rest, and we run independent
        security audits every year.
      </div>
    </div>
  </div>
  <div class="accordion-item px-4">
    <h3>
      <button id="acc-integration-b" class="accordion-trigger">
        What integrations do you support?
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
      </button>
    </h3>
    <div class="accordion-panel" data-sp-toggle="#acc-integration-b">
      <div class="accordion-content">
        We integrate with the major productivity, analytics, and communication
        tools your team already uses.
      </div>
    </div>
  </div>
</div>

Accordion in a card

An accordion slots into a card for a framed FAQ.

<div class="card w-full max-w-lg">
  <div class="card-header">
    <h3 class="card-title">Subscription &amp; Billing</h3>
    <p class="card-description">
      Common questions about your account, plans, payments and cancellations.
    </p>
  </div>
  <div class="card-content">
    <div class="accordion">
      <div class="accordion-item">
        <h3>
          <button id="acc-plans" class="accordion-trigger" aria-expanded="true">
            What subscription plans do you offer?
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
          </button>
        </h3>
        <div class="accordion-panel expanded" data-sp-toggle="#acc-plans">
          <div class="accordion-content">
            We offer Free, Pro, and Enterprise plans. Each tier adds more seats,
            storage, and support options.
          </div>
        </div>
      </div>
      <div class="accordion-item">
        <h3>
          <button id="acc-billing-c" class="accordion-trigger">
            How does billing work?
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
          </button>
        </h3>
        <div class="accordion-panel" data-sp-toggle="#acc-billing-c">
          <div class="accordion-content">
            We bill monthly or annually, with a discount for annual plans. Your
            card is charged at the start of each cycle.
          </div>
        </div>
      </div>
      <div class="accordion-item">
        <h3>
          <button id="acc-cancel" class="accordion-trigger">
            How do I cancel my subscription?
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
          </button>
        </h3>
        <div class="accordion-panel" data-sp-toggle="#acc-cancel">
          <div class="accordion-content">
            Cancel anytime from your billing settings. Your plan stays active
            until the end of the paid period.
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

RTL

Add dir="rtl" to any parent element, typically <html>, to render right-to-left. See the RTL guide for details.

<div id="accordion-rtl-demo" class="accordion w-full max-w-lg" dir="rtl">
  <div class="accordion-item">
    <h3>
      <button
        id="accordion-rtl-password"
        class="accordion-trigger"
        aria-expanded="true"
      >
        <span data-i18n="q1">كيف يمكنني إعادة تعيين كلمة المرور؟</span>
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
    </button>
    </h3>
    <div class="accordion-panel expanded" data-sp-toggle="#accordion-rtl-password">
      <div class="accordion-content" data-i18n="a1">
        انقر على «نسيت كلمة المرور» في صفحة تسجيل الدخول وسنرسل لك رابطًا
        لإعادة تعيين كلمة المرور.
      </div>
    </div>
  </div>
  <div class="accordion-item">
    <h3>
      <button id="accordion-rtl-plan" class="accordion-trigger">
        <span data-i18n="q2">هل يمكنني تغيير خطة الاشتراك الخاصة بي؟</span>
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
    </button>
    </h3>
    <div class="accordion-panel" data-sp-toggle="#accordion-rtl-plan">
      <div class="accordion-content" data-i18n="a2">
        نعم، يمكنك ترقية أو تخفيض خطتك في أي وقت من إعدادات حسابك.
      </div>
    </div>
  </div>
  <div class="accordion-item">
    <h3>
      <button id="accordion-rtl-payment" class="accordion-trigger">
        <span data-i18n="q3">ما هي طرق الدفع التي تقبلونها؟</span>
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="in-aria-expanded:rotate-180"><path d="m6 9 6 6 6-6"/></svg>
    </button>
    </h3>
    <div class="accordion-panel" data-sp-toggle="#accordion-rtl-payment">
      <div class="accordion-content" data-i18n="a3">
        نقبل جميع بطاقات الائتمان الرئيسية و PayPal والتحويلات المصرفية.
      </div>
    </div>
  </div>
</div>
 
<script>
  const translations = {
    ar: {
      dir: "rtl",
      q1: "كيف يمكنني إعادة تعيين كلمة المرور؟",
      a1: "انقر على «نسيت كلمة المرور» في صفحة تسجيل الدخول وسنرسل لك رابطًا لإعادة تعيين كلمة المرور.",
      q2: "هل يمكنني تغيير خطة الاشتراك الخاصة بي؟",
      a2: "نعم، يمكنك ترقية أو تخفيض خطتك في أي وقت من إعدادات حسابك.",
      q3: "ما هي طرق الدفع التي تقبلونها؟",
      a3: "نقبل جميع بطاقات الائتمان الرئيسية و PayPal والتحويلات المصرفية.",
    },
    he: {
      dir: "rtl",
      q1: "איך אני מאפס את הסיסמה שלי?",
      a1: "לחץ על 'שכחתי סיסמה' בעמוד ההתחברות ונשלח לך קישור לאיפוס הסיסמה.",
      q2: "האם אני יכול לשנות את תוכנית המנוי שלי?",
      a2: "כן, אתה יכול לשדרג או להוריד את התוכנית שלך בכל עת מהגדרות החשבון.",
      q3: "אילו אמצעי תשלום אתם מקבלים?",
      a3: "אנו מקבלים כרטיסי אשראי, PayPal והעברות בנקאיות.",
    },
    en: {
      dir: "ltr",
      q1: "How do I reset my password?",
      a1: "Click 'Forgot Password' on the login page and we'll send you a link to reset your password.",
      q2: "Can I change my subscription plan?",
      a2: "Yes, you can upgrade or downgrade your plan at any time from your account settings.",
      q3: "What payment methods do you accept?",
      a3: "We accept all major credit cards, PayPal, and bank transfers.",
    },
  };
  window.addEventListener("message", (e) => {
    const t = translations[e.data?.lang];
    if (e.data?.type !== "sp-language" || !t) return;
    document.getElementById("accordion-rtl-demo").dir = t.dir;
    document.querySelectorAll("[data-i18n]").forEach((el) => {
      el.textContent = t[el.dataset.i18n];
    });
  });
</script>

Options

Accordion

Set each option with its own data-sp-* attribute on the accordion element.

AttributeValuesDefault
data-sp-multipleBooleanfalse

Each accordion-panel points at its trigger with its own data-sp-toggle attribute.

JavaScript

Events

The panels are collapsibles, so their lifecycle events fire on each panel and bubble. The before* events are cancelable.

EventWhen
sp-beforeexpandBefore expanding (cancelable)
sp-expandExpanding
sp-expandedExpanded and settled
sp-beforecollapseBefore collapsing (cancelable)
sp-collapseCollapsing
sp-collapsedCollapsed and settled
accordion.addEventListener("sp-expand", (e) => {
  console.log("opening", e.target.id);
});

Methods

Each panel is a collapsible, so drive one with sp.collapsible(panel):

MethodDescription
expand()Expand the panel (closing siblings unless multiple)
collapse()Collapse the panel
toggle()Expand if collapsed, else collapse
sp.collapsible(document.querySelector("#section-1-panel")).expand();