Bootstrapモーダル・カルーセル・アコーディオン
インタラクティブなコンポーネント
Bootstrapのモーダル、カルーセル、アコーディオンの使い方を解説。JavaScript制御やカスタマイズ方法まで学べます。
こんな人向けの記事です
- Bootstrapのモーダルを実装したい
- 画像スライダー(カルーセル)を作りたい
- アコーディオンメニューを実装したい
Step 1モーダルの基本構造
モーダルは画面の上にオーバーレイ表示されるダイアログです。確認メッセージ、フォーム入力、詳細情報の表示などに使います。
HTML
<!-- モーダルを開くボタン -->
<button type="button" class="btn btn-primary"
data-bs-toggle="modal" data-bs-target="#myModal">
モーダルを開く
</button>
<!-- モーダル本体 -->
<div class="modal fade" id="myModal" tabindex="-1"
aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="myModalLabel">タイトル</h5>
<button type="button" class="btn-close"
data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
モーダルの本文がここに入ります。
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary"
data-bs-dismiss="modal">閉じる</button>
<button type="button" class="btn btn-primary">保存</button>
</div>
</div>
</div>
</div>
モーダルの3層構造
.modal → 背景オーバーレイ(画面全体を覆う).modal-dialog → ダイアログの位置・サイズ制御.modal-content → 実際のコンテンツ(header / body / footer)
モーダルのサイズは .modal-dialog にクラスを追加して変更できます。
| クラス | 最大幅 | 用途 |
|---|---|---|
modal-sm | 300px | 確認ダイアログ |
| (デフォルト) | 500px | 一般的な用途 |
modal-lg | 800px | フォーム・詳細表示 |
modal-xl | 1140px | 大きなコンテンツ |
modal-fullscreen | 100% | 全画面表示 |
HTML
<!-- 大きいモーダル -->
<div class="modal-dialog modal-lg">...</div>
<!-- 中央寄せモーダル -->
<div class="modal-dialog modal-dialog-centered">...</div>
<!-- スクロール可能なモーダル -->
<div class="modal-dialog modal-dialog-scrollable">...</div>
Step 2モーダルのJavaScript制御
データ属性(data-bs-toggle)を使わず、JavaScriptでモーダルを制御できます。動的な処理が必要な場合に便利です。
JavaScript
// モーダルのインスタンスを取得
const myModal = new bootstrap.Modal(document.getElementById("myModal"));
// 表示
myModal.show();
// 非表示
myModal.hide();
// 表示/非表示の切り替え
myModal.toggle();
モーダルにはイベントが用意されており、開閉時に処理を実行できます。
JavaScript
const modalEl = document.getElementById("myModal");
// モーダルが完全に表示された後に実行
modalEl.addEventListener("shown.bs.modal", function () {
console.log("モーダルが表示されました");
// 例: フォームの最初の入力欄にフォーカス
document.getElementById("inputName").focus();
});
// モーダルが完全に非表示になった後に実行
modalEl.addEventListener("hidden.bs.modal", function () {
console.log("モーダルが閉じました");
// 例: フォームをリセット
document.getElementById("myForm").reset();
});
| イベント名 | タイミング |
|---|---|
show.bs.modal | 表示が開始される直前 |
shown.bs.modal | 表示アニメーション完了後 |
hide.bs.modal | 非表示が開始される直前 |
hidden.bs.modal | 非表示アニメーション完了後 |
Step 3モーダル内のフォーム
モーダル内にフォームを配置する場合、送信処理と閉じる処理を適切に組み合わせることが重要です。
HTML
<div class="modal fade" id="formModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<form id="myForm" action="/submit" method="POST">
<div class="modal-header">
<h5 class="modal-title">お問い合わせ</h5>
<button type="button" class="btn-close"
data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label for="inputName" class="form-label">お名前</label>
<input type="text" class="form-control"
id="inputName" required>
</div>
<div class="mb-3">
<label for="inputEmail" class="form-label">メール</label>
<input type="email" class="form-control"
id="inputEmail" required>
</div>
<div class="mb-3">
<label for="inputMessage" class="form-label">メッセージ</label>
<textarea class="form-control"
id="inputMessage" rows="3"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary"
data-bs-dismiss="modal">キャンセル</button>
<button type="submit" class="btn btn-primary">送信</button>
</div>
</form>
</div>
</div>
</div>
フォームの配置に注意
<form> タグは .modal-content の直下に配置し、header・body・footer を囲みます。こうすることで送信ボタンを footer に置いても正しくフォームが送信されます。
確認ダイアログとしてモーダルを使う例です。削除前の確認などに便利です。
HTML + JavaScript
<!-- 削除確認モーダル -->
<div class="modal fade" id="confirmDelete" tabindex="-1">
<div class="modal-dialog modal-sm modal-dialog-centered">
<div class="modal-content">
<div class="modal-body text-center py-4">
<p class="mb-0">本当に削除しますか?</p>
</div>
<div class="modal-footer justify-content-center">
<button class="btn btn-secondary"
data-bs-dismiss="modal">キャンセル</button>
<button class="btn btn-danger"
id="confirmDeleteBtn">削除する</button>
</div>
</div>
</div>
</div>
<script>
document.getElementById("confirmDeleteBtn")
.addEventListener("click", function () {
// 削除処理を実行
fetch("/api/delete/" + targetId, { method: "DELETE" })
.then(() => {
bootstrap.Modal.getInstance(
document.getElementById("confirmDelete")
).hide();
});
});
</script>
Step 4カルーセルの基本構造
カルーセル(スライダー)は、画像やコンテンツを順番にスライド表示するコンポーネントです。
HTML
<div id="myCarousel" class="carousel slide"
data-bs-ride="carousel">
<!-- スライド本体 -->
<div class="carousel-inner">
<div class="carousel-item active">
<img src="slide1.jpg" class="d-block w-100" alt="スライド1">
</div>
<div class="carousel-item">
<img src="slide2.jpg" class="d-block w-100" alt="スライド2">
</div>
<div class="carousel-item">
<img src="slide3.jpg" class="d-block w-100" alt="スライド3">
</div>
</div>
<!-- 前後のコントロール -->
<button class="carousel-control-prev" type="button"
data-bs-target="#myCarousel" data-bs-slide="prev">
<span class="carousel-control-prev-icon"></span>
</button>
<button class="carousel-control-next" type="button"
data-bs-target="#myCarousel" data-bs-slide="next">
<span class="carousel-control-next-icon"></span>
</button>
</div>
カルーセルの必須ポイント
.carousel-item の1つに必ず active クラスを付けること(なければ何も表示されません)data-bs-ride="carousel" で自動スライドが有効になります画像には
d-block w-100 を付けてレスポンシブ表示にします
スライドにキャプション(テキスト)を追加できます。
HTML
<div class="carousel-item active">
<img src="slide1.jpg" class="d-block w-100" alt="...">
<div class="carousel-caption d-none d-md-block">
<h5>スライドのタイトル</h5>
<p>スライドの説明文がここに入ります。</p>
</div>
</div>
Step 5カルーセルのオプション
カルーセルのインジケーター(現在のスライド位置を示すドット)を追加できます。
HTML
<div id="myCarousel" class="carousel slide" data-bs-ride="carousel">
<!-- インジケーター -->
<div class="carousel-indicators">
<button type="button" data-bs-target="#myCarousel"
data-bs-slide-to="0" class="active"></button>
<button type="button" data-bs-target="#myCarousel"
data-bs-slide-to="1"></button>
<button type="button" data-bs-target="#myCarousel"
data-bs-slide-to="2"></button>
</div>
<div class="carousel-inner">
<div class="carousel-item active">...</div>
<div class="carousel-item">...</div>
<div class="carousel-item">...</div>
</div>
<!-- コントロール省略 -->
</div>
データ属性やJavaScriptでカルーセルの動作をカスタマイズできます。
| オプション | デフォルト | 説明 |
|---|---|---|
data-bs-interval | 5000 | 自動スライドの間隔(ミリ秒) |
data-bs-ride | false | "carousel" で自動再生 |
data-bs-wrap | true | 最後のスライドから最初に戻るか |
data-bs-pause | "hover" | ホバー時に一時停止 |
data-bs-touch | true | スワイプ操作の有効/無効 |
HTML
<!-- 3秒間隔・ループなし -->
<div class="carousel slide" data-bs-ride="carousel"
data-bs-interval="3000" data-bs-wrap="false">
...
</div>
<!-- スライドごとに異なる間隔 -->
<div class="carousel-item active" data-bs-interval="2000">
<img src="slide1.jpg" class="d-block w-100" alt="...">
</div>
<div class="carousel-item" data-bs-interval="4000">
<img src="slide2.jpg" class="d-block w-100" alt="...">
</div>
JavaScriptでカルーセルを制御することもできます。
JavaScript
const carousel = new bootstrap.Carousel(
document.getElementById("myCarousel"), {
interval: 3000, // 3秒間隔
wrap: true, // ループする
pause: "hover" // ホバーで一時停止
}
);
// 次のスライドへ
carousel.next();
// 前のスライドへ
carousel.prev();
// 指定のスライドへ(0始まり)
carousel.to(2);
// 自動スライドを停止
carousel.pause();
// 自動スライドを再開
carousel.cycle();
フェードアニメーション
.carousel に carousel-fade クラスを追加すると、スライドではなくフェードで切り替わります。<div class="carousel slide carousel-fade">
Step 6アコーディオンの使い方
アコーディオンは、クリックで開閉するコンテンツパネルです。FAQやカテゴリ別の情報表示に適しています。
HTML
<div class="accordion" id="myAccordion">
<!-- アイテム1 -->
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button"
data-bs-toggle="collapse"
data-bs-target="#collapse1">
アコーディオンアイテム #1
</button>
</h2>
<div id="collapse1" class="accordion-collapse collapse show"
data-bs-parent="#myAccordion">
<div class="accordion-body">
最初のアイテムの内容です。デフォルトで開いた状態です。
</div>
</div>
</div>
<!-- アイテム2 -->
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button"
data-bs-toggle="collapse"
data-bs-target="#collapse2">
アコーディオンアイテム #2
</button>
</h2>
<div id="collapse2" class="accordion-collapse collapse"
data-bs-parent="#myAccordion">
<div class="accordion-body">
2番目のアイテムの内容です。
</div>
</div>
</div>
<!-- アイテム3 -->
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button"
data-bs-toggle="collapse"
data-bs-target="#collapse3">
アコーディオンアイテム #3
</button>
</h2>
<div id="collapse3" class="accordion-collapse collapse"
data-bs-parent="#myAccordion">
<div class="accordion-body">
3番目のアイテムの内容です。
</div>
</div>
</div>
</div>
アコーディオンの仕組み
data-bs-parent="#myAccordion" を指定すると、1つ開くと他が自動で閉じます(排他制御)この属性を省略すると、複数のアイテムを同時に開くことができます
デフォルトで開きたいアイテムには
collapse show を付けます
枠線なしのフラットなデザインにするには .accordion-flush を使います。
HTML
<!-- フラットなアコーディオン(枠線なし) -->
<div class="accordion accordion-flush" id="flushAccordion">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button"
data-bs-toggle="collapse"
data-bs-target="#flush1">
フラッシュアイテム #1
</button>
</h2>
<div id="flush1" class="accordion-collapse collapse"
data-bs-parent="#flushAccordion">
<div class="accordion-body">
枠線のないシンプルなデザインです。
</div>
</div>
</div>
</div>
閉じた状態のボタンには collapsed を付ける
.accordion-button に collapsed クラスがないと、矢印アイコンの向きが正しく表示されません。デフォルトで閉じているアイテムには必ず collapsed を付けてください。
アコーディオンをFAQとして活用する例です。
HTML
<h2>よくある質問</h2>
<div class="accordion" id="faqAccordion">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button"
data-bs-toggle="collapse"
data-bs-target="#faq1">
送料はいくらですか?
</button>
</h2>
<div id="faq1" class="accordion-collapse collapse"
data-bs-parent="#faqAccordion">
<div class="accordion-body">
全国一律550円です。5,000円以上のお買い上げで送料無料です。
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button"
data-bs-toggle="collapse"
data-bs-target="#faq2">
返品は可能ですか?
</button>
</h2>
<div id="faq2" class="accordion-collapse collapse"
data-bs-parent="#faqAccordion">
<div class="accordion-body">
商品到着後7日以内であれば返品可能です。
</div>
</div>
</div>
</div>
まとめ
.modal+data-bs-toggle="modal"でモーダルを表示new bootstrap.Modal()でJavaScript制御(show / hide / toggle)- モーダル内フォームは
.modal-content直下に<form>を配置 .carousel+data-bs-ride="carousel"で自動スライドdata-bs-intervalでスライド間隔、carousel-fadeでフェード切替.accordion+data-bs-parentで排他的な開閉パネル