web制作のしおり

日々の学習をアウトプットします。

33.Sassの便利な書き方を知る③ ~mixin~

本日は昨日書ききれなかったmixinについて学習していきます。

読み方が統一されていなく、ミクシン、ミックスイン、ミキシンなど人によって様々です。

 

mixinとは

CSSのプロパティやバリュー、関数、引数などを予め定義しておいて、

それを色々な場所で使い回せるものです。

例えば、クラスの共通部分をmixinで定義しておいて、各々読み込んで使う。

といったケースです。

 

言葉で伝えるの難しいですね(汗

 

とはいえ、この考え方は以前も触れている気がします。

JavaScriptの「オブジェクト」に似ていると思いませんか。

変数や関数を定義しておいて、呼び出して使う、引数も設定できる。

 

mixinは面白くて、いくつかゼロから作って試してみました。

うまくいくと爽快です。

 

では早速やっていきましょう。

 

まずは書き方を知る

mixinの書き方

 

@mixin mixin名($引数名){

 

スタイル定義や関数定義

@content; 

(※@contentは使用の際に{ }で括られた中身が挿入される箇所です。)

 

}

 

これで定義は終わりです。

定義が終わったら次はどうやって使うかですね。

mixinを呼び出して使う時は@includeを使います。

 

@include mixin名(引数){

 @contentに対応する内容

}

 

では、具体例を踏まえて1つずつ見ていきましょう。

 

具体例で定義の仕方を確認する

@mixin test-styles($font-size , $line-height){

  font-size : $font-size;

  line-height : l$line-height;

  color : white;

       

  &:hover{

    @content;

  }

}

 

上記は、test-stylesという名前のmixinを設定しています。

引数には$font-sizeという名前の変数と、$line-heightという名前の変数を指定し

 

スタイル定義は

font-sizeプロパティとline-heightプロパティそれぞれに引数の値を設定。

colorプロパティで文字色白を設定しています。

疑似要素のhoverを入れ子構造で書いています。

そして、その中身は@contentで、mixinの使用先に記述されている内容が挿入されます。

 

 

定義済みのmixinを使ってみる

.test{

  @include test-styles(16px , 1.5){

          color : red;

  }

}

 

上記は.testクラスの中にmixinのtest-stylesを読み込んでいます。

引数に16px、1.5が指定されそれぞれfont-sizeとline-hightに使われます。

そして、color : redは@contentの部分に挿入された形で最終的なCSSになります。

 

上記を最終的なCSSにすると

 

.test{

  font-size : 16px;

  line-height : 1.5;

  color : white;

}

 

.test :hover{

  color : red;

}

 

このようにCSSに記述されて出力されます。

魔法みたいですよね。すごい。

 

メディアクエリの処理をmixinを使って書く

まずはコードから、

 

$sp-max-width : 767px;
$pc-min-width : $smart-phone-max-width + 1;


$breakpoints:(
    'sp':'screen and (max-width: #{$sp-max-width})',
    'pc':'screen and (min-width: #{$pc-min-width})'
);

 

@mixin media-query($breakpoint){
    @media #{map-get($breakpoints,$breakpoint)}
    {
        @content;
    }
}

 

拒否反応起こしそうなそこのあなた!大丈夫です、私が1つずつ解説します。

 

それではやっていきましょう。

 

まず冒頭では変数を定義しています。

ここまでがスマホ、ここからがPCという区切り(ブレークポイント)

に使う数字を変数として先に定義しています。

 

$sp-max-width : 767px;
$pc-min-width : $smart-phone-max-width + 1;

 

今回はスマホとPCの2種類なので、

PCのmin-widthはスマホのwidthに1足した値を代入しています。

これで、区切りを変更するときも767pxの部分だけを修正すればOKですね。

 

次は、

$breakpoints:(
    'sp':'screen and (max-width: #{$sp-max-width})',
    'pc':'screen and (min-width: #{$pc-min-width})'
);

 

昨日学習したmap型変数ですね。

キーはスマホかPCで区別がつくように設定し、バリューには文字列を代入しています。

#{ } で括られた変数は文字列として使用されます。

ですので、例えばmap型変数の値を取得する為に

map-get($breakpoints , sp)

とした場合は

返り値として「screen and (max-width: 767px)」という文字列が取得できるわけです。

 

最後に

@mixin media-query($breakpoint){
    @media #{map-get($breakpoints,$breakpoint)}
    {
        @content;
    }
}

ようやく下準備も終わり、ようやくmixinの出番ですね。

 

media-queryという名前で、引数に$breakpointを設定しました。

メディアクエリのキーワード、@media の後に

map-get()メソッドでmixinの引数に設定した値をキーとして、文字列を取得しています。

もちろん#{ }で括っているので、最終的に文字列として記述されます。

 

@contentで、@media ~{  }の中に、mixinの呼び出し先{ }内に記述されている内容が挿入されるわけです。

 

具体例でどんな出力がされるか確認する

 

ではmixinを呼び出して使ってみましょう。

 

.test{

  float : left;

  @include media-query(sp){

    float : none;

  }

}

 

これで使用する際の記述は終わりです。

カンタンですね。

 

こちらも1つずつ見ていきます。

.testクラスには元々float : leftが設定されています。

そこへmedia-query を引数にspを設定・挿入して.testクラスの入れ子になりました。

@contentの部分にはfloat : none;を設定。

 

最終的なCSS出力を見てみましょう

 

.test{

  float : left;

}

 

@media screen and (max-width: 767px){

  .test{

    float : none;

  }

}

 

このように出力される…。

これを毎回手書きで書くよりも、

レスポンシブさせたい所に入れ子かつピンポイントで書いていける

というのが素晴らしいですね。

 

これにさらにmixinを組み合わせて、引数を2つ用意して、pcの時のバリュー、spの時のバリューを代入すると簡単記述されるなんて言うこともできそうですよね。

 

余談

追記で下記mixinを定義すると、さらに簡単にクラスの記述ができるはずです…。

@mixin float($pc-float,$sp-float){
    float: $pc-float;
    @include media-query(sp){
        float: $sp-float;
    }
}

 

すると、

 

.test{

  @include float( left , none);

}

とするだけで、

 

.test{

  float : left;

}

 

@media screen and (max-width: 767px){

  .test{

    float : none;

  }

}

ここまで出力してくれます。

スゴイ。楽しい。

 

今日のまとめ

  • mixinはJavaScriptでやったオブジェクトに似ている
  • スタイルのテンプレート的な役割を持ち、微妙に変化させたい場合は引数を使う
  • map型、入れ子構造、mixin等組み合わせて使うと、同じコードを書く量が減る

 

今日はmixinについて学習しました。

長い。

とはいえ、それだけ骨太の昨日だと思います。ぜひ使いこなして行きたいですね。

 

では、また。