検索

Accordion

このページは現在調整中です
Lism UI (@lism-css/ui) はまだ準備中です。

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

Preview
Accordion Example

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 Example

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 p='15'>
<Accordion.Header>
<Accordion.Label>Accordion Example</Accordion.Label>
<Accordion.Icon />
</Accordion.Header>
<Accordion.Body my-s='15'>
<Dummy length='l' />
</Accordion.Body>
</Accordion.Root>

基本構造

details.d--accordion
summary.d--accordion_header
span.d--accordion_label Accordion Label
span.d--accordion_icon
svg.a--icon
div.d--accordion_body
div.d--accordion_inner(.l--flow) ...Contents...

ソースコード

_style.css
@layer lism.modules {
	.d--accordion {
		--duration: var(--acc-duration, 0.25s);
	}
	.d--accordion[data-opened] {
		--_notOpen: ;
	}
	.d--accordion:not([data-opened]) {
		--_isOpen: ;
	}

	.d--accordion_header {
		display: grid;
		grid: auto / 1fr auto;
		gap: 0.5em;
		align-items: center;
		--focus-offset: -1px; /* overflow:hidden; で見えなくなってしまいがちなので内側に寄せておく */

		/* Safariで表示されるデフォルトの三角形アイコンを消す */
		&::-webkit-details-marker {
			display: none;
		}
	}

	.d--accordion_body {
		display: grid;
		grid: 1fr / auto;
		transition-property: margin-block, padding-block, opacity, grid-template;
		transition-duration: var(--duration);
	}

	/* ※ 正常な animation には必須 */
	.d--accordion_inner {
		overflow: hidden;
	}

	/* 閉じている時 */
	.d--accordion:not([data-opened]) > .d--accordion_body {
		grid: 0fr / auto;
		padding-block: 0 !important;
		margin-block: 0 !important;
	}

	/* アコーディオンブロックのネスト時、別のアイコンタイプにすると表示が崩れるがそこまでは考慮しない。 */
	.d--accordion_icon {
		display: grid;
	}

	/* .d--accordion_icon 自体にborderつけたりすると回転が見えてしまうので、中にある .a--icon を回転させる。 */
	.d--accordion_icon > .a--icon {
		transition: transform var(--duration);
		transform: var(--_isOpen, scaleY(-1));
	}
}

Import

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

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

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

  • <Accordion.Root>
  • <Accordion.Header>
  • <Accordion.Label>
  • <Accordion.Icon>
  • <Accordion.Body>

さらに、.HeaderLabel を使うと、.Header, .Label, .Icon をまとめて配置できるようになっています。

<Accordion.HeaderLabel {...props}>Text</Accordion.HeaderLabel>
↓ これは以下のように内部で展開されます
<Accordion.Header {...props}>
<Accordion.Label>Text</Accordion.Label>
<Accordion.Icon/>
</Accordion.Header>

Props

プロパティ説明
<Accordion.Icon>
icon
内部で呼び出される<Icon> に渡す icon を指定できます。ただし、<Accordion.Icon>に子要素が配置されている場合は無視されます。
<Accordion.Icon>
isTrigger
アイコンが buttonタグでの出力となり[data-role="trigger"]が付与されます。
<Accordion.Body>
flow
__innerに渡されます。

Examples

ラベルのHTMLタグとアイコンを変更する

ラベルをh3タグに、アイコンを x に変える例を紹介します。

Accordion Label

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 Label

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.

<Stack bd-y>
<Accordion.Root>
<Accordion.Header p="15">
<Accordion.Label tag='h3' f='inherit' fw='bold'>Accordion Label</Accordion.Label>
<Accordion.Icon>
<Icon viewBox="0 0 256 256" style={{transform: 'var(--_isOpen, rotate(45deg))'}}>
<path d="M228,128a12,12,0,0,1-12,12H140v76a12,12,0,0,1-24,0V140H40a12,12,0,0,1,0-24h76V40a12,12,0,0,1,24,0v76h76A12,12,0,0,1,228,128Z"></path>
</Icon>
</Accordion.Icon>
</Accordion.Header>
<Accordion.Body p='15' py-s='5'>
<Dummy length='l' />
</Accordion.Body>
</Accordion.Root>
<Accordion.Root bd-t>
<Accordion.Header p="15">
<Accordion.Label tag='h3' f='inherit' fw='bold'>Accordion Label</Accordion.Label>
<Accordion.Icon>
<Icon viewBox="0 0 256 256" style={{transform: 'var(--_isOpen, rotate(45deg))'}}>
<path d="M228,128a12,12,0,0,1-12,12H140v76a12,12,0,0,1-24,0V140H40a12,12,0,0,1,0-24h76V40a12,12,0,0,1,24,0v76h76A12,12,0,0,1,228,128Z"></path>
</Icon>
</Accordion.Icon>
</Accordion.Header>
<Accordion.Body p='15' py-s='5'>
<Dummy length='l' />
</Accordion.Body>
</Accordion.Root>
</Stack>

