Sass
Sass ソースファイルを利用して、変数、マップ、ミックスイン、そして関数を活用しプロジェクトをカスタマイズしましょう。
Sass ソースファイルを利用して、変数、マップ、ミックスインなどの機能を使いこなしましょう。Bootstrap のビルドにおいては、ブラウザの丸めによる問題を防ぐため、Sass の丸め誤差の精度を 6 (デフォルトは5) に上げています。
ファイル構造
可能であれば、Bootstrap のコアファイルを編集するのは控えましょう。代わりに Bootstrap をインポートしてそれを編集・拡張する新しいスタイルシートを作ります。npm のようなパッケージマネージャーを使っている場合、以下のようなファイル構造になっているでしょう:
your-project/
├── scss
│ └── custom.scss
└── node_modules/
└── bootstrap
├── js
└── scss
もしパッケージマネージャーを使わずにソースファイルをダウンロードした場合、似た構造をセットアップしなくてはなりませんが、Bootstrap のソースファイルはあなた自身のコードとはまとめないでください。
your-project/
├── scss
│ └── custom.scss
└── bootstrap/
├── js
└── scss
インポート
custom.scss
では、Bootstrap の Sass ファイルをインポートします。これには、全ての Bootstrap を含む方法と、必要な部分のみを選ぶ方法があります。私たちは後者を推奨しますが、コンポーネントの間にはいくつかの要求または依存関係を持つため、注意する必要があります。加えて、プラグインのためにいくつかの JavaScript をインポートする必要があります。
// Custom.scss
// Option A: Include all of Bootstrap
@import "../node_modules/bootstrap/scss/bootstrap";
// Custom.scss
// Option B: Include parts of Bootstrap
// Required
@import "../node_modules/bootstrap/scss/functions";
@import "../node_modules/bootstrap/scss/variables";
@import "../node_modules/bootstrap/scss/mixins";
// Optional
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/images";
@import "../node_modules/bootstrap/scss/containers";
@import "../node_modules/bootstrap/scss/grid";
以上のセットアップをすることで、custom.scss
の中で自由に Sass 変数やマップを編集することができます。必要であれば、// Optional
セクションの後に Bootstrap のパーツを追加することも可能です。しかし、全てのインポートを行う bootstrap.scss
から始めることをおすすめします。
変数の初期値
Bootstrap の全ての Sass 変数は !default
フラグを持っており、Bootstrap のソースコードを編集すること無く初期値を変更することができます。必要な場合は、変数をコピー & ペーストし、その値を編集して !default
フラグを削除します。すでに変数に値が代入されている場合は、初期値による再代入は行われません。
scss/_variables.scss
では全ての Bootstrap の変数が確認できます。いくつかの変数は値が null
となっていますが、これらは設定を上書きしない限りプロパティとして出力されることはありません。
同じ Sass ファイル内で変数の上書きをしたい場合は、デフォルトの変数の前か後のどちらでも書くことができます。しかし、複数の Sass ファイル間の場合は、Bootstrap の Sass ファイルをインポートされる前に上書きする必要があります。
以下は npm 経由でインストールした Bootstrap のインポートとコンパイル時に <body>
の background-color
と color
を変更する例です:
// Your variable overrides
$body-bg: #000;
$body-color: #111;
// Bootstrap and its default variables
@import "../node_modules/bootstrap/scss/bootstrap";
Bootstrap のどの変数についても同様に行うことができます。下で説明するグローバルオプションでも同様です。
マップとループ
Bootstrap は Sass マップ、すなわち関連する CSS を簡単に生成できるキーバリューペアを持っています。Sass マップはカラー、グリッドのブレークポイントなどで使われています。Sass 変数と同じように、これらの Sass マップは上書き及び拡張できるように !default
フラグが付与されています。
いくつかの Sass マップはデフォルトで空のマップにマージされています。これにより簡単に Sass マップを拡張できますが、マップから要素を 削除 することは難しいです。
マップの編集
$theme-colors
マップの全ての変数は個別の変数で定義されています。そのため $theme-colors
マップの変数を変更するには、カスタム Sass ファイルで次のようにします:
$primary: #0074d9;
$danger: #ff4136;
この結果、これらの変数は Bootstrap の $theme-colors
マップに次のようにセットされます。
$theme-colors: (
"primary": $primary,
"danger": $danger
);
マップへの追加
$theme-colors
へ新しい色を追加するためには、新しいキーと値を与えます。
この場合、Bootstrap は新しい $custom-colors
マップを用意し $theme-colors
にマージします。
// Create your own map
$custom-colors: (
"custom-color": #900
);
// Merge the maps
$theme-colors: map-merge($theme-colors, $custom-colors);
マップからの削除
$theme-colors
、もしくは別のマップから色を削除するには、map-remove
を使います。// Required
と // Optional
の間に書く必要があることに注意してください:
// Required
@import "../node_modules/bootstrap/scss/functions";
@import "../node_modules/bootstrap/scss/variables";
@import "../node_modules/bootstrap/scss/mixins";
$theme-colors: map-remove($theme-colors, "info", "light", "dark");
// Optional
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
...
要求されるキー
Bootstrap は使う、拡張する Sass マップにいくつかの特定のキーが含まれることを仮定しています。マップをカスタマイズした場合、Sass マップのキーが既に使われているというエラーに遭遇するかもしれません。
例えば、$theme-colors
の primary
、success
、danger
キーをリンク、ボタン、フォームの状態として使ったとします。これらのキーの値を入れ替えることは問題ありませんが、これらのキーを削除した場合は Sass のコンパイルで問題が起こる可能性があります。この場合、それらの値を使う Sass コードを変更する必要があります。
関数
色
Sass マップ と同じく、テーマカラーは $primary
のように独立した変数として使うこともできます。
.custom-element {
color: $gray-100;
background-color: $dark;
}
Bootstrap の tint-color()
と shade-color()
関数を使うことで、明るくしたり暗くしたりできます。これらの関数は白や黒と色を混ぜ合わせることで実現されており、Sass の lighten()
や darken()
関数とは変化量が異なるため、予想と異なる結果になる可能性があります。
// Tint a color: mix a color with white
@function tint-color($color, $weight) {
@return mix(white, $color, $weight);
}
// Shade a color: mix a color with black
@function shade-color($color, $weight) {
@return mix(black, $color, $weight);
}
// Shade the color if the weight is positive, else tint it
@function shift-color($color, $weight) {
@return if($weight > 0, shade-color($color, $weight), tint-color($color, -$weight));
}
使う際には、関数を呼ぶためには元の色と効果の重さのパラメータを渡す必要があります。
.custom-element {
color: tint-color($primary, 10%);
}
.custom-element-2 {
color: shade-color($danger, 30%);
}
色のコントラスト
WCAG 2.0 色のコントラストについてのアクセシビリティ基準を満たすため、製作者はいくらかの例外を除き、必ず 4.5:1 以上のカラーコントラストを設ける必要があります。
Bootstrap で追加されている関数の一つに色のコントラスト関数である color-contrast
があります。これは WCAG 2.0 のアルゴリズムを用いてコントラストの閾値を計算します。このアルゴリズムは sRBG
色空間における 相対輝度を基準に、自動的に light (#fff
)、dark (#212529
) または black (#000
) コントラストの色を返します。この関数は特に複数のクラスを生成するためのミックスインやループで便利です。
これは $theme-colors
マップからカラースウォッチを生成する例です:
@each $color, $value in $theme-colors {
.swatch-#{$color} {
color: color-contrast($value);
}
}
ループだけでなく、一回だけ利用することもできます:
.custom-element {
color: color-contrast(#000); // returns `color: #fff`
}
色のマップ関数にベースの色を渡すこともできます:
.custom-element {
color: color-contrast($dark); // returns `color: #fff`
}
SVG のエスケープ
SVG の背景画像に含まれる <
、>
、#
文字をエスケープするには、escape-svg
関数を使います。
加算関数と減算関数
Bootstrap では、CSS の calc
関数のラッパーである add
と substract
関数が用意されています。これらは単位のない 0
値を calc
関数に渡した際に発生するエラーを防ぐためにあります。calc(10px - 0)
は数学的には正しいですが、全てのブラウザでエラーとなります。
calc
が有効な例:
$border-radius: .25rem;
$border-width: 1px;
.element {
// Output calc(.25rem - 1px) is valid
border-radius: calc($border-radius - $border-width);
}
.element {
// Output the same calc(.25rem - 1px) as above
border-radius: subtract($border-radius, $border-width);
}
calc
が無効な例:
$border-radius: .25rem;
$border-width: 0;
.element {
// Output calc(.25rem - 0) is invalid
border-radius: calc($border-radius - $border-width);
}
.element {
// Output .25rem
border-radius: subtract($border-radius, $border-width);
}