Bootstrapで練習用Webページを作って学んだことまとめ

# はじめに

Bootstrapを少し勉強したので、せっかくだから実際に何か作ってみようと思い、簡単なWebページを作ってみました。

目的は、フレームワークを使う経験を積むことです。

学習方法としては、生成AIに問題を出してもらい、それを自分で実装していくという形で進めました。

この記事では、その過程で学んだことを備忘録的にまとめておきます。

# 基本的なレスポンシブカード

## 概要

以下の要素を持つレスポンシブ対応のカードを作成しました。

- カードの内容
    - 画像
    - タイトル
    - 説明文
    - ボタン（primaryカラー）
- レスポンシブなカラム構成
    - `lg`以上（デスクトップ）：3列
    - `md`（タブレット）：2列
    - `sm`以下（モバイル）：1列
- カードの高さを揃える

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3841606/86b2cad1-25dd-43af-95a1-f4c4d332473e.png)

## 学んだこと

### `container`クラス

最初、`container`を使い忘れて余白に困っていました。
[公式ドキュメント](https://getbootstrap.jp/docs/5.3/layout/containers/#%E4%BB%95%E7%B5%84%E3%81%BF)では以下のように説明されています。

> コンテナは、Bootstrap基本的なレイアウト要素であり、特定のデバイスやビューポート内のコンテンツに適切な余白を与え整列させることができます。
> 

また、必要に応じて、余白がある`.container`と、幅いっぱいに広がる`.container-fluid`を使い分けます。

### グリッドシステムと列の指定

方法1：`row-cols-*` を使う場合

```html
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3">
  <div class="col">
    <div class="card">
      <!-- カードの中身 -->
    </div>
  </div>
  <div class="col">
    <div class="card">
      <!-- カードの中身 -->
    </div>
  </div>
</div>
```

方法2：`col-*` で個別に指定する場合

```html
<div class="row">
  <div class="col col-sm-12 col-md-6 col-lg-4">
    <div class="card">
      <!-- カードの中身 -->
    </div>
  </div>
  ...
</div>
```

### カードの高さをそろえる

- `.row` の中の `.col` は高さを揃える構造を作れます
- `.card` に `h-100` をつけることで、列の高さにフィットさせることができます

### ボタンを一番下に固定する

- `.d-flex` ＋ `.flex-column` → 縦並びにする
- ボタンに `.mt-auto` → 余白を利用して一番下に押し出す
- また、flexboxでは`align-items: stretch`がデフォルトなので、ボタンもいい感じで幅いっぱいになります

# ナビゲーションバーとヒーロー

## 概要

- レスポンシブなナビゲーションバー（ハンバーガーメニュー対応）
- ヒーローセクションに以下を配置
    - メインタイトル
    - サブタイトル
    - CTA（Call To Action）ボタン
- テキスト配置の指定
    - モバイル：中央揃え
    - デスクトップ：左揃え
- 背景には薄いグラデーションを適用

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3841606/17cf7dd3-7dc2-4ae6-badc-d8fc1f48c5cb.png)

## 学んだこと

### Navbarのポイント

- `navbar-expand-lg`
    
    → `lg`以上の画面で横並び、それ未満で折りたたみ
    
- `collapse` ＋ `navbar-collapse`
    
    → 折りたたみ式メニューの実現に使う
    
- `ms-auto`
    
    → 左側にマージンをつけ、右寄せにする
    

### ヒーローセクションのレイアウト

`<div>`が多くて最初は混乱しましたが、構造を理解すると納得感が出てきます。

```html
<section class="hero-section d-flex align-items-center">
  <div class="container">
    <div class="row">
      <div class="col-lg-8 col-md-10 mx-auto">
        <div class="text-center text-lg-start">
          <h1 class="display-4 fw-bold mb-3">あなたのビジネスを次のレベルへ</h1>
          <p class="lead mb-4">
            革新的なソリューションで、お客様の成功をサポートします。まずは無料相談からはじめませんか？
          </p>
          <div class="d-grid d-md-flex justify-content-md-center justify-content-lg-start">
            <a href="#" class="btn btn-light btn-lg me-md-2 mb-2 mb-md-0">今すぐ始める</a>
            <a href="#" class="btn btn-outline-light btn-lg">詳細を見る</a>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>
```

### 各構造の意味と役割

各構造の意味と役割は以下の表に整理しました。

