Docs
検索

Accordion

アコーディオン要素を作成できるUIコンポーネントです。

<details> / <summary> ではなく、<div> / <button> ベースで構成されており、JavaScriptで開閉アニメーションを制御します。 パネルには hidden="until-found" を活用しているため、アコーディオンが閉じた状態でもブラウザのページ内検索でコンテンツを検出でき、ヒット時に自動的にパネルが展開されます。

Overview

↓
Preview
<Accordion.Root>
<Accordion.Item>
<Accordion.Heading>
<Accordion.Button>Accordion Example 1</Accordion.Button>
</Accordion.Heading>
<Accordion.Panel>
<DummyText length="l" />
</Accordion.Panel>
</Accordion.Item>
</Accordion.Root>

<Accordion.Button> には、末尾に <Accordion.Icon> が自動的に配置されます。 アイコンはCSSの疑似要素(::before / ::after)で描画されるため、SVGの指定は不要です。

Styles

Accordion のベーススタイルは、以下のCSSで定義されています。

_style.css
@layer lism-block {
  .b--accordion {
    --duration: var(--acc-duration, 0.25s);
  }
  .b--accordion_item {
    --_panelH: 0px;
    --icon-transform: rotate(90deg);
  }

  /* 開いている時 */
  .b--accordion_item[data-opened] {
    --icon-transform: rotate(0deg);
    --_panelH: auto; /* Note: アニメーション時、jsでセットされる */
  }

  .b--accordion_button {
    display: flex;
    gap: var(--s15);
    align-items: center;
    justify-content: space-between;
    padding: var(--s15);
    width: 100%;
  }
  .b--accordion_panel {
    position: relative;
    overflow: hidden;
    height: var(--_panelH);
    transition: height var(--duration);
  }
  .b--accordion_content {
    /* _panel に padding を付けると閉じた時に余白が残るので _content に付ける */
    padding: var(--s15);
  }

  /* パネルが完全に閉じている時にabsoluteで飛ばしておくと、Chromeでも検索時に正常にハイライトされるようになる(なぜかは不明) */
  [hidden] > .b--accordion_content {
    position: absolute;
  }

  /* アイコンの描画 */
  .b--accordion_icon {
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 1em;
    height: 1em;

    &::before,
    &::after {
      content: '';
      display: block;
      grid-area: 1 / 1;
      background-color: currentColor;
      height: 0.1em;
      width: 87.5%;
      border-radius: 0.1em;
    }
    &::before {
      transition: transform var(--duration);
      transform: var(--icon-transform);
    }
  }

  /* フォーカス時のアウトラインを少し内側に寄せる( overflow:hidden によって途切れてしまうので)  */
  .b--accordion_button:focus-visible {
    outline: solid 2px currentColor;
    outline-color: revert;
    outline-offset: -3px; /* offset 調整だけだとブラウザ間の差が大きい */
  }

  /* --- 「視差効果を減らす」設定を考慮 --- */
  @media (prefers-reduced-motion: reduce) {
    .b--accordion_item {
      --duration: 0s;
    }
  }

  /* --- JSオフ環境の考慮 --- */
  @media (scripting: none) {
    .b--accordion_panel {
      height: auto !important;
      content-visibility: visible !important;
    }
    .b--accordion_content {
      position: static !important;
    }
  }
}

ソースコード全体は GitHub で公開しています。

How to use

@lism-css/ui パッケージでAccordionとして提供しています。

Import

import { Accordion } from '@lism-css/ui/react';

以下のコンポーネントが利用できます。

  • <Accordion.Root>: 複数のアコーディオンアイテムをラップするルート要素(レイアウトが必要な場合は layout="stack" などを指定できます)
  • <Accordion.Item>: 個別のアコーディオン要素
  • <Accordion.Heading>: 見出しエリアのラッパー(デフォルトは <div role="heading">)
  • <Accordion.Button>: 開閉トリガーのボタン(末尾に <Accordion.Icon> を自動で含みます)
  • <Accordion.Icon>: 開閉状態を示すアイコン(CSS疑似要素で描画)
  • <Accordion.Panel>: 開閉されるコンテンツパネル(hidden="until-found" を使用)

Props

