Old-School Front-End / 2026 ・ No.06

いにしえのフロントエンド入門

第6回 CSS ③ ── Bootstrap:いにしえの道具箱を、中身を知ったうえで使う

公開

Bootstrap で書き直した申請一覧を、パソコンとスマホで並べた写真。紺のナビバー、赤い新規申請ボタン、白いカードが3つ、縞模様の表。スマホではナビが三本線のボタンにまとまり、カードは縦に並ぶ
今回のゴール。申請一覧を Bootstrap で書き直しました。自前の CSS は custom.css の31行だけです(筆者のデモページを、クラウド上の Chromium で撮影。スマホは Playwright のスマホ表示(390×844)。2026年10月17日。端末やブラウザの枠は説明のために描き足したもの)

AI に頼まず、一行ずつ手で書く「いにしえの」フロントエンド入門。第6回は Bootstrap です。
第4・5回で手書きしたものを、クラスを付けるだけで手に入れられる道具箱。
今回は申請一覧と申請フォームを Bootstrap で書き直し、どのクラスが、手で書いたどの CSS にあたるのかを確かめます。
便利さの裏にある重さと、AI がよく踏む落とし穴も、実際に測ってみました。

一

今回のゴール

新井先輩、Bootstrap って AI がよく使ってくるやつですよね。クラスをいっぱい書くだけで、それっぽくなる。

古井そう、「毎回同じ CSS を書くのはもう嫌だ」という人たちが作った道具箱だ。2011年に Twitter 社の開発者が公開して、いまや定番になった。

新井じゃあ、最初から Bootstrap を教えてくれればよかったのに……。

古井中身を知らずに使うと、道具に使われる。第4・5回で手書きしたいまなら、クラスの名前を見ただけで「ああ、あの CSS だ」と分かるはずだ。

いまここ:第6回

1 準備 2 HTML の骨組み 3 フォーム 4 CSS の基本 5 レイアウト 6 Bootstrap 7 JS の基本 8 DOM・イベント 9 入力チェック 10 通信 11 ログイン 12 承認の流れ 13 集計と印刷 14 jQuery 15 仕上げ いまここ 準備 HTML CSS JavaScript 実戦 仕上げ

今回使うのは、執筆時点の安定版 Bootstrap 5.3.8(2025年8月26日公開)です。2026年10月8日には次の大きな版 6.0.0 の最初の試作版(alpha.1)が出ましたが、まだ試作段階なので、業務システムには 5.3 系を使います。まずは、第5回の手書きの CSS 版と並べてみましょう。

2つの申請一覧を並べた画面。1 第5回の手書きの CSS 版と、2 Bootstrap 版。見た目はほとんど同じで、Bootstrap 版は文字の太さや余白が少し違う
①第5回の手書きの CSS(205行)。②Bootstrap + custom.css(31行)。見た目はほぼ同じです(筆者のデモページを、クラウド上の Chromium で撮影。スマホは Playwright のスマホ表示(390×844)。2026年10月17日。端末やブラウザの枠は説明のために描き足したもの)

見た目はほぼ同じです。違いは中身。①は自前の CSS が205行(空行を除く。以下同じ)、②は Bootstrap のクラスを HTML に付けて、自前の CSS(custom.css)は31行だけ。CSS を書く代わりに、クラスを選ぶ。これが Bootstrap の使い方です。

二

Bootstrap を読み込む

Bootstrap の正体は、名前の付いた CSS のルールの詰め合わせ(bootstrap.min.css)と、ナビの開け閉めなどの動きを担う JavaScript(bootstrap.bundle.min.js)です。

読み込む順番

<head> bootstrap.min.css 名前の付いたルールの詰め合わせ 232 KB 1 css/custom.css 自前の上書き(ブランドの色) 0.9 KB 2 後に書いたほうが勝つ 同じ詳細度(0-1-0)なら 順番を逆にすると負ける(第4回) <body> class="btn btn-brand" HTML はクラスを付けるだけ bootstrap.bundle.min.js ナビの開閉などの動き 80 KB body の最後に。中身は第7回以降

ファイルの置き方は二通りあります。今回は npm で取ってきたファイルをフォルダに置きました(vendor/bootstrap/)。社内のネットワークだけで動かす業務システムでは、こちらが安心です。

