アコーディオンをHTMLとCSSだけで実装しよう

アコーディオンの表現をJavaScriptを使わずにHTMLとCSSで実装していきましょう。

目次

HTMLの基本の書き方

detailssummary要素を使うことでアコーディンの元となる表現が可能になります。summaryを押すことでその他の要素を開閉できます。

<details>
	<summary>質問が入ります。質問が入ります。質問が入ります。質問が入ります。質問が入ります。</summary>
	<div class="details__contents">
		<p>回答が入ります。回答が入ります。回答が入ります。回答が入ります。回答が入ります。回答が入ります。</p>
	</div>
</details>

開くとdetailsopen属性が付与されます。

<details open>
	<summary>質問が入ります。質問が入ります。質問が入ります。質問が入ります。質問が入ります。</summary>
	<div class="details__contents">
		<p>回答が入ります。回答が入ります。回答が入ります。回答が入ります。回答が入ります。回答が入ります。</p>
	</div>
</details>

summaryのアイコンを消す

summarydisplayにはlist-itemが指定されています。アイコンを消したい場合はdisplayの値を変えることで消すことが可能です。

summary {
	display: block;
}

また、Safariでは以下の通り::-webkit-details-markerの擬似要素で表現されています。不要でしたら消しましょう。

summary::-webkit-details-marker {
	display: inline-block;
	width: 0.66em;
	height: 0.66em;
	margin-inline-end: 0.4em;
}

summary::-webkit-details-marker {
	display: none;
}

見出し部分の装飾を当てる方法

見出しはsummaryに装飾を当てることができます。フレージングコンテンツに相当しますが、見出し(h1h6)も交ぜることが可能です。

summary {
	display: block;
	padding: 10px;
}

アイコンを追加する

summary {
	display: block;
	padding: 12px;
	position: relative;

	&::after {
		content: "↓";
		position: absolute;
		inset-inline-end: 12px;
		inset-block-start: 50%;
		translate: 0 -50%;
	}
}

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

開いた時にdetailsに追加される[open]属性を活用して開閉の状態に合わせたCSSを指定しましょう。

details {
	--animation-duration: 0.3s;
}

summary {
	&::after {
		transition: rotate 0.3s;
	}
}

details[open] {
	summary {
		&::after {
			rotate: 180deg;
		}
	}
}

コンテンツ部分の装飾を当てる方法

detailsのコンテンツ部分はsummary以外が相当します。そのコンテンツ部分は::details-contentの擬似要素で指定することが可能です。

活用例としては、開閉する際にアニメーションを当てることが可能になります。実装例としては以下の通りです。interpolate-size: allow-keywords;を指定することで、block-size0autoをアニメーションしながら切り替えることができます。

details {
	--animation-duration: 0.3s;
}

details::details-content {
	block-size: 0;
	overflow: hidden;
	transition: block-size var(--animation-duration), content-visibility var(--animation-duration) allow-discrete;
	interpolate-size: allow-keywords;
}

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

排他的なアコーディオンにする

detailsname属性を指定して同じ値を指定すると、排他的なアコーディンにすることが可能です。以下の例ではnameに同じqaを指定しています。

<details name="qa">
	<summary>質問が入ります。質問が入ります。質問が入ります。質問が入ります。質問が入ります。</summary>
	<div class="details__contents">
		<p>回答が入ります。回答が入ります。回答が入ります。回答が入ります。回答が入ります。回答が入ります。</p>
	</div>
</details>
<details name="qa">
	<summary>質問が入ります。質問が入ります。質問が入ります。質問が入ります。質問が入ります。</summary>
	<div class="details__contents">
		<p>回答が入ります。回答が入ります。回答が入ります。回答が入ります。回答が入ります。回答が入ります。</p>
	</div>
</details>
<details name="qa">
	<summary>質問が入ります。質問が入ります。質問が入ります。質問が入ります。質問が入ります。</summary>
	<div class="details__contents">
		<p>回答が入ります。回答が入ります。回答が入ります。回答が入ります。回答が入ります。回答が入ります。</p>
	</div>
</details>

detailssummary要素を使うメリット

隠れている部分がブラウザの検索機能に反応するようになります。以下の場合に「回答」と検索しすると、自動的に隠れている部分が開いてテキストがあることを教えてくれます。

<details>
	<summary>質問が入ります。質問が入ります。質問が入ります。質問が入ります。質問が入ります。</summary>
	<div class="details__contents">
		<p>回答が入ります。回答が入ります。回答が入ります。回答が入ります。回答が入ります。回答が入ります。</p>
	</div>
</details>

この記事が気に入ったら
フォローしてね!

この記事を書いた人

WordPressが得意なWeb屋。HPcode代表。

300件以上のWordPressカスタマイズを対応してきました。SE → 農家 → アフィリエイター → Web屋。生まれは三重県。

目次