ブレイクポイントや使用回数が増えるに連れてどんどん管理などが面倒になってくるMedia Queries(メディアクエリ)を、Sassのmixinを使って利用しやすく且つ管理もしやすいようにしたスニペットを紹介します。ここで紹介する以外にも方法はあるとは思いますが、個人的に過去に使っていたとか普段から使っているものを3つ紹介します。
条件分岐を使う
ひとつ目は条件分岐を使ってひとつずつブレイクポイントを指定したものです。
ブレイクポイントの追加をしたい場合は同じように条件分岐を追記し、逆に不要なものがあれば該当の条件分岐を消せば変更できます。
また、各ブレイクポイントは数値での指定ではなく「small」や「large」という形でそれぞれ用意しており、使用時は「usage」にあるようにこれらを引数に指定します。
こうしておくことで後で数値を変更することになった場合でも、mixin内で記述している数値部分のみ変更すれば、このmixinを使ってMedia Queriesを指定している箇所に関してはすべてその変更した数値が反映されるので変更が非常に楽になりますし、Media Queries使用箇所をすべてこのmixinで対応すればサイト内でどれくらいブレイクポイントがあるのかも把握しやすいです。
自分は後で新しくブレイクポイントを追加するのが容易などの理由で、大体この「xsmall」「small」「medium」「large」「xlarge」を利用していますが、例えば確実に3つのブレイクポイントしか使わないとわかっていて且つわかりやすくしたいなら「mobile」「tablet」「laptop」みたいな形にしたりもできます。
mixin
SCSS
@mixin mq($breakpoint: medium) {
@if $breakpoint == xsmall {
@media screen and (min-width: 320px) {
@content;
}
} @else if $breakpoint == small {
@media screen and (min-width: 600px) {
@content;
}
} @else if $breakpoint == medium {
@media screen and (min-width: 768px) {
@content;
}
} @else if $breakpoint == large {
@media screen and (min-width: 1024px) {
@content;
}
} @else if $breakpoint == xlarge {
@media screen and (min-width: 1280px) {
@content;
}
}
}
使用時は下記のように記述し、デフォルトで「medium」を設定しているので「medium」を指定したい場合は@include mq
のみでいけます。
他のサイズを指定する場合は、その下にあるように引数に指定サイズを記述します。
※デフォルトを「medium」から別のものに変更したい場合は、mixin内の赤文字表記部分を任意のものに変更してください。
usage
SCSS
.elements {
@include mq {
/* @include mq */
}
@include mq(large) {
/* @include mq(large) */
}
}
output
CSS
@media screen and (min-width: 768px) {
.elements {
/* @include mq */
}
}
@media screen and (min-width: 1024px) {
.elements {
/* @include mq(large) */
}
}
マップを使う #1
こちらはマップを用いたmixinで見た目も先ほどのものよりスッキリしていると思います。
ブレイクポイントの調整は条件分岐を利用したときと同ルールで、追加をしたい場合はマップ内に同じような形で追記していき、逆に不要なものがあれば該当のものをマップから消せば変更できます。
コードの見た目は変わりましたが、各ブレイクポイントは数値での指定ではなく「small」や「large」という形で用意してあったり、使用時はそれらを引数に指定するなど基本的な使い方は条件分岐を利用したときと同じになります。
また、同じくデフォルトの指定は「medium」となっているので、このmixinをそのまま利用し「medium」を使用する場合は引数指定なしで利用できます。
※デフォルトを「medium」から別のものに変更したい場合は、mixin内の赤文字表記部分を任意のものに変更してください。
mixin
SCSS
$mq-breakpoints: (
'xsmall': 320px,
'small' : 600px,
'medium': 768px,
'large' : 1024px,
'xlarge': 1280px,
);
@mixin mq($breakpoint: medium) {
@media screen and (min-width: #{map-get($mq-breakpoints, $breakpoint)}) {
@content;
}
}
usage
SCSS
.elements {
@include mq {
/* @include mq */
}
@include mq(large) {
/* @include mq(large) */
}
}
output
CSS
@media screen and (min-width: 768px) {
.elements {
/* @include mq */
}
}
@media screen and (min-width: 1024px) {
.elements {
/* @include mq(large) */
}
}
マップを使う #2
上で紹介したきたのはいずれもmin-width
のみを使用しているもの(もちろん少し内容を変更・追記すればmax-width
も使用できます)でしたが、こちらはmin-width
だけでなくmax-width
での指定も楽にできるようにしたmixinで、こちらもブレイクポイントの管理にはマップを使用したものになります。
mixin
SCSS
$mq-breakpoints: (
'xsmall': 320px,
'small' : 600px,
'medium': 768px,
'large' : 1024px,
'xlarge': 1280px,
);
@mixin mq($breakpoint: medium, $rule: min, $subtraction: false) {
$breakpoint: map_get($mq-breakpoints, $breakpoint);
@if $rule == max and $subtraction {
$breakpoint: $breakpoint - 1;
}
@media screen and (#{$rule}-width: $breakpoint) {
@content;
}
}
min-width
単純にmin-width
を利用した指定は、「マップを使う #1」と同じように@include mq
や@include mq(large)
という形で記述します。
usage
SCSS
.elements {
@include mq {
/* @include mq */
}
@include mq(large) {
/* @include mq(large) */
}
}
output
CSS
@media screen and (min-width: 768px) {
.elements {
/* @include mq */
}
}
@media screen and (min-width: 1024px) {
.elements {
/* @include mq(large) */
}
}
max-width
max-width
を利用した指定をしたい場合は、第2引数にmax
を記述することで使用できるようになっています。
また、主に後ほど紹介するネスト使用時を想定して用意したものになりますが、第3引数でtrue
を記述して使用した場合は指定したブレイクポイントの値から-1した値を使ってmax-width
を出力するようになっています。
usage
SCSS
.elements {
@include mq(small, max) {
/* @include mq(small, max) */
}
@include mq(large, max, true) {
/* @include mq(large, max, true) */
}
}
output
CSS
@media screen and (max-width: 600px) {
.elements {
/* @include mq(small, max) */
}
}
@media screen and (max-width: 1023px) {
.elements {
/* @include mq(large, max, true) */
}
}
ネストと組み合わせて使用
上記はそれぞれmin-width
のみ または max-width
のみというものでしたが、以下のようにネストと組み合わせて使用することで、(min-width: 768px) and (max-width: 1023px)
のように組み合わせたMedia Queriesを出力させることが可能です。
単純にネストしたmixinの第2引数にmax
を指定するだけだとそのまま指定したmin-width
とmax-width
の値が出てしまうのですが、個人的にmax-width
の値は次のブレイクポイントの値を1減らして使用することが多いです。
なので、このようにネストして記述する場合にはmax-width
を出力させる方のmixinに、上で少し触れた第3引数としてtrue
を指定します。
このmixinの第3引数は減算するかどうかというのを選択するようになっており、デフォルトはfalse
なので何も起きませんが、true
にすることで指定したブレイクポイントの値から-1するようになっています。
usage
SCSS
.elements {
@include mq {
/* @include mq */
@include mq(large, max, true) {
/* @include mq in @include mq(large, max, true) */
}
}
}
output
CSS
@media screen and (min-width: 768px) {
.elements {
/* @include mq */
}
}
@media screen and (min-width: 768px) and (max-width: 1023px) {
.elements {
/* @include mq in @include mq(large, max, true) */
}
}
以上、mixinを使ってMedia Queries(メディアクエリ)を使いやすくするスニペットの紹介でした。
最近はほぼ最後に紹介したものを愛用していますが、今のところ特別困ることもなく、むしろ後で変更や追記なども楽で個人的には使いやすいです。
ただ、例えばメディアタイプも指定できるようにとかもうちょっと改善しようかなと思う部分もあるので、それはまた時間作っていろいろ試してみようと思います。
もし、このmixinを試しに使って何か不具合とかもっとこうした方が良いって部分あったら教えてもらえると嬉しいです。
また、ブレイクポイントの管理にマップを用いた方法については、下記を非常に参考にさせてもらいました。
ありがとうございます。