<!-- 自分のフォルダに置く(今回) -->
<link rel="stylesheet" href="vendor/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="css/custom.css">
…
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>

<!-- CDN(配信サービス)から読み込む場合 -->
<link rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
  integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB"
  crossorigin="anonymous">

CDN を使うときの integrity は、「届いたファイルが、この指紋(ハッシュ)と一致しなければ使わない」という指定です。配信元のファイルが書き換えられても、気づかずに読み込むことを防げます。上の値は、npm の 5.3.8 のファイルから筆者が計算し、jsDelivr から取ってきたファイルとも一致することを確かめたものです。

三

クラスの読み方

Bootstrap のクラスには、2種類あります。navbar や card のような部品(コンポーネント)と、mb-3 や d-flex のような、1つのことだけをする小道具(ユーティリティ)です。小道具の名前は、規則さえ分かれば読めます。

ユーティリティの名前を分解する

m m = margin(p なら padding) s s = start(左)。t・b・e・x・y も -md -md = 768px 以上のときだけ -auto -auto = 値(0〜5 か auto) 余白の段階(実測。1 は 0.25rem、3 は 1rem) m-0 0px m-1 4px m-2 8px m-3 16px m-4 24px m-5 48px

第4・5回で手書きした CSS と、Bootstrap のクラスを対応させると、こうなります。

手書きの CSS(第4・5回)Bootstrap のクラス
body > header { display: flex; … }navbar navbar-expand-md + container
.user { margin-left: auto; }ms-md-auto
.page-head { display: flex; justify-content: space-between; … }d-flex flex-wrap justify-content-between align-items-center gap-3
.summary { display: grid; … }row g-3 + col-12 col-sm-6 col-lg-4
.summary li { border: 1px solid; border-radius: 8px; … }card + card-body
.table-wrap { overflow-x: auto; }table-responsive
tbody tr:nth-child(even)、tr:hovertable-striped、table-hover
.amount { text-align: right; white-space: nowrap; }text-end text-nowrap
.status-approved { color: …; background: …; }badge rounded-pill text-bg-success
@media (min-width: 768px) { … }クラス名の中の -md-

新井本当だ……。d-flex は display: flex、ms-md-auto は 768px 以上で margin-left: auto。もう呪文に見えません!

古井それが手書きをしてきたご褒美だ。

四

グリッドと画面の幅

第5回では grid の auto-fit で「入るだけ並べる」を書きました。Bootstrap のグリッドは考え方が違い、横を12列に分けて、何列分を使うかをクラスで指定します。

12列のグリッド

横を12列に分ける 1 2 3 4 5 6 7 8 9 10 11 12 col-12 スマホ:1つずつ col-sm-6 576px〜:2つ並ぶ col-lg-4 992px〜:3つ並ぶ まとめの箱には3つまとめて付けた:col-12 col-sm-6 col-lg-4

col-12 col-sm-6 col-lg-4 は、「ふだんは12列(1つずつ)、sm 以上で6列分(2つ並ぶ)、lg 以上で4列分(3つ並ぶ)」と読みます。sm や lg は、Bootstrap が決めている画面の幅の区切り(ブレークポイント)です。bootstrap.css の中の min-width の値を数えると、576・768・992・1200・1400px の5か所でした。実際に幅を変えて測った見た目です。

画面の幅の区切りと、実測した見た目

xs 0 sm 576 md 768 lg 992 xl 1200 xxl 1400 container の幅(実測 px) 画面幅 540 720 960 1140 1320 まとめの箱(col-12 col-sm-6 col-lg-4) 1つ並ぶ 2つ並ぶ 3つ並ぶ ナビ(navbar-expand-md) ハンバーガー 横一列 画面の幅(px)

container は、中身の幅を区切りごとに決まった値にそろえる箱です。第5回で書いた max-width: 960px の代わりになります。ナビの navbar-expand-md は「md(768px)以上で横に展開、それより狭ければ三本線のボタンにたたむ」という意味です。

