LoginSignup
7
7

More than 5 years have passed since last update.

BEMITのレスポンシブなwidthヘルパークラスを生成する@mixin

Last updated at Posted at 2015-09-30

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内で数が増えていくので分子になります。\/はスラッシュをエスケープしていて、$breakpointnullに指定されているので@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})
    }
}
7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7