Bootstrap

Bootstrapモーダル・カルーセル・アコーディオン|インタラクティブなコンポーネント

Bootstrap モーダル カルーセル

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-sm300px確認ダイアログ
(デフォルト)500px一般的な用途
modal-lg800pxフォーム・詳細表示
modal-xl1140px大きなコンテンツ
modal-fullscreen100%全画面表示
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-interval5000自動スライドの間隔(ミリ秒)
data-bs-ridefalse"carousel" で自動再生
data-bs-wraptrue最後のスライドから最初に戻るか
data-bs-pause"hover"ホバー時に一時停止
data-bs-touchtrueスワイプ操作の有効/無効
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();
フェードアニメーション
.carouselcarousel-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-buttoncollapsed クラスがないと、矢印アイコンの向きが正しく表示されません。デフォルトで閉じているアイテムには必ず 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 で排他的な開閉パネル