Bootstrap 版の申請一覧に赤枠と番号を付けたもの。1 navbar、2 btn btn-brand、3 d-flex の行、4 row g-3 のグリッド、5 card、6 table-responsive、7 badge
使った Bootstrap のクラス。①navbar navbar-expand-md、②btn btn-brand、③d-flex justify-content-between、④row g-3、⑤card、⑥table-responsive と table、⑦badge rounded-pill(筆者のデモページを、クラウド上の Chromium で撮影。スマホは Playwright のスマホ表示(390×844)。2026年10月17日。端末やブラウザの枠は説明のために描き足したもの)
五

部品を使う:ナビ・カード・表・バッジ・ボタン

部品(コンポーネント)は、決まった組み合わせで HTML を書くと、見た目と動きがそろって手に入ります。スマホでは、ナビが三本線のボタン(通称ハンバーガー)にまとまります。

スマホの画面を2台並べた写真。1 ナビが右上の三本線のボタンにまとまっている。2 ボタンを押すと、申請一覧・承認・ダッシュボードと利用者名が下に開く
①閉じたところ。②三本線を押したところ。開け閉めは bootstrap.bundle.min.js が担当します(筆者のデモページを、クラウド上の Chromium で撮影。スマホは Playwright のスマホ表示(390×844)。2026年10月17日。端末やブラウザの枠は説明のために描き足したもの)

開け閉めの動きは CSS だけではできないので、body の最後で読み込んだ bootstrap.bundle.min.js が担当しています。ボタンの data-bs-toggle="collapse" と data-bs-target="#mainNav" が、「押したら #mainNav を開け閉めして」という合図です。JavaScript の中身は第7回から自分で書いていきます。

  • card ── 枠線と角の丸みと余白が付いた箱。中身は card-body に入れる。h-100 で、並んだカードの高さをそろえた
  • table ── table を付けるだけで罫線と余白が付く。Bootstrap は表題(caption)を表の下に置くので、上に出すために caption-top を付けた
  • badge ── 状態のバッジ。text-bg-success などで、背景色と、それに合う文字色が同時に決まる
  • btn ── ボタン。btn-primary などの色の種類があるが、今回はブランドの赤にしたいので、custom.css で btn-brand を作った

Bootstrap 5.3 のボタンは、色を --bs-btn-bg などのCSS 変数(第4回)で持っています。だから、変数を上書きするだけで、新しい色のボタンが作れます。

.btn-brand {
  --bs-btn-color: #fff;
  --bs-btn-bg: #c0392b;          /* ふだんの背景 */
  --bs-btn-hover-bg: #a93226;    /* マウスを乗せたとき */
  …
}

Bootstrap の色の組み合わせのコントラスト比も、WCAG の式で計算しておきました。

クラス文字 / 背景(実測)コントラスト比
text-bg-warning#000000 / #ffc10712.88 : 1
text-bg-success#ffffff / #1987544.53 : 1
text-bg-danger#ffffff / #dc35454.53 : 1
text-bg-secondary#ffffff / #6c757d4.69 : 1
btn-primary(参考)#ffffff / #0d6efd4.50 : 1
btn-brand(自前)#ffffff / #c0392b5.44 : 1

どれも、ふつうの文字の目安 4.5:1 は満たしています(btn-primary はぎりぎり)。ただしバッジの文字は小さいので、色を自分で変えるときは、この数字が下がらないように気を付けましょう。

六

フォームも Bootstrap で

第3回の申請フォームも書き直しました。入力欄には form-control、選択肢には form-select、ラジオボタンとチェックボックスは form-check の組み合わせです。label と name の付け方は第3回のまま。HTML の正しさは、Bootstrap になっても変わりません。

    <form action="/api/expenses" method="post" enctype="multipart/form-data">
      <div class="card mb-4">
        <div class="card-body">
          <div class="row g-3">
            <fieldset class="col-md-7">
              <legend class="h6 section-title">申請の内容</legend>
              <label for="title" class="form-label">件名(必須)</label>
              <input type="text" class="form-control" id="title" name="title" required maxlength="50">
              <div class="invalid-feedback">件名を入力してください。</div>
            </fieldset>
            <fieldset class="col-md-5">
              <legend class="h6 section-title">支払い方法</legend>
              <div class="form-check form-check-inline">
                <input class="form-check-input" type="radio" name="payment" id="pay-personal" value="personal" checked>
                <label class="form-check-label" for="pay-personal">立て替え(自分で払った)</label>
              </div>
              <div class="form-check form-check-inline">
                <input class="form-check-input" type="radio" name="payment" id="pay-corporate" value="corporate">
                <label class="form-check-label" for="pay-corporate">会社のカード</label>
              </div>
            </fieldset>
          </div>
        </div>
      </div>

      …

      <div class="form-check mb-4">
        <input class="form-check-input" type="checkbox" id="agree" name="agree" value="yes" required>
        <label class="form-check-label" for="agree">経費規程を確認しました(必須)</label>
      </div>

      <div class="d-flex flex-wrap justify-content-end gap-2">
        <button type="submit" class="btn btn-outline-secondary" name="action" value="draft" formnovalidate>下書き保存</button>
        <button type="submit" class="btn btn-brand" name="action" value="submit">申請する</button>
      </div>
    </form>