summary 内の hタグは、スクリーンリーダーで読み上げる際に見出しとして認識されないという問題があります。

アニメーション時間を変更し、アコーディオンの複数同時展開を禁止する

アコーディオンの開閉アニメーションの時間は--acc-durationで管理できるようになっており、親要素に変数をセットすると、複数のアコーディオンに対して一括管理できます。

:root--acc-durationを上書きすると、サイト全体でデフォルトの開閉速度を変更できます。

また、複数の<Accordion.Root>(.d--accordion)を含む親要素に [data-multiple="disallow"]を指定することで、アコーディオンを複数同時に開くことを禁止することが可能です。

Preview
Accordion Label

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 Label

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. Occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis undeomnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam.

Accordion Label

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.

<Stack g='1px' data-multiple='disallow' style={{'--acc-duration': '.2s'}}>
<Accordion.Root>
<Accordion.HeaderLabel p='20' bgc='text' c='base' hov="neutral">Accordion Label</Accordion.HeaderLabel>
<Accordion.Body p='20'>
<Dummy length='l' />
</Accordion.Body>
</Accordion.Root>
<Accordion.Root>
<Accordion.HeaderLabel p='20' bgc='text' c='base' hov="neutral">Accordion Label</Accordion.HeaderLabel>
<Accordion.Body p='20'>
<Dummy length='xl' />
</Accordion.Body>
</Accordion.Root>
<Accordion.Root>
<Accordion.HeaderLabel p='20' bgc='text' c='base' hov="neutral">Accordion Label</Accordion.HeaderLabel>
<Accordion.Body p='20'>
<Dummy length='l' />
</Accordion.Body>
</Accordion.Root>
...
</Stack>

Opt-in 機能

追加でCSSが必要な機能

開閉時にアイコンを切り替える方法

追加で少しCSSを加える必要がありますが、開閉時にアイコンを切り替える例も紹介します。

Example
Accordion Label

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 Label

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.

<Stack g='15'>
<Accordion.Root bgc='base' bxsh='10' bdrs='10' ov='hidden'>
<Accordion.Header p='20' bgc='base-2' hov='neutral'>
<Accordion.Label>Accordion Label</Accordion.Label>
<Accordion.Icon>
<Icon setTransition ga='1/1' viewBox="0 0 256 256">
<path d="M228,128a12,12,0,0,1-12,12H140v76a12,12,0,0,1-24,0V140H40a12,12,0,0,1,0-24h76V40a12,12,0,0,1,24,0v76h76A12,12,0,0,1,228,128Z"></path>
</Icon>
<Icon setTransition ga='1/1' viewBox="0 0 256 256">
<path d="M228,128a12,12,0,0,1-12,12H40a12,12,0,0,1,0-24H216A12,12,0,0,1,228,128Z"></path>
</Icon>
</Accordion.Icon>
</Accordion.Header>
<Accordion.Body p='20'>
<Dummy length='l' />
</Accordion.Body>
</Accordion.Root>
<Accordion.Root bgc='base' bxsh='10' bdrs='10' ov='hidden'>
<Accordion.Header p='20' bgc='base-2' hov='neutral'>
<Accordion.Label>Accordion Label</Accordion.Label>
<Accordion.Icon>
<Icon setTransition ga='1/1' viewBox="0 0 256 256">
<path d="M228,128a12,12,0,0,1-12,12H140v76a12,12,0,0,1-24,0V140H40a12,12,0,0,1,0-24h76V40a12,12,0,0,1,24,0v76h76A12,12,0,0,1,228,128Z"></path>
</Icon>
<Icon setTransition ga='1/1' viewBox="0 0 256 256">
<path d="M228,128a12,12,0,0,1-12,12H40a12,12,0,0,1,0-24H216A12,12,0,0,1,228,128Z"></path>
</Icon>
</Accordion.Icon>
</Accordion.Header>
<Accordion.Body p='20'>
<Dummy length='l' />
</Accordion.Body>
</Accordion.Root>
</Stack>

© Lism CSS. All rights reserved.