2016/10/18 20:07:08

SaSSでメディアクエリをmixinでまとめる

目次(クリックするとジャンプします)
  • 1:メディアクエリをまとめる
  • 1.1:contentディレクティブを使った方法
  • 1.2:複数ブレイクポイントの場合
  • 2:もう少し改良できるかも
  • 2.1:mixinをさらにまとめたmixinでメディアクエリを一撃
  • 3:まとめ

メディアクエリをまとめる

多くの場合ブレイクポイントを何箇所か設定するかと思います。するとブレイクポイントに対してひとまとめにCSSを記述できると楽ですよね。

SaSSでメディアクエリを扱う時はmixinを使うとメディアクエリを容易に設定することが出来便利です。

contentディレクティブを使った方法

一箇所ごとに書く場合は以下のようなmixinが考えられます。

@mixin media_query{
    @media (max-width:320px){
        @content;
    }
}

contentディレクティブを使った方法ですね。contentディレクティブを書くと、ブロックコンテンツを受け取ることができます。

実際に使う時は以下のように使うことができます。

 body{
@include media_query{
        width:100%;
    }
}

これは以下のように展開されます。

@media (max-width: 320px) {
    body{
        width:100%; 
    }
}

便利ですね。

複数ブレイクポイントの場合

上記の方法で複数のブレイクポイントの場合は以下のように行います。

ブレイクポイントごとにmixinを作ります。

@mixin media_query_mobile{
    @media (max-width:320px){
        @content;
    }
}

@mixin media_query_phablet{
    @media (min-width: 320px) and (max-width: 768px){
        @content;
    }
}

@mixin media_query_tablet{
    @media (min-width: 768px) and (max-width: 1024px){
        @content;
    }
}

@mixin media_query_pc{
    @media (min-width: 1024px) and (max-width: 1366px){
        @content;
    }
}

@mixin media_query_large_pc{
    @media (min-width: 1366px){
        @content;
    }
}

これをこのように使います。

 body{
    @include media_query_mobile{
        width:100%;
    }
    @include media_query_phablet{
        width:90%;
    }
    @include media_query_tablet{
        width:80%;
    }
    @include media_query_pc{
        width:75%;
    }
    @include media_query_large_pc{
        width:60%;
    }
}

これは以下のように展開されます。

@media (max-width:320px){
    body{
        width:100%;
    }
}
@media (min-width: 320px) and (max-width: 768px){
    body{
        width:90%;
    }
}
@media (min-width: 768px) and (max-width: 1024px){
    body{
        width:80%;
    }
}
@media (min-width: 1024px) and (max-width: 1366px){
    body{
        width:75%;
    }
}
@media (min-width: 1366px){
    body{
        width:60%;
    }
}

おお!便利ですね。この方法のいいところは書きたい場所にメディアクエリを入れることができることです。

これによってブレイクポイントごとの記述を一箇所に集めることができ、コードの見通しがよくなります。

もう少し改良できるかも

ただ、メディアクエリが欲しい場所にブレイクポイント分のmixinをいちいちincludeするのは面倒なきもします。

ですのでさらにmixinでまとめて使いやすくしてみます。mixinmixinですね。

通常ブレイクポイントは1セットとして使うと思うので、あまり1つのブレイクポイントだけを書くことは無いのではないかと思います。

であれば、配列でプロパティを値を与えられるようにして、mixinを1つ記述するだけですべてのブレイクポイントに対しての記述できれば便利ですよね。

mixinをさらにまとめたmixinでメディアクエリを一撃

それを企図して作ったmixinが以下です。contentディレクティブは使っていませんが、代わりにプロパティと値を受け取れるようになっています。

$breakpoint-s : 425px;
$breakpoint-m : 768px;
$breakpoint-l : 1024px;
$breakpoint-xl : 1366px;


@mixin xs($p,$v){
  @media (max-width:$breakpoint-s){
  #{$p}:$v;
  }
}
@mixin s($p,$v){
  @media (min-width:$breakpoint-s)and(max-width:$breakpoint-m){
  #{$p}:$v;
  }
}
@mixin m($p,$v){
  @media (min-width:$breakpoint-m)and(max-width:$breakpoint-l){
  #{$p}:$v;
  }
}
@mixin l($p,$v){
  @media (min-width:$breakpoint-l)and(max-width:$breakpoint-xl){
  #{$p}:$v;
  }
}
@mixin exl($p,$v){
  @media (min-width:$breakpoint-xl){
  #{$p}:$v;
  }
}

@mixin media(
$propaty-value-array
){
    @include xs(nth($propaty-value-array,1),nth($propaty-value-array, 2));
    @include s(nth($propaty-value-array,1),nth($propaty-value-array, 3));
    @include m(nth($propaty-value-array,1),nth($propaty-value-array, 4));
    @include l(nth($propaty-value-array,1),nth($propaty-value-array, 5));
    @include exl(nth($propaty-value-array,1),nth($propaty-value-array, 6));
}

プロパティと各ブレイクポイントでの値は1セットになることが多いかと思うので、配列を渡す形にしています。

配列の構成は1番目にプロパティ名、2番目以降が各ブレイクポイントの値を想定します。

配列から値を取り出すのにはnth関数を使います。

nth($array, index)

配列変数とインデックス番号を指定します。これで対応する値が取得できます。

多くのプログラミング言語において配列のインデックスは0から始まりますが、SaSSでは1から始まりますので注意してください。

実際に使う時は以下の様に記述します。

body{
    @include media_query(width 100%  90% 80% 75% 60%);
}

例で配列は()の中でベタ書きしています。

カンマ無しで空白区切りで値を書いていくと配列とみなされますので単純な値の場合はこの書き方でもOKです。

ただ空白区切りの値、たとえばmarginなどの全方向指定などはこの書き方ができないので、予め配列を作ってから行うのが良いかと思います。

配列変数を事前につくる場合は、以下のような感じになります。

例ではローカル変数としていますが、もちろんグローバル変数でも大丈夫ですよ。

.class{
    $var : margin,0 0 0 0,0 2px 2px 0,3px 0 0 3px, 2px,2px 5px;
    @include media(nth($var,1)  nth($var,2) nth($var,3) nth($var,4) nth($var,5) nth($var,6));
}

これは以下のように展開されます。

@media (max-width: 425px) {
    .class {
        margin: 0 0 0 0;
    } 
}
@media (min-width: 425px) and (max-width: 768px) {
    .class {
        margin: 0 2px 2px 0; 
    }
}
@media (min-width: 768px) and (max-width: 1024px) {
     .class {
        margin: 3px 0 0 3px;
     }
 }
@media (min-width: 1024px) and (max-width: 1366px) {
    .class {
        margin: 2px;
     }
 }
@media (min-width: 1366px) {
    .class {
        margin: 2px 5px;
     }
 }

ちゃんと値が与えられていますね。

これでメディアクエリに尻込みすることなくバンバン記述することができそうです。

やった!

まとめ

メディアクエリをまともに書くとほんとに苦労するんですよね…。色んな所にCSSが飛び散っちゃうので修正があると直すのが大変です。

SaSSは本当に便利ですね。今までCSSを効率よく書けなくて悩んでいたのがうそのようです。もっと早く使えばよかったですよ。