Bootstrap には、入力チェックの結果を色で示す見た目も用意されています。form に was-validated というクラスが付くと、ブラウザの検査(第3回の required など)の結果に合わせて、欄が赤や緑になります。

Bootstrap で書き直した申請フォーム。件名には入力済みで緑の枠とチェック。明細の1行目の必須の欄と、規程の確認のチェックボックスは赤。2・3行目の空の欄にも緑のチェックが付いている
Bootstrap の検証の見た目(was-validated を付けた状態)。必須の空欄は赤、それ以外は緑。空の任意の欄にまで緑のチェックが付くのに注意(筆者のデモページを、クラウド上の Chromium で撮影。スマホは Playwright のスマホ表示(390×844)。2026年10月17日。端末やブラウザの枠は説明のために描き足したもの)

写真は、件名だけを入れて was-validated を付けたところです。気になるのは、明細の2・3行目のような空の任意の欄にも、緑のチェックが付くこと。「入力していないのに OK?」と利用者を迷わせるので、実際には、入力した欄だけに印を付けるなどの工夫が要ります。そして、was-validated を付けるのは「送信ボタンが押されたとき」なので、JavaScript の仕事です。続きは第9回の入力チェックで。

七

書き直した HTML

Bootstrap 版の index.html です(表の行は1行目だけ表示)。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>申請一覧 | 経費精算システム</title>
  <link rel="stylesheet" href="vendor/bootstrap/css/bootstrap.min.css">
  <link rel="stylesheet" href="css/custom.css">
</head>
<body class="bg-body-tertiary">
  <header class="navbar navbar-expand-md navbar-dark brand-bar">
    <div class="container">
      <a class="navbar-brand fw-bold" href="/"><img src="img/logo.svg" alt="" width="32" height="32"> 経費精算システム</a>
      <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#mainNav" aria-controls="mainNav" aria-expanded="false" aria-label="メニューを開く">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="mainNav">
        <nav aria-label="メイン">
          <ul class="navbar-nav">
            <li class="nav-item"><a class="nav-link active" aria-current="page" href="/">申請一覧</a></li>
            <li class="nav-item"><a class="nav-link" href="approve.html">承認</a></li>
            <li class="nav-item"><a class="nav-link" href="dashboard.html">ダッシュボード</a></li>
          </ul>
        </nav>
        <p class="navbar-text mb-0 ms-md-auto">新井 太郎(申請者)</p>
      </div>
    </div>
  </header>

  <main class="container py-4">
    <div class="d-flex flex-wrap justify-content-between align-items-center gap-3 mb-4">
      <h1 class="h3 mb-0">申請一覧</h1>
      <a class="btn btn-brand" href="form.html">+ 新規申請</a>
    </div>

    <section class="mb-4">
      <h2 class="h5 section-title mb-3">今月のまとめ</h2>
      <ul class="row g-3 list-unstyled">
        <li class="col-12 col-sm-6 col-lg-4"><div class="card h-100"><div class="card-body">今月の申請:4 件</div></div></li>
        <li class="col-12 col-sm-6 col-lg-4"><div class="card h-100"><div class="card-body">承認待ちの金額:<strong class="d-block fs-4 text-danger">32,400 円</strong></div></div></li>
        <li class="col-12 col-sm-6 col-lg-4"><div class="card h-100"><div class="card-body">差し戻し:1 件</div></div></li>
      </ul>
    </section>

    <section>
      <h2 class="h5 section-title mb-3">申請の一覧</h2>
      <div class="table-responsive" tabindex="0" role="region" aria-label="申請の一覧">
        <table class="table table-striped table-hover align-middle caption-top wide-table mb-0">
          <caption>2026年10月の申請(新しい順)</caption>
          <thead class="table-light">
            <tr>
              <th scope="col">No.</th>
              <th scope="col">申請日</th>
              <th scope="col">件名</th>
              <th scope="col" class="text-end">金額(円)</th>
              <th scope="col">状態</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>0007</td>
              <td class="text-nowrap"><time datetime="2026-10-16">2026-10-16</time></td>
              <td><a href="detail.html">大阪出張(交通費・宿泊費)</a></td>
              <td class="text-end text-nowrap">32,400</td>
              <td><span class="badge rounded-pill text-bg-warning">申請中</span></td>
            </tr>
            …
          </tbody>
        </table>
      </div>
    </section>
  </main>

  <footer class="py-4 text-center text-body-secondary">
    <small>© 2026 KIJI 経費精算システム(練習用)</small>
  </footer>
  <script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
