BEMITというのはcsswizardry (Harry Roberts)が提唱しているBEM(MindBEMding)をベースにした命名規則です。
BEMIT: Taking the BEM Naming Convention a Step Further – CSS Wizardry
その中で「Responsive Suffixes」というものがあります。これは、そのclassにブレイクポイントが指定されていることを明示するために@md
といった接尾辞を付けるというものです。
<div class="o-media@md">
<img src="" alt="" class="o-media__img@md" />
<p class="o-media__body@md"></p>
</div>
今回はこのResponsive Suffixesに対応したレスポンシブなwidth
のヘルパークラスを生成する@mixinを紹介します。この@mixinはGitHubに上がっていたソースコードに若干の変更を加えたものです。
frcss/_trumps.widths.scss at master · csswizardry/frcss
生成されるclassとマークアップ例
生成されるclassはこのようになります。
.u-1\/12 { width: 8.33333% !important; }
.u-2\/12 { width: 16.66667% !important; }
.u-3\/12 { width: 25% !important; }
.u-4\/12 { width: 33.33333% !important; }
.u-5\/12 { width: 41.66667% !important; }
.u-6\/12 { width: 50% !important; }
.u-7\/12 { width: 58.33333% !important; }
.u-8\/12 { width: 66.66667% !important; }
.u-9\/12 { width: 75% !important; }
.u-10\/12 { width: 83.33333% !important; }
.u-11\/12 { width: 91.66667% !important; }
.u-12\/12 { width: 100% !important; }
@media screen and (min-width: 400px) {
.u-1\/12\@sm { width: 8.33333% !important; }
.u-2\/12\@sm { width: 16.66667% !important; }
.u-3\/12\@sm { width: 25% !important; }
.u-4\/12\@sm { width: 33.33333% !important; }
.u-5\/12\@sm { width: 41.66667% !important; }
.u-6\/12\@sm { width: 50% !important; }
.u-7\/12\@sm { width: 58.33333% !important; }
.u-8\/12\@sm { width: 66.66667% !important; }
.u-9\/12\@sm { width: 75% !important; }
.u-10\/12\@sm { width: 83.33333% !important; }
.u-11\/12\@sm { width: 91.66667% !important; }
.u-12\/12\@sm { width: 100% !important; }
}
@
をCSSで使用するためにはバックスラッシュ\
でエスケープする必要があります。HTMLにclassを指定する時にはエスケープする必要はありません。
<div class="c-grid">
<div class="c-grid__item u-8/12@md"></div>
<div class="c-grid__item u-4/12@md"></div>
</div>
@mixin
まずブレイクポイント用の変数をマップで定義します。
$breakpoints: (
'sm': 'screen and (min-width: 400px)',
'md': 'screen and (min-width: 768px)',
'lg': 'screen and (min-width: 1000px)',
'xl': 'screen and (min-width: 1200px)',
) !default;
使用する@mixinはこのようになります。上記の変数と合わせてSassMeisterに貼り付けるとコンパイル結果が確認できます。
// 取得したいカラム数をリスト形式で指定します。
// 例えば`1 2`を指定すると1/1, 1/2, 2/2の`width`を取得できます。
$width-cols: 12 !default;
// @param {Number} $cols - 取得したいカラム数を指定します。
// @param {String} $breakpoint(null) - ブレイクポイント用のキーワードを付与します。
// @requires {List} $width-cols - 取得するカラム数を定義しています。
@mixin width($cols, $breakpoint: null) {
// 受け取った値を$colに渡し、値の数だけ繰り返します。
@each $col in $cols {
// 格納した数値を繰り返して、その回数を$iに格納します。
@for $i from 1 through $col {
// .u- + 分子($i)/分母($col) + ブレイクポイント名という命名規則。
// バックスラッシュ`\`でスラッシュ`/`をエスケープします。
.u-#{$i}\/#{$col}#{$breakpoint} {
// `percentage()`関数でパーセンテージに変換します。
width: percentage($i / $col) !important;
}
}
}
}
// ブレイクポイントのないclassを生成します。
@include width($width-cols);
// ブレイクポイント付きのclassを生成します。
// @requires {Map} $breakpoints - ブレイクポイントを定義しています。
@each $name, $breakpoint in $breakpoints {
@media #{$breakpoint} {
// @とkeyを第二引数に渡します。
@include width($width-cols, \@#{$name})
}
}
width
という@mixinを作成し、レスポンシブ対応したclassを生成する場合は@eachを併用します。まず生成するカラム数を定義します。よく使われる12カラムのグリッドシステムだけが必要な場合は12
と1つだけ指定をして、2カラムと3カラムも必要な場合は2 3 12
とリストとして指定します。
$width-cols: 12 !default;
上記の変数に指定した数値の数だけ@eachで繰り返します。その数値は変数$col
に格納します。
@each $col in $cols {
数値を格納した変数$cols
を利用して、@each内で@forを使用します。
@for $i from 1 through $col {
次にセレクタを指定します。$cols
は@for内で値が変わらないので分母になり、$i
は@for内で数が増えていくので分子になります。\/
はスラッシュをエスケープしていて、$breakpoint
はnull
に指定されているので@mixinの第二引数を指定しない限り反映されません。
.u-#{$i}\/#{$col}#{$breakpoint} {
width: percentage($i / $col) !important;
}
この状態で@includeするとブレイクポイントが指定されていないclassが生成されます。
@include width($width-cols);
最後に@eachを使用してブレイクポイントを付けたclassを生成します。マップ$breakpoints
から'screen and (min-width: 400px)'
などのブレイクポイントの条件を@mediaに渡します。'sm'
などのkeyは@mixinの第二引数に渡します。
@each $name, $breakpoint in $breakpoints {
@media #{$breakpoint} {
@include width($width-cols, \@#{$name})
}
}