プロパティ 説明
<Accordion.Root>
allowMultiple
複数のアコーディオンを同時に展開できるようにします。デフォルトでは一つしか展開できません。
<Accordion.Item>
isOpen
アイテムを初期状態で展開します(data-opened を付与)。<Accordion.Button> / <Accordion.Panel> の isOpen と併せて指定します。
<Accordion.Heading>
as
見出しのHTMLタグを指定します。デフォルトは div(role="heading" が自動付与されます)。h2〜h6 を指定すると role は付与されません。
<Accordion.Button>
isOpen
初期展開状態に合わせて aria-expanded を設定します。
<Accordion.Panel>
as
外側のパネル要素(.b--accordion_panel)のHTMLタグを指定します。デフォルトは div です。
<Accordion.Panel>
Lism Props
p、pt、flowなどのPropsは、内側のコンテンツ領域(.b--accordion_content)に渡されます。as、class(Astro)/className(React)、accID、isOpenは外側のパネル要素に適用されます。
<Accordion.Panel>
isOpen
パネルを初期表示します(hidden を解除)。

Examples

スタイリング例

↓
Preview
<Accordion.Root bd>
<Accordion.Item>
<Accordion.Heading>
<Accordion.Button p="20" hov={{bgc:"base-2"}}>Accordion Example 1</Accordion.Button>
</Accordion.Heading>
<Accordion.Panel p="20" pt="15">
<DummyText length="l" />
</Accordion.Panel>
</Accordion.Item>
<Accordion.Item bd-t>
<Accordion.Heading>
<Accordion.Button p="20" hov={{bgc:"base-2"}}>Accordion Example 2</Accordion.Button>
</Accordion.Heading>
<Accordion.Panel p="20" pt="15">
<DummyText length="l" />
</Accordion.Panel>
</Accordion.Item>
</Accordion.Root>

見出しタグを変更する

<Accordion.Heading> はデフォルトでは <div role="heading"> として出力されますが、as に h3 などの見出しタグを指定することで、実際の見出し要素として出力できます。

↓
例

<Accordion.Root bd>
<Accordion.Item>
<Accordion.Heading as="h3">
<Accordion.Button>Accordion Label</Accordion.Button>
</Accordion.Heading>
...
</Accordion.Item>
</Accordion.Root>

アニメーション時間を変更する

アコーディオンの開閉アニメーションの速度は --duration 変数で管理されており、デフォルトは 0.25s です。 <Accordion.Root>(全体)または <Accordion.Item>(個別)に CSS変数として指定することで変更できます。

↓
Preview
<Accordion.Root bd style={{ '--duration': '.15s' }}>
<Accordion.Item>...</Accordion.Item>
<Accordion.Item bd-t>...</Accordion.Item>
</Accordion.Root>

最初の一つを開いた状態にする

初期状態で展開しておきたいアイテムには、<Accordion.Item> / <Accordion.Button> / <Accordion.Panel> のそれぞれに isOpen を指定します。

isOpen はコンポーネントごとに役割が異なるため、3つ揃えて指定します。 <Accordion.Item> では data-opened を付与してパネルの高さとアイコンを開いた状態にし、<Accordion.Button> では aria-expanded を、<Accordion.Panel> では hidden の切り替えを担当します。

↓
Preview

Lorem ipsum dolor sit amet. Consectetur adipiscing elit, sed do eiusmod tempor Incididunt ut. Labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut. Aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint.

<Accordion.Root bd>
<Accordion.Item isOpen>
<Accordion.Heading>
<Accordion.Button hov={{bgc:"base-2"}} isOpen>Accordion Label 1</Accordion.Button>
</Accordion.Heading>
<Accordion.Panel isOpen>
<DummyText length="l" />
</Accordion.Panel>
</Accordion.Item>
<Accordion.Item bd-t>...</Accordion.Item>
<Accordion.Item bd-t>...</Accordion.Item>
</Accordion.Root>

複数同時展開を許可する

デフォルトでは、同じ <Accordion.Root> 内で一つのアコーディオンしか同時に展開できません。 allowMultiple を指定することで、複数を同時に展開できるようになります。

↓
Preview
<Accordion.Root allowMultiple bd>
<Accordion.Item>...</Accordion.Item>
<Accordion.Item bd-t>...</Accordion.Item>
<Accordion.Item bd-t>...</Accordion.Item>
</Accordion.Root>

© 2026 Lism CSS.