</body>
</html>

そして、自前の CSS はこれだけです。

/* Bootstrap の後に読み込んで、ブランドの色だけを足す */

/* ヘッダーの帯の色 */
.brand-bar {
  background-color: #1f4e6b;
}

/* ブランド色のボタン(Bootstrap のボタンの変数を上書き) */
.btn-brand {
  --bs-btn-color: #fff;
  --bs-btn-bg: #c0392b;
  --bs-btn-border-color: #c0392b;
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: #a93226;
  --bs-btn-hover-border-color: #a93226;
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: #922b21;
  --bs-btn-active-border-color: #922b21;
  --bs-btn-focus-shadow-rgb: 192, 57, 43;
  font-weight: 700;
}

/* 見出しの左の赤い線(第4回と同じ) */
.section-title {
  padding-left: 10px;
  border-left: 4px solid #c0392b;
}

/* 表は、これより狭くしない(狭い画面では横スクロール) */
.wide-table {
  min-width: 640px;
}
.line-items {
  min-width: 720px;
}

どちらも Nu Html Checker でエラーはありませんでした。HTML が少し長くなり、CSS がほとんどなくなった。見た目の指定が、CSS ファイルから HTML のクラスへ引っ越した、と考えると分かりやすいでしょう。

八

よくある落とし穴

Bootstrap ならではのつまずきを、二つ実験しました。

4つの帯を縦に並べた画面。1 custom.css を先に読み込むと、新規申請ボタンの背景が透明で文字だけになる。2 正しい順番では赤いボタン。3 Bootstrap 4 の ml-auto では利用者名がナビのすぐ隣にくっつく。4 Bootstrap 5 の ms-md-auto では右端に寄る
よくある落とし穴2つ。①②読み込む順番。③④Bootstrap 4 の書き方(ml-auto)は Bootstrap 5 では効かない(筆者のデモページを、クラウド上の Chromium で撮影。スマホは Playwright のスマホ表示(390×844)。2026年10月17日。端末やブラウザの枠は説明のために描き足したもの)
# ① custom.css を Bootstrap より先に読み込んだとき(.btn-brand の計算後の値)
color → rgb(33, 37, 41) (正しい順番なら rgb(255, 255, 255))
background-color → rgba(0, 0, 0, 0) 透明(正しい順番なら rgb(192, 57, 43))

# ② Bootstrap 4 の書き方が混ざったとき(Bootstrap 5.3.8 のページで)
ml-auto(v4) → margin-left 0px 名前の左端 502px
ms-md-auto(v5) → margin-left 316.484px 名前の左端 819px
data-toggle(v4) → ボタンを押すと aria-expanded="false"、メニューの高さ 0px
data-bs-toggle(v5) → ボタンを押すと aria-expanded="true"、メニューの高さ 160px
  • 読み込む順番 ── Bootstrap の .btn も、自前の .btn-brand も、詳細度は同じ 0-1-0。同点なら後に書いたほうが勝つ(第4回)ので、custom.css を先に書くと、.btn の「背景は透明」が勝ってしまう。自前の CSS は必ず Bootstrap の後
  • 版の違い ── Bootstrap 4 と 5 では、クラス名や属性の名前がいくつも変わった。古い書き方は、エラーも出さずにただ効かない
