bootstrap-color-system について
Bootstrap 6 の Sass と CSS トークンによる色の変更を支援するスキルです。パレット、意味的なテーマ、カラーモード、実行時の調整に適した層を案内します。
主な機能
- 01OKLCH 色相とスケールの設定
- 02意味的なテーマロールの割り当て
- 03ライト/ダークモードの調整
- 04実行時の CSS 変数上書き
- 05カラー utility の生成
活用シーン
- 01Bootstrap のブランドパレット調整
- 02意味的なテーマカラーの追加
- 03ページやテナント単位の配色
- 04カラー・トークンとコントラストの検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ twbs/ bootstrap --skill bootstrap-color-systemインストール後、Claude Code で/bootstrap-color-systemを入力して読み込まれたか確認します。
詳細
Bootstrap 6 のカラーシステム
Bootstrap 6 の色は、固定されたパイプラインを通じて扱われます。少数の oklch() 色相からフルスケールを生成し、その一部のスケールにセマンティックな役割を割り当て、コンポーネントは色相ではなく役割を参照します。色をカスタマイズする際は、変更する適切なレイヤーを選ぶ必要があるため、まず作業がどのレイヤーに当てはまるかを確認してください。
ワークフロー
- ステップ 1:変更が必要なレイヤーを特定する
- ステップ 2:基本色相とスケール
- ステップ 3:テーマカラー
- ステップ 4:背景、前景、ボーダー用のレイヤーカラー
- ステップ 5:カラーモード
- ステップ 6:コンパイル時のオーバーライド
- ステップ 7:実行時のオーバーライド
- ステップ 8:関数とユーティリティ
- ステップ 9:確認
ステップ 1:変更が必要なレイヤーを特定する
各段階を担当するファイルとともに、パイプラインを示します。
- 基本色相 —
scss/_colors.scssで 16 色相をoklch()のスカラーとして定義し、$colorsにまとめます。 - カラースケール — 同じファイルで、各色相から
color-mix()を使ってステップ025~975を生成し、:rootに--blue-500、--red-200などを出力します。 - テーマカラー —
scss/_theme.scssで、セマンティックな名前(primary、danger、…)をスケールトークンに一つずつ対応付けます。 - ルートトークン —
scss/_root.scssですべてのテーマの役割を--<name>-<role>(--danger-bg-subtle)として出力し、レイヤーカラートークンも出力します。 - テーマクラス —
scss/helpers/_theme-colors.scssで@layer helpersに.theme-<name>を出力し、--<name>-<role>を汎用の--theme-<role>に再マッピングします。 - コンポーネントとユーティリティ —
--theme-*(ニュートラルなフォールバック付き)とレイヤートークンを参照します。生の色相を参照するものはありません。
作業内容に合わせてレイヤーを選びます。ブランドの青を変更するならステージ 1、新しいセマンティックカラーを追加するならステージ 3、単一のコンポーネントのスタイルを変更するならコンポーネントトークン(bootstrap-component スキルを参照)、アプリで一度限りの調整を行うなら実行時の CSS 変数オーバーライドです。
ステップ 2:基本色相とスケール
各色相は、ステップ 500 の基準となる単一の oklch() 値です。
$blue: oklch(60% 0.24 240) !default;
16 色相は、blue、indigo、violet、purple、pink、red、orange、amber、yellow、lime、green、teal、cyan、brown、gray、pewter で、これに $white と $black が加わります。$colors は defaults() を通じてこれらをまとめるため、マップは置き換えられず、マージされます。
スケールは手作業で選ぶのではなく、生成されます。各色相は、$color-mix-space カラースペース(lab)で、ステップ 025 050 100 200 300 400 では $tint-color(var(--white))に向けて、600 700 800 900 950 975 では $shade-color(var(--black))に向けて混合されます。色相を変更すると、そのスケール全体が再生成されます。
$colors にマージして色相を追加すると、そのフルスケールと、$colors から生成される色ユーティリティが自動的に追加されます。
@use "bootstrap/scss/bootstrap" with (
$colors: (
"slate": oklch(55% 0.04 250),
)
);
色合いと陰影の割合($color-tints、$color-shades)、混合スペース、混合先も、同じ方法で設定できます。個別のステップは $color-tokens を通じてオーバーライドできます。
意図的に var(--white)/var(--black) を相手に混合しています。これにより、出力内の color-mix() がそのまま維持され、CSS ミニファイアーによって静的な lab() 値に展開されるのを防げます。
ステップ 3:テーマカラー
scss/_theme.scss の $theme-colors は、8 つのセマンティックカラー(primary、accent、success、danger、warning、info、inverse、secondary)を定義します。それぞれが、次の 9 つの役割を持つネストされたマップです。
| 役割 | 用途 |
|---|---|
base | ほかの色の基準となる、ブランドカラーの値 |
bg | ソリッドボタンやバッジなどの、単色の背景 |
bg-subtle | アラート、控えめなボタン、コールアウト向けの色付きサーフェス |
bg-muted | 控えめな背景より一段強い背景 |
fg | 控えめなサーフェス上のテキスト |
fg-emphasis | 控えめなサーフェス上の、よりコントラストの高いテキスト |
contrast | base/bg 上に配置するテキストとアイコン |
border | 控えめなサーフェス上の境界線 |
focus-ring | フォーカスアウトラインの色 |
ほとんどの役割は light-dark(…) のペアで、すべての値が色のリテラル値ではなく、スケールトークンへの var() 参照になっています。
"danger": (
"base": var(--red-500),
"fg": light-dark(var(--red-600), var(--red-400)),
"bg-subtle": light-dark(var(--red-100), var(--red-900)),
"border": light-dark(var(--red-300), var(--red-600)),
"contrast": var(--white)
),
このマップから 2 つのものが生成されます。:root, :host 上の --danger-fg のようなトークンと、それらを汎用の --theme-fg、--theme-bg-subtle などに割り当てる .theme-danger クラスです。この間接参照が重要です。--theme-* に基づいて記述したコンポーネントは、1 つのルールですべてのカラー(現在のものと将来追加されるもの)に対応できます。
ネストされたサブツリーに .theme-reset を使用すると、これらの --theme-* トークンが initial に設定され、子要素がコンポーネントのデフォルトに戻ります。
primary、success、danger のキーは必須です。リンク、フォーカスリング、フォームの状態、チェック済みのコントロールなど、ほかのコードがこれらのトークンを参照します。名前を変更したり削除したりすると、ビルドに失敗します。
ステップ 4:背景、前景、境界線用のレイヤーカラー
ニュートラルなサーフェスは $theme-colors には含まれません。scss/_theme.scss にある 3 つの独立したマップで定義されています。
$theme-bgs→--bg-body、--bg-1~--bg-4(順にコントラストが強くなるサーフェス)、および--bg-white、--bg-black、--bg-transparent。$theme-fgs→--fg-body、--fg-1~--fg-4(順に強調度が低くなる前景)。$theme-borders→--border-body、--border-subtle、--border-muted、--border-emphasized。
これらはコンポーネントトークンで、テーマが適用されていない場合のフォールバックとして使用します。例:var(--theme-bg-subtle, var(--bg-1))、var(--theme-border, var(--border-color))。--border-color は $root-tokens にある独立したグローバルトークンで、コンポーネントのデフォルトの境界線の色です。この --border-* ファミリーとは異なる点に注意してください。
$theme-colors とは異なり、これらはフラットなマップなので、追加のサーフェスレベルを簡単に拡張できます。4 つのマップすべてが defaults() を通じてマージされるため、変更するキーだけを渡してください。
ステップ 5:カラーモード
Bootstrap 6 では、モードごとに変数を再宣言しません。すべての適応型トークンは light-dark() のペアで、CSS は継承された color-scheme に基づいて値を解決します。
:root, :hostはcolor-scheme: light darkを設定するため、デフォルトでは OS の設定が使用されます。[data-bs-theme="dark"]と[data-bs-theme="light"]は、そのサブツリーのcolor-schemeを設定してモードを強制します。任意の要素で機能し、ネストにも対応しているため、JavaScript は必要ありません。
そのため、モードの切り替えは属性を 1 つ設定するだけで行えます。また、適応型カラーの定義では、ダークモード用のオーバーライドブロックを書く代わりに light-dark() を使用します。
light-dark() では対応できないケース向けに、2 つのミックスインがあります。
// Non-color values can't go through light-dark()
@include color-mode(dark, $root: true) {
--shadow-strength: 2.4;
}
color-mode($mode, $root) は $color-mode-type 設定を参照します。デフォルトは "media-query" で、@media (prefers-color-scheme: …) を出力します。これを "data" に設定すると、代わりに [data-bs-theme="…"] セレクターを出力します。color-scheme($name) は、常にメディアクエリーを使用する場合のシンプルなラッパーです。
カスタムモードも同様に機能します。独自の [data-bs-theme="blue"] セレクターを追加し、その中でトークンをオーバーライドしてください。
ステップ 6:コンパイル時のオーバーライド
defaults() で構築されるマップ — $colors、$color-tokens、$root-tokens、$theme-colors、$theme-bgs、$theme-fgs、$theme-borders、およびすべてのコンポーネントの $*-tokens — はマージされます。変更するキーだけを渡し、削除する場合は null を渡してください。
ネストされたテーマカラーのマップは、1階層までマージされます。組み込みテーマのロールを1つ変更するには、そのテーマのサブマップ全体を渡してください。一部だけを含むサブマップを渡すと、そのテーマのほかのロールは置き換えられます。
既存のテーマカラーの調整は、1階層下で変更するのが最も簡単です。色相を変えれば、そこから派生するすべての値も追従します。
@use "bootstrap/scss/bootstrap" with (
$blue: oklch(58% 0.21 250)
);
テーマカラーを追加または再スタイルするには、メインのエントリーポイントを通じて一部の $theme-colors マップを渡してください。defaults() によって組み込みの設定は維持されます。サブマップ全体を置き換えない限り、primary、success、danger はそのまま残してください。
@use "bootstrap/scss/bootstrap" with (
$theme-colors: (
"brand": (
"base": var(--indigo-500),
"fg": light-dark(var(--indigo-600), var(--indigo-400)),
"fg-emphasis": light-dark(var(--indigo-800), var(--indigo-300)),
"bg": var(--indigo-500),
"bg-subtle": light-dark(var(--indigo-100), var(--indigo-900)),
"bg-muted": light-dark(var(--indigo-200), var(--indigo-800)),
"border": light-dark(var(--indigo-300), var(--indigo-600)),
"focus-ring": light-dark(color-mix(in oklch, var(--indigo-500) 50%, var(--bg-body)), color-mix(in oklch, var(--indigo-500) 75%, var(--bg-body))),
"contrast": var(--white)
)
)
);
ユーティリティは不要で、テーマカラーをもう1つだけ追加したい場合は、Sass の設定を使わずにクラスを自分で記述してください。コンポーネントが参照するのは --theme-* トークンだけです。
@layer helpers {
.theme-brand {
--theme-base: var(--purple-500);
--theme-bg: var(--purple-500);
--theme-bg-subtle: light-dark(var(--purple-100), var(--purple-900));
--theme-fg: light-dark(var(--purple-600), var(--purple-400));
--theme-border: light-dark(var(--purple-300), var(--purple-600));
--theme-contrast: var(--white);
}
}
これで .theme-brand は、テーマに対応するすべてのコンポーネントで機能します。ただし、ユーティリティと --brand-* ルートトークンは $theme-colors から生成されるため、.bg-brand と var(--brand-bg) は存在しません。
ステップ 7:実行時のオーバーライド
すべてのトークンは CSS カスタムプロパティなので、ほとんどの色の変更では再コンパイルは不要です。
/* Global — repeat on :host if you adopt the stylesheet in a shadow root */
:root,
:host {
--bs-primary-bg-subtle: #eef2ff;
}
/* One subtree */
.marketing-hero {
--bs-theme-bg-subtle: #eef2ff;
}
Sass ではトークン名をプレフィックスなしで記述します(--primary-bg-subtle)。Bootstrap の dist と CDN の CSS では、PostCSS によって --bs- プレフィックスが追加されます。そのため、配布済みの CSS をオーバーライドする場合は --bs-* を、ソースを自分でコンパイルする場合はプレフィックスなしの名前を使用してください。
実行時のオーバーライドはページ単位やテナント単位のテーマ設定に適しています。コンパイル時の設定は、システムのデフォルトを変更するためのものです。
ステップ 8:関数とユーティリティ
scss/_theme.scss にある、主にユーティリティの生成に使われる、カラーマップを横断して値を取得するヘルパーです。
theme-color-values($role)— 色名から、そのロールの生の値へのフラットなマップです。theme-color-refs($role)— 同じマップですが、var(--<name>-<role>)形式の参照を返します。theme-token-refs($map, $prefix)— レイヤーカラーマップに相当する関数です。theme-opacity-values($var, $fallback)—transparentとのcolor-mix()で構築される不透明度の段階です。
scss/_functions.scss の color-contrast($background) は、WCAG のコントラストアルゴリズムを使って、明色、暗色、または黒の前景色を返します。Sass の色の値に対して動作し、var() 参照には対応しません。そのため、ビルド時のスウォッチや生成クラスに使用します。実行時に使う場合は、$theme-colors の contrast ロールを使用してください。
生成されるユーティリティはロール名に従います。テーマカラーごとに .fg-primary、.fg-emphasis-primary、.fg-contrast-primary、.bg-primary、.bg-subtle-primary、.bg-muted-primary、.border-primary、.border-subtle-primary が生成されます。レイヤーカラーにも同様に .bg-1 から .bg-4、.fg-1 から .fg-4、.border-subtle が生成されます。不透明度は同じクラス名のまま数値で段階化され、10刻みで .fg-50、.bg-70、.border-30 のように指定できます。
個別のプロパティではなく要素全体にテーマを適用したい場合は、代わりに .theme-* を使用してください。
ステップ 9:検証
npm run css-lintを実行し、続けてnpm run cssを実行します。- コンパイルされた
dist/css/bootstrap.cssを検索し、想定したトークン(--bs-primary-bg-subtle、--bs-slate-500)が出力されていることを確認します。 - OS の設定、
data-bs-theme="dark"、およびその中にネストされたdata-bs-theme="light"の両方のカラーモードを確認します。 - 新しいテーマカラーのコントラストを検証します。最低限、両方のモードで
bgに対するcontrastと、bg-subtleに対するfgを確認してください。 $colorsまたは$theme-colorsの項目を追加または削除した場合は、生成されるユーティリティと.theme-*クラスが適切に変更されたこと、さらにnpm run docs-buildが引き続き成功することを確認します(ドキュメントではこれらのマップからスウォッチを描画します)。