Sassのmixinでメディアクエリを管理する



多くのデバイスに対応させるWebサイトの制作では、CSSのメディアクエリを使ってレスポンシブWebデザインを実装していきますが、Sassを使ったWeb制作でも、ベースとなるスタイルの後にメディアクエリを使う、またはネスト(入れ子)でメディアクエリを記述していくことになります。

Sassでは変数が扱えたり、mixinで使いまわしたいスタイルを定義しておいたり、便利な概念がたくさんあります。

レスポンシブWebデザインを実装するのに必要なメディアクエリも、デバイス幅で切り替えるブレイクポイントをmixinで管理しておくと、効率よくコードを書いていくことができます。
ブレイクポイントの幅の数値を、毎回記述していくのはすごく手間なので、定義しておいて呼び出してあげると楽です。

ということで今回は、Sassのmixinでメディアクエリを管理する方法についてご紹介していきます。

ここではサンプルとして、Sass(scss)ファイルを分割で管理して説明していきます。
メディアクエリの指定を「responsive.scss」で管理してもいいですが、Sassではネストでメディアクエリを記述していけますので、今までのCSSのように書いていくか、対象のセレクタに対してネストでメディアクエリを書いていくは好みによります。

以下、Dart Sassの記法での、@useでパーシャルファイルを呼び出した例です。

Sassファイルを分割で管理



ファイルの分割管理について気になる方は、以下の記事でご紹介しています。



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

mixinでメディアクエリを定義する


サンプルでは、main.scssにスタイルを書いていきます。
今回は、mixinでメディアクエリを管理していく内容になりますので、responsive.scssは必要なく、main.scssにネストで記述していきます。

まずは、通常のメディアクエリのネストの書き方です。

_main.scss

body {
  background-color: #bebeff;
  @media screen and (min-width: 768px) {
    background-color: #ffbebe;
  }
  @media screen and (min-width: 1025px) {
    background-color: #cacaca;
  }
}



メディアクエリをネストで記述していく中で、毎回デバイス幅のブレイクポイントの数値を記述する必要がありますので、わかっていても少々面倒です。
この問題を解決するために、mixinでメディアクエリを管理します。

mixinを定義していきますがその前に、
デバイス幅で切り替えるブレイクポイントを、「マップ」で管理していきます。

マップとは、プログラミングの連想配列の概念と同じで、キーに対して値を設定するものです。
以下、マップの構文になります。

$マップの名前: (
  キー01: キー01に対する値,
  キー02: キー02に対する値,
  キー03: キー03に対する値
);



サンプルとしてここでは、モバイルファーストを想定したブレイクポイントを設定していきます。
マップを設定してから、mixinを記述していきます。

_mixin.scss

$breakpoint: (
  sp: 'screen and (max-width: 767px)',
  tab: 'screen and (min-width: 768px)',
  pc: 'screen and (min-width: 1025px)'
);

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


マップの名前はわかりやすく「breakpoint」としました。
キーは3つ「sp, tab, pc」として、カンマ区切りで複数用意します。
そして各キーの値に文字列として、メディアクエリを「’ ‘(シングルクォーテーション)」内にセットします。
ここまででマップの設定は完了です。

続いてmixinの定義です。
mixin名を「mq」としました。そしてmixinに引数「$bp」を用意します。
mixinの処理として、@mediaを使用してメディアタイプ(screen)から理論演算子(and)、ブレイクポイントとメディアクエリを記述していきますが、その情報はブレイクポイントのマップから取得してきます。

まず、処理の中にマップの情報を文字列として挿入するために、「#{ }」で文字列のインターポレーションを設定します。
インターポレーションとは、数値や文字列の書き入れや挿入を意味します。
そして、マップから値を取得するには、map-get()関数を使います。

map-get($マップの名前, 取得したいキー)


対象のマップから取得したいキーを指定すれば、キーに対する値(screen and (〇〇〇-width: 〇〇〇px))が設定できます。

最後に、mixinの処理には「@content」を記述して、任意のスタイルが記述できるようにします。

mixinを作成しましたら、style.scss等で、@includeでmixinを呼び出します。

@include mixinの名前(引数) {

}


今回用意したmixinですと、以下のように記述していきます。

@include mq(tab) {

}


mqというmixinから、引数(tab)がmixinのプログラムに引き渡され、以下のコードが生成されます。

@media screen and (min-width: 768px) {

}

mixinのメディアクエリを呼び出す


サンプルでは、Dart Sassの記法で書いていますので、@useではas節で独自の名前空間「m」でmixinを呼び出します。
以下、mixinで管理するメディアクエリをネストで記述したサンプルです。

_main.scss(またはstyle.scss)

body {
  background-color: #bebeff;
  @include m.mq(tab) {
    background-color: #ffbebe;
  }
  @include m.mq(pc) {
    background-color: #cacaca;
  }
}
マップとmixinの定義



ネストでの記述では、名前空間「m」を連結演算子の「.(ドット)」を使い、「m.mp()」のように@includeでmixinを呼び出します。
mixinの引数には、「tab」や「pc」といった引数を指定し、mixinの処理内に値を引き渡して、マップのキーに対する値(メディアクエリ)を呼び出します。

Sassファイルをコンパイルすると、以下のようにCSSが生成されます。

style.css

body {
  background-color: #bebeff;
}
@media screen and (min-width: 768px) {
  body {
    background-color: #ffbebe;
  }
}
@media screen and (min-width: 1025px) {
  body {
    background-color: #cacaca;
  }
}
mixinでのメディアクエリの管理とCSSの生成



もし、ブレイクポイントを変更する時があれば、mixinのマップのキーの値を変更するだけとなります。

以下、ここまでの実装の流れです。
動画(4分ほど)



動画でのSassファイルのコンパイルは、便利なプラグインを使っています。
Visual Studio Codeをご利用の方におすすめです。

まとめ


ブレイクポイントは、3つ、4つほどでサイトを構築するのが、スタイルの上書きもコードも増えることもないので、良いCSS設計だと個人的に思いますので、ここでは、モバイルファーストで3つのブレイクポイントで管理するサンプルでご紹介してきました。

もちろん、複雑なデザインで微調整が必要になる場合は、mixinでブレイクポイントを増やして、わかりやすい名前で管理してください。
あまり増えすぎると、混乱することもありますのでご注意を。

切り替える幅の数値は、皆さんのお好みのサイズやデザインに合わせてください。

また、メディアクエリについてはMedia Queries Level 4からRange型が扱えるようになり、範囲指定の構文が拡張されました。
以下の記事でご紹介しています。