Accordion

Vertically stacked list of items, each item can be expanded or collapsed to reveal the content associated with that item.

Class name Type
.prs-accordion Component Container
.prs-accordion-content Component For content container
  • Default

    Make sure you use <details> and <summary> tags for the best accessibility.

    <div class="w-screen max-w-lg"> <!-- <- this is just for demo purposes -->
      <div class="prs-accordion">
        <details>
          <summary>Summary</summary>
          <div class="prs-accordion-content">
            Lorem ipsum dolor sit amet. Ad aute proident do eu ad eu consectetur ad esse incididunt mollit non.
          </div>
        </details>
        <details>
          <summary>Here's a summary with a very long label so we can test the wrapping and make sure the icon position, flex gap, and flex-shrink rules are working properly</summary>
          <div class="prs-accordion-content">
            Lorem ipsum dolor sit amet. Ad aute proident do eu ad eu consectetur ad esse incididunt mollit non.
          </div>
        </details>
        <details>
          <summary>The third summary</summary>
          <div class="prs-accordion-content">
            Lorem ipsum dolor sit amet. Ad aute proident do eu ad eu consectetur ad esse incididunt mollit non.
          </div>
        </details>
      </div>
    </div>
    
  • Exclusive

    Only one detail open at a time. Change the name attribute value.

    <div class="w-screen max-w-lg"> <!-- <- this is just for demo purposes -->
      <div class="prs-accordion">
        <details name="group-name" open>
          <summary>Summary 1</summary>
          <div class="prs-accordion-content">
            Lorem ipsum dolor sit amet. Ad aute proident do eu ad eu consectetur ad esse incididunt mollit non.
          </div>
        </details>
        <details name="group-name">
          <summary>Summary 2</summary>
          <div class="prs-accordion-content">
            Lorem ipsum dolor sit amet. Ad aute proident do eu ad eu consectetur ad esse incididunt mollit non.
          </div>
        </details>
        <details name="group-name">
          <summary>Summary 3</summary>
          <div class="prs-accordion-content">
            Lorem ipsum dolor sit amet. Ad aute proident do eu ad eu consectetur ad esse incididunt mollit non.
          </div>
        </details>
      </div>
    </div>
    

CSS

Full Library

Component Only

.prs-accordion {
  --marker-size: 1rem;
  --marker-gap: 0.5rem;
  border-top: 1px solid var(--prs-c-gray-300);
  border-bottom: 1px solid var(--prs-c-gray-300);

  :where(details) {
    interpolate-size: allow-keywords;
    padding: 0 1rem;

    &::details-content {
      block-size: 0;
      overflow: hidden;

      @media (prefers-reduced-motion: no-preference) {
        transition-property: all;
        transition-timing-function: var(--prs-transition-timing);
        transition-duration: var(--prs-transition-duration);
        transition-behavior: allow-discrete;
      }
    }

    &[open]::details-content {
      block-size: auto;
    }
  }

  > :where(:not(:last-child, [hidden])) {
    border-bottom: 1px solid var(--prs-c-gray-300);
  }

  :where(summary) {
    padding: 0.75rem 0;
    color: var(--prs-c-gray-900);
    font-weight: 600;
    display: flex;
    align-items: start;
    gap: var(--marker-gap);
    user-select: none;
    cursor: pointer;

    &::before {
      margin: 0.25rem 0;
      width: var(--marker-size);
      height: var(--marker-size);
      background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' width='16' height='16' fill='rgb(104 104 104)'><path fill-rule='evenodd' clip-rule='evenodd' d='m5.39972 1.40039-.93933.94667 5.65271 5.65333-5.65271 5.65331.93933.9467 6.59998-6.60001z' /></svg>");
      display: flex;
      flex-shrink: 0;
      align-items: center;
      justify-content: center;
      content: '';
      transition-property: var(--prs-transition-property);
      transition-timing-function: var(--prs-transition-timing);
      transition-duration: var(--prs-transition-duration);
    }

    &::marker,
    &::-webkit-details-marker {
      content: '';
    }
  }

  [open] :where(summary)::before {
    transform: rotate(90deg);
  }
}

.prs-accordion-content {
  margin-left: var(--marker-gap);
  padding-left: var(--marker-size);
  padding-bottom: 1.125rem;
}

Figma

Coming soon...