Bootstrap 4 の書き方Bootstrap 5 の書き方
ml-*、mr-*、pl-*、pr-*ms-*、me-*、ps-*、pe-*(left/right → start/end)
text-left、float-righttext-start、float-end
data-toggle、data-targetdata-bs-toggle、data-bs-target
custom-selectform-select
form-groupなくなった(mb-3 などの余白で代わりに)
sr-onlyvisually-hidden
jQuery が必要jQuery は不要に
POINT

AI は、ネット上に大量に残る Bootstrap 4 時代の書き方を、5 のページに平気で混ぜてきます。ml-auto や data-toggle を見かけたら要注意。「使っている Bootstrap は 5.3」と最初に伝え、出てきたクラスは公式の資料で確かめるのが、いにしえ流の付き合い方です。

九

重さと「Bootstrap 顔」

便利な道具箱には、重さもあります。ファイルの大きさと、Chromium のカバレッジ(CSS のうち、そのページで実際に使われた部分を数える機能)で測った値です。

ファイルの大きさと、実際に使われた割合(実測)

style.css 第5回の自前の CSS 4.0 KB gzip 1.7 KB bootstrap.min.css 232.1 KB gzip 30.9 KB 使われたのは 一覧 7.4%・フォーム 9.0% bootstrap.bundle.min.js 80.5 KB gzip 23.7 KB 灰色が元の大きさ、青が gzip(転送時の圧縮)後、赤が実際に使われた部分

申請一覧で使われたのは、bootstrap.min.css の 7.4% だけ。残りは、ほかの部品のためのルールです。転送のときは gzip で圧縮されて約31KB になり、一度読み込めばブラウザが覚えておくので、社内の業務システムなら大きな問題にはなりにくい重さです。ただ、「たった1つのボタンのために Bootstrap を丸ごと」は、少し考えたほうがよいでしょう。

新井でも先輩、Bootstrap で作った画面って、どこかで見たような顔になりません?

古井いわゆる「Bootstrap 顔」だな。業務システムなら、見慣れた顔はむしろ安心感になる。お客さま向けの看板ページなら、custom.css で色や形をしっかり変えるか、手書きを選ぶ。道具は、目的で選ぶんだ。

結 — 一枚まとめと次回予告

  1. Bootstrap は 名前の付いた CSS のルールの詰め合わせ+動きの JS。CSS を書く代わりに、クラスを選ぶ。
  2. 自前の CSS は 必ず Bootstrap の後に読み込む。同じ詳細度なら後に書いたほうが勝つ。
  3. ユーティリティは 何を・どこに・どの幅から・どれだけ(例:ms-md-auto)と読む。グリッドは12列、区切りは 576・768・992・1200・1400px。
  4. ボタンの色は CSS 変数の上書きで作れる。コントラスト比と、caption の位置などの初期値は自分で確かめる。
  5. Bootstrap 4 の書き方(ml-auto、data-toggle)は 5 では黙って効かない。版を確かめてから使う。

新井これで見た目は一通り完成ですね! ……でも、明細の合計金額、まだ自分で電卓をたたいて書いてるんですけど。

古井それを計算させるのが、次の筋肉だ。第7回からは JavaScript。まずは合計を出す関数から始めよう。

参考

ページの写真は、筆者が作ったデモページを2026年10月17日にクラウド上の Chromium(Playwright)で撮影したものです。スマホは Playwright のスマホ表示(isMobile)による再現で、実機の画面ではありません。撮影環境には Hiragino Sans がないため、日本語は Noto Sans CJK JP で表示されています。Bootstrap は npm の bootstrap 5.3.8 のファイルを使い、版の公開日は npm の記録によります。ファイルの大きさ、カバレッジ、余白の段階、container の幅、カードの並び方、ボタンとバッジの色、読み込む順番と Bootstrap 4 の書き方の実験結果は、同じ Chromium で測った実際の値です。コントラスト比は WCAG 2.2 の式で計算しました。HTML と custom.css は Nu Html Checker(vnu)でエラーがないことを確かめています。登場人物は架空の人物です。

いにしえのフロントエンド入門 第6回 — CSS ③:Bootstrap / 2026.10

← 記事一覧へ