特に`.col-...`（レイアウト）と`.text-...`（見た目）を分けて使うことで、幅だけ変えたい時や位置だけ調整したい時に柔軟に対応できる点が興味深かったです。

| 構造 | 役割 |
| --- | --- |
| `<section>` | 意味づけのあるブロック。構造化に便利 |
| `.container` | 余白＋中央揃え。レイアウトの基本 |
| `.row` | カラムを並べるための行 |
| `.col-lg-8 col-md-10 mx-auto` | カラム幅の指定 |
| `.text-center text-lg-start` | テキストの見た目の調整 |
| `.d-grid d-md-flex ...` | ボタンの配置調整 |

# フォームとモーダル

## 概要

- フォームバリデーション機能の追加
- レスポンシブなレイアウト
    - モバイル：1カラム
    - タブレット以上：2カラム
- 「送信」ボタンクリック時にモーダルを表示
- モーダルには以下の要素を含む
    - 送信完了メッセージ
    - クローズボタン

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3841606/1ffce01f-c1a5-42d0-895d-8f7050f0d1ee.png)

## 学んだこと

### ボタンの横幅を100%にする

`d-grid`クラスを使用すると、グリッドレイアウトの特性により、内部のボタンは自動的に横幅100%で表示されます。

```
<div class="d-grid">
  <button class="btn btn-primary">送信</button>
</div>
```

### バリデーション

| クラス・属性名 | 説明 |
| --- | --- |
| `needs-validation` | フォームをバリデーション対象にする。JSでの制御が有効になる。 |
| `novalidate` | ブラウザのデフォルトのバリデーションUIを無効にし、Bootstrapに切り替える。 |
| `required` | 入力を必須にするHTML5の属性。これがないとバリデーションされない。 |
| `form-control` | 入力欄にBootstrapのスタイルを適用するクラス。 |
| `.invalid-feedback` | 無効な入力に対するエラーメッセージの表示領域。JSと連携して表示制御。 |
| `.valid-feedback` | 有効な入力に対するメッセージの表示領域。 |
| `.was-validated` | バリデーション実行後に付けることで、フィードバック表示を有効化する。 |
| `.is-valid` / `.is-invalid` | 入力欄の枠色（緑または赤）を切り替えるクラス。結果に応じて自動付与。 |

### モーダル

モーダルは、ユーザーに重要なメッセージを表示したり、操作の確認を求める場面で使用するポップアップのようなUIです。

HTML上では非表示の状態で用意し、必要なときだけJavaScriptやBootstrapの仕組みで表示・非表示を切り替えるようにします。

`data-bs-toggle`と`data-bs-target`属性を使用することで、ボタンなどから簡単にモーダルを開くことができます。

```html
<!-- モーダルを開くボタン -->
<button data-bs-toggle="modal" data-bs-target="#myModal" class="btn btn-primary">
  モーダルを開く
</button>

<!-- 非表示で用意するモーダル本体 -->
<div class="modal fade" id="myModal" tabindex="-1">
  <div class="modal-dialog">
    <div class="modal-content">
      <!-- モーダルの中身をここに書く -->
    </div>
  </div>
</div>
```

# アコーディオンとプログレスバー

## 概要

- アコーディオン形式でFAQを表示
- 各FAQ項目に重要度を示すプログレスバーを追加
- レスポンシブなレイアウト
    - モバイル：1カラム
    - タブレット以上：2カラム
- 開閉やバーの表示にアニメーション効果を加える

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3841606/c458518b-4298-4995-8045-2196fbd8875c.png)

## 学んだこと

### プログレスバーのアニメーション

これはBootstrapの標準機能ではありませんが、Bootstrapのコンポーネントに自作のCSSアニメーションを追加することができます。

```css
.progress-animate {
  animation: progressFill 2s ease-in-out;
}

@keyframes progressFill {
  from {
    width: 0%;
  }
}
```

### 細かい仕様の調整

アコーディオンの仕様として、1つの項目が開いているときに別の項目を開くと、先に開いていた項目が自動で閉じるように動作させる必要がありました。

また、最初からすべての項目が開いた状態になってしまうという問題が発生していたため、初期状態ではすべて閉じた状態になるように修正を行いました。

このように、細かい動作や表示に関して、どのように実装するか迷う場面が多くありました。

# 感想

実際に手を動かしてアウトプットすることで、多くの学びが得られました。

特に感じたのは、構造を意識することがマークアップ言語の核であるということです。

今後も、構造や意味を意識しながらコーディングしていきたいと思います。