Web programming

Toggle: A simple feature that switches specific content between being shown and hidden when clicked.

Accordion: A feature with multiple sections where clicking on a section header toggles the visibility of that section's content.

Toggle & Accordion

 Webサイトの一部のコンテンツを隠しておき、テキストをクリックすることで表示される技術は「トグル(toggle)」または「アコーディオン(accordion)」と呼ばれます。

トグル(Toggle)
トグルはシンプルに、クリックすることで特定のコンテンツを表示したり隠したりする方法です。
アコーディオン(Accordion)
アコーディオンは複数のセクションを持ち、各セクションのタイトルをクリックするとその内容が表示され、他のセクションの内容は隠される形式です。

 これらの技術は、HTML、CSS、および JavaScriptを使用して実装することが一般的です。例えば、jQueryや他の JavaScriptライブラリを使って、クリックイベントをトリガーにしてコンテンツの表示・非表示を制御します。

Toggle

シンプルなトグル

クリックしてコンテンツを表示

ここに隠されたコンテンツがあります。

HTML

<details>
	<summary>クリックしてコンテンツを表示</summary>
	<p>ここに隠されたコンテンツがあります。</p>
</details>

CSS

summary {
	padding: 1em 0;
	cursor: pointer;
}

 HTMLだけで実現できますが、ここでは、CSSを使って見た目(padding)の微調整と summary要素の上にカーソルが来ると見た目が変わり、クリックできることを明示するために cursor:pointer; を使っています。

 続いて、このトグルを JavaScriptを使って制御してみます。ここでは、ボタンを3つ用意して、それぞれに違った機能を設定しています。

クリックしてコンテンツを表示

ここに隠されたコンテンツがあります。

HTML

<details id="toggle">
	<summary>クリックしてコンテンツを表示</summary>
	<p>ここに隠されたコンテンツがあります。</p>
</details>
<button onclick="toggleDetails()">Toggle</button>
<button onclick="openDetails()">Open</button>
<button onclick="closeDetails()">Close</button>
<script>
	<!-- JavaScript code here -->
</script>

CSS

summary {
	padding: 1em 0;
	cursor: pointer;
}
button {
	display: inline-block;
	padding: 1ex 2ex;
	margin: 1ex;
	font-size: larger;
	box-shadow: 0.2ex 0.2ex 0.3ex;
}

JavaScript

function toggleDetails() {
	const details = document.getElementById('toggle');
	details.open = !details.open;
}

function openDetails() {
	const details = document.getElementById('toggle');
	details.open = true;
}

function closeDetails() {
	const details = document.getElementById('toggle');
	details.open = false;
}

Accordion

シンプルなアコーディオン

 トグルで使った、details要素を並べただけです。

クリックしてコンテンツを表示

ここに隠されたコンテンツがあります。

クリックしてコンテンツを表示

ここに隠されたコンテンツがあります。

クリックしてコンテンツを表示

ここに隠されたコンテンツがあります。

HTML

<details>
	<summary>クリックしてコンテンツを表示</summary>
	<p>ここに隠されたコンテンツがあります。</p>
</details>
<details>
	<summary>クリックしてコンテンツを表示</summary>
	<p>ここに隠されたコンテンツがあります。</p>
</details>
<details>
	<summary>クリックしてコンテンツを表示</summary>
	<p>ここに隠されたコンテンツがあります。</p>
</details>

CSS

summary {
	cursor: pointer;
}
details:first-of-type {
	margin-top: 1em;
}
details:last-of-type {
	margin-bottom: 1em;
}

 これも HTMLだけで実現できますが、ここでは、CSSを使って見た目(margin)の微調整と summary要素の上にカーソルが来ると見た目が変わり、クリックできることを明示するために cursor:pointer; を使っています。

 続いて、「Close all」ボタンを設置して、開いたアコーディオンをすべて閉じるように JavaScriptを使って設定します。

クリックしてコンテンツを表示

ここに隠されたコンテンツがあります。

クリックしてコンテンツを表示

ここに隠されたコンテンツがあります。

クリックしてコンテンツを表示

ここに隠されたコンテンツがあります。

HTML

<details>
	<summary>クリックしてコンテンツを表示</summary>
	<p>ここに隠されたコンテンツがあります。</p>
</details>
<details>
	<summary>クリックしてコンテンツを表示</summary>
	<p>ここに隠されたコンテンツがあります。</p>
</details>
<details>
	<summary>クリックしてコンテンツを表示</summary>
	<p>ここに隠されたコンテンツがあります。</p>
</details>
<button id="close-all">Close all</button>
<script>
	<!-- JavaScript code here -->
</script>

CSS

summary {
	cursor: pointer;
}
details:first-of-type {
	margin-top: 1em;
}
details:last-of-type {
	margin-bottom: 1em;
}
button {
	display: inline-block;
	padding: 1ex 2ex;
	margin: 1ex;
	font-size: larger;
	box-shadow: 0.2ex 0.2ex 0.3ex;
}

JavaScript

document.getElementById('close-all').addEventListener('click', function() {
	// すべての<details>要素を取得
	const detailsElements = document.querySelectorAll('details');
	
	// 各<details>要素を閉じる
	detailsElements.forEach(function(details) {
		details.removeAttribute('open');
	});
});

 続いて、「Close all」ボタンに設置していた閉じる機能を、各summary要素に適用させます。

クリックしてコンテンツを表示

ここに隠されたコンテンツがあります。

クリックしてコンテンツを表示

ここに隠されたコンテンツがあります。

クリックしてコンテンツを表示

ここに隠されたコンテンツがあります。

HTML

<details>
	<summary>クリックしてコンテンツを表示</summary>
	<p>ここに隠されたコンテンツがあります。</p>
</details>
<details>
	<summary>クリックしてコンテンツを表示</summary>
	<p>ここに隠されたコンテンツがあります。</p>
</details>
<details>
	<summary>クリックしてコンテンツを表示</summary>
	<p>ここに隠されたコンテンツがあります。</p>
</details>
<script>
	<!-- JavaScript code here -->
</script>

CSS

summary {
	cursor: pointer;
}
details:first-of-type {
	margin-top: 1em;
}
details:last-of-type {
	margin-bottom: 1em;
}

JavaScript

// すべての<summary>要素を取得
const summaryElements = document.querySelectorAll('summary');

// 各<summary>要素にクリックイベントリスナーを追加
summaryElements.forEach(function(summary) {
	summary.addEventListener('click', function() {
		// すべての<details>要素を取得
		const detailsElements = document.querySelectorAll('details');
		
		// 各<details>要素を閉じる
		detailsElements.forEach(function(details) {
			details.removeAttribute('open');
		});
	});
});

 これでクリックしたところだけが開き、それ以外の場所は閉じるという理想的なアコーディオンになりましたので、一旦良しとします。