SASS(.scss)の機能を使うと、多様な画面幅に合わせたメディアクエリを簡単に一括で作成することができます。
プロジェクト間での使い回しもで、変数で指定しているブレイクポイント値(画面幅)を変更するだけで簡単に対応できます。
ここではSASS(.scss)を使ったメディアクエリの作成方法を実例で解説しています。
SASSでメディアクエリを使う手順
SASSでメディアクエリを使には以下の2つの手順を踏みます。
mixin, map-get, @contentや@includeなどあまり目にしない単語が並んでいますが、それぞれ使い方を実例で解説していきます。
もう知っているという方は読み飛ばしてください。
mixin
mixinとは何か?
SASSにはmixin(ミクシン)という機能が用意されています。
mixinとはコンポーネント(専用の名前をつけたパーツ)のことで、好きな場所で呼び出すことができます。
複数回使い回すプロパティや処理を設定する場合に使用します。
mixinの使い方
mixinを作成するときは以下のように記述します。
@mixin <mixin名> { 処理 }
mixinの呼び出し方
同じファイルの中か、@importを使う場合
mixinを定義してあるのと同じファイルの中でmixinを呼び出すか、そのファイルを@importで呼び出す場合は「@include」を使って使用したいmixin名を指定します。
@include <mixin名>
@useを使う場合
@useを使ってmixinが定義してあるファイルを読み込み、そのmixinを使用するためには、mixin名の前に名前空間を指定する必要があります。
@include <名前空間.mixin名>
mixinの実例
例えば、「caution」というmixinを作成して、下のhogeの処理の中で呼び出す場合は以下のようにします。
@mixin caution {
color: red;
font-size: 32px;
}
// mixinを呼び出す
.hoge {
@include caution;
font-weight: bold;
}
↓ cssにコンパイル。
.hoge {
color: red;
font-size: 32px;
font-weight: bold;
}
@includeのところに指定したmixinの内容が入っていることがわかります。
mixinで引数を使う方法
メディアクエリを作成するときはmixinで引数を渡す必要があるため、mixinで引数を使う方法を解説しておきます。
使い方
@mixinの後ろにmixin名を指定して、( )の中に引数を記述していきます。その際、初期値を指定できます。
引数の初期値は省略することもできます。
@mixin <mixin名>($引数名1: 初期値1, $引数名2: 初期値2,,, ) { 処理 }
注意点
引数の初期値を省略する場合は、mixinを呼び出すときにかならず各引数の値を渡さなければいけません。渡す引数の数が合わないと以下のようなエラーが発生します。
Compilation Error
Error: Missing argument $color.
引数を使ったmixinの呼び出し方
引数を使ったmixinの呼び出し方には以下の3つの方法があります。
引数を指定しない
引数を指定しないで呼び出すと、mixinを作成したときに使用した初期値が入ります。
@include mixin名
実例
// mixinを定義
@mixin test($color: red, $fsize: 32px) {
color: $color;
font-size: $fsize;
}
//引数指定なしで呼び出す(初期値を使う)
.hoge {
@include test;
font-weight: bold;
}
↓ CSSへのコンパイル結果
.hoge {
color: red;
font-size: 32px;
font-weight: bold;
}
引数の中でデフォルトとして指定したredと32pxが適用されていることがわかります。
引数でプロパティの値を渡す
引数でプロパティの値を指定することも可能です。
@include mixin名(値1, 値2,,,,)
実例
// mixinを定義
@mixin test($color: red, $fsize: 32px) {
color: $color;
font-size: $fsize;
}
//引数で値を指定して呼び出す
.hoge {
@include test(blue, 18px);
font-weight: bold;
}
↓ CSSへのコンパイル結果
.hoge {
color: blue;
font-size: 18px;
font-weight: bold;
}
@includeでmixinを呼び出したときに引数の中で指定したblueと18pxが適用されていることがわかります。
注意点:引数の順番が重要
引数で値を渡すときは、mixinを定義したときに指定した変数の順番で値を渡す必要があります。
例えば、以下のように、「@include test(18px, blue)」とすると、$colorに18px、$fsizeにblueが入ってしまいます。
// mixinを定義
@mixin test($color: red, $fsize: 32px) {
color: $color;
font-size: $fsize;
}
//引数で値を指定して呼び出す
.hoge {
@include test(18px, blue);
font-weight: bold;
}
↓ CSSへのコンパイル結果
.hoge {
color: 18px;
font-size: blue;
font-weight: bold;
}
引数で変数名と値を指定して渡す
mixinを@includeで呼び出すときに、常に同じファイルを使用するとは限りません。このためmixinで定義している変数の順番を覚えていない場合などがあります。
そういった場合に便利なのが、引数で変数名と値の両方を指定してmixinを呼び出す方法です。
@include mixin名($変数名1: 値1, $変数名2: 値2,,,,)
実例
// mixinを定義
@mixin test($color: red, $fsize: 32px) {
color: $color;
font-size: $fsize;
}
//引数を名前付きで指定する
.hoge {
@include test($fsize: 18px, $color: green);
font-weight: bold;
}
↓ CSSへのコンパイル結果
.hoge {
color: green;
font-size: 18px;
font-weight: bold;
}
@includeでmixinを呼び出したときに、mixinを定義している変数の順番とは異なる、順序で変数と値を渡していますが、指定した通りに受け渡しができています。
@contentの使い方
@mixinの中で使うディレクティブの一つに@contentがあります。
@contenはmixinを定義するときに処理の中に記述します。
すると、mixinを@includeで呼び出すときに、{ }で処理を記述すると、そこに記述した内容が@contentの部分入ります。
つまり、外からmixinの中にプロパティと値を渡すことができる機能です。
mixinを定義し@contentを記述する
@mixin mixin名(引数){
処理
@content
}
@includeでmixinを呼び出す
@include mixin名(引数){
処理
}
この呼び出し時の処理の内容が@contentに渡されます。
@contentの実例
// mixinを定義
@mixin test($color: yellow, $fsize: 32px) {
color: $color;
font-size: $fsize;
@content;
}
// mixinを呼び出す
.hoge {
@include test($color: blue, $fsize: 16px) {
max-height: 60%;
max-width: 60%;
background-color: gold
}
}
@includeでmixinを呼び出したときに{ }の中に記述した内容が、@contentの中に入ります。
↓ CSSにコンパイル
.hoge {
color: blue;
font-size: 16px;
max-height: 60%;
max-width: 60%;
background-color: gold;
}
@contentの部分に、呼び出したときに記述した処理が入っていることがわかります。
変数の使い方
SASSでは変数を定義することができます。
変数の作り方には値をどのように指定するかで、次の2種類の定義方法があります。
変数の値をオブジェクト形式(キー名: 値)で指定するときは、呼び出し時にmap-getメソッドを使用する必要があります。
値を指定する
変数の定義方法
$変数名として、その変数に代入する値をそのまま記述することができます。
$変数名: 値;
変数の呼び出し方
変数の呼び出しは値に「$変数名」をそのまま記述します。
プロパティ名: $変数名;
実例
以下のように変数「$theme-color」と「$original-size」を用意して、それぞれプロパティの値で呼び出します。
$theme-color: red;
$original-size: 16px;
.hoge {
color: $theme-color;
font-size: $original-size;
}
↓ CSSにコンパイル
.hoge {
color: red;
font-size: 16px;
}
指定した変数の値が入っていることがわかります。
オブジェクト形式で指定する(キー名: 値)
変数の値をオブジェクト形式で指定することもできます。
mixinなどの処理に引数を渡して、その引数の内容に応じて値を振り分ける場合は、変数をオブジェクト形式にします。
変数の定義方法
$変数名の値にオブジェクト(キー名: 値)を記述します。
$変数名: ( 'キー名1': 値1, 'キー名2': 値2,,,);
変数の呼び出し方
値をオブジェクト形式で記述した変数を呼び出すときはmap-getメソッドを使います。
map-get($変数名, キー名);
第1引数で変数名を指定し、第2引数で欲しい値を持つキー名を指定します。
実例
以下のように値に「default」「small」「large」というキー名を持つ変数「$fsizes」を用意して、map-getを使って欲しい値を呼び出します。
//値がオブジェクト形式の変数を定義する
$fsizes: ( 'default': 14px, 'small': 10px, 'large': 20px );
//オブジェクト形式の変数をキー名を指定して呼び出す
.headline {
font-size: map-get( $fsizes, large );
}
.detail {
font-size: map-get( $fsizes, small );
}
.contents {
font-size: map-get( $fsizes, default );
}
↓ CSSにコンパイル
.headline {
font-size: 20px;
}
.detail {
font-size: 10px;
}
.contents {
font-size: 14px;
}
map-getで指定した変数の中のキーの値が入っていることがわかります。
!defaultで変数を上書き可能にする
ファイルを@importや@use、@forwardで読み込む場合に、読み込み元の変数の値を上書きできるようにするには変数の後ろに「!default」を記述する必要があります。
!defaultの書き方
変数を値で定義している場合
$変数名: 値 !default;
変数をオブジェクト形式(キー名: 値)で定義している場合
変数をオブジェクト形式(キー名: 値)で定義している場合は( )の後ろに「!default」を記述します。
$変数名: ( キー名1: 値1, キー名2: 値2,,,, ) !default;
「!default」がないと変数の値を上書きできない
「!default」がないと元のファイルの変数の値が上書きされません。
特に、@useや@forwardを使っている場合は「!default」がない変数を上書きしようとすると、以下のようなエラーが発生します。
Compilation Error
Error: This variable was not declared with !default in the @used module.
「エラー:この変数は、@usedモジュールで!defaultで宣言されていません。」というように、変数の値を書き変えたいなら「!default」を使ってねというメッセージが表示されます。
変数を値以外で呼び出す方法
変数を値以外で呼び出す方法
変数をプロパティの値の中で使う場合は「$変数名
」と記載すればその値が入ります。
ですが、変数をプロパティ名など値以外の処理の中で呼び出したい場合は#{ }
を使う必要があります。
#{ 変数名 }
このため、プロパティ名や@media(メディアクエリ)の中で変数を呼び出したい場合は #{}を使う必要があります。
#{ }の実例
例えば、以下のように変数「$fsize」に値「font-size」、「$unit」に値「px」が入っているとします。
$fsize: font-size;
$unit: px;
これを、pタグの中で「font-size: 20px」として呼び出すためには、プロパティ名のところで#{ }を使用する必要があります。
$fsize: font-size;
$unit: px;
p{
#{$fsize}: 20 + $unit;
}
↓ CSSにコンパイル
p {
font-size: 20px;
}
#{ }がないと無視される
例えば、以下のように変数「$fsize」に値「font-size」、「$unit」に値「px」が入っているとします。
$fsize: font-size;
$unit: px;
これを、pタグの中で「font-size: 20px」として呼び出すときに、プロパティ名のところで#{ }を使用しないと、そのプロパティは無視されます。
$fsize: font-size;
$unit: px;
p{
$fsize: 20 + $unit;
color: red;
}
↓ CSSにコンパイル
p {
color: red;
}
「$fsize: 20 + $unit;」の記述が無視されています。
@mediaと#{ }
メディアクエリ@mediaを使って、変数の中にあるブレイクポイントの記述を呼び出す場合は #{ }が必要になります。
例えば、変数「$breakpoint」がsp, tablet, pcというキー名で以下のようなテキストを所持しているとします。
$breakpoint: (
'sp': 'screen and (min-width: 320px)',
'tablet': 'screen and (min-width: 600px)',
'pc': 'screen and (min-width: 1000px)',
);
これを@mediaクエリの中でmap-getを使って呼び出す場合は以下のようになります。
@media #{ map-get($breakpoint, sp) } {
p {
color: red;
}
}
↓ CSSにコンパイル
@media screen and (min-width: 320px) {
p {
color: red;
}
}
SASSを使ったメディアクエリ定義
以上でSASSを使ってメディアクエリを定義するために必要な機能が揃いました。
画面幅のサイズと変数の作成
ここでは、画面幅のサイズとして、以下の5つの変数を定義します。
size | 意味 |
---|---|
xs | eXtra Small |
sm | SMall |
md | MeDium |
lg | LarGe |
xl | eXtra Large |
それぞれに対応するブレイクポイントを変数名「$breakpoint」として、メディアクエリの内容を値に入れます。
//冒頭に使うサイズを明記しておくと、何を指定できるかがわかりやすい。
$sizes: xl, lg, md, sm, xs;
$breakpoint-up: (
'xs': 'screen and (min-width: 321px)',
'sm': 'screen and (min-width: 376px)',
'md': 'screen and (min-width: 501px)',
'lg': 'screen and (min-width: 961px)',
'xl': 'screen and (min-width: 1201px)',
) !default;
mixinの作成
「mq」という名前のmixinを作成します。(Media Queryの略)
引数に「$size」を入れ、デフォルト値を「md」としておきます。
その中でメディアクエリ(@media)を使う記述を書きます。メディアクエリの内容は変数「$breakpoint」の値をmap-getで取得して表示するようにします。
また、「@include」で呼び出されたときに、処理の内容がメディアクエリの中に入るように「@content」を記述しておきます。
//冒頭に使うサイズを明記するとわかりやすい
$sizes: xl, lg, md, sm, xs;
//ブレイクポイント
$breakpoint: (
'xs': 'screen and (min-width: 321px)',
'sm': 'screen and (min-width: 376px)',
'md': 'screen and (min-width: 501px)',
'lg': 'screen and (min-width: 961px)',
'xl': 'screen and (min-width: 1201px)',
) !default;
//mixinを定義(初期値はmd)
@mixin mq($size: md) {
@media #{ map-get( $breakpoint, $size ) } {
@content;
}
}
なおファイル名は「_mixin.scss」としています。
以上でSASSを使ったメディアクエリの作成は完成です。
メディアクエリの呼び出し
実際にメディアクエリを使うには以下のようにします。
@importや同じファイル内で呼び出す場合
@include mq('サイズ')
@useで呼び出す場合
@useで呼び出す場合は、mixinの前に名前空間を指定する必要があります。
@include 名前空間.mq('サイズ')
なお、引数は「$breakpoint」で定義した「xl, lg, md, sm, xs」のいずれかを渡します。
実例
例えば、.headlineというセレクタの処理で、ブレイクポイントの指定がないときは「color: red;」を適用し、画面幅が「xs」のときは「color: blue;」、画面幅が「lg」のときは「color: gold;」を適用する処理は以下のようになります。
@import(または同一ファイル内の場合)
@importを使って「_mixin.scss」を呼び出す(または同一ファイル内の場合)は以下のようになります。(※ファイルパスは適宜設定してください。以下は同一階層にある場合の例です)
@import 'mixin'
.headline{
color: red;
@include mq('xs'){
color: blue;
}
@include mq('lg'){
color: gold;
}
}
↓ CSSへのコンパイル
.headline {
color: red;
}
@media screen and (min-width: 321px) {
.headline {
color: blue;
}
}
@media screen and (min-width: 961px) {
.headline {
color: gold;
}
}
指定した、メディアクエリが正しく適用されていることがわかります。
@useを使う場合
@useを使って「_mixin.scss」を呼び出す場合は、mixinを呼び出すときにファイルの名前空間も指定する必要があります。(※ファイルパスは適宜設定してください。以下は同一階層にある場合の例です)
@use 'mixin';
.headline{
color: red;
@include mixin.mq('xs'){
color: blue;
}
@include mixin.mq('lg'){
color: gold;
}
}
↓ CSSへのコンパイル
.headline {
color: red;
}
@media screen and (min-width: 321px) {
.headline {
color: blue;
}
}
@media screen and (min-width: 961px) {
.headline {
color: gold;
}
}
指定した、メディアクエリが正しく適用されていることがわかります。
(応用編)メディアクエリの一括定義
上記の例では「min-width」(画面幅~以上)のみを指定しました。
ですが、プロジェクトやスタイルの指定によっては「max-width」(画面幅~以下)や画面幅~以上、~以下といった指定を行いたい場合もあります。
そういった場合は、以下のように「min-width」「max-width」およびその両方を値として持つ変数を定義すると便利です。
例えば以下のようにそれぞれの変数名を「$breakpoint-up」「$breakpoint-down」「$breakpoint-range」とします。
変数名 | 対象 |
---|---|
$breakpoint-up | min-width |
$breakpoint-down | max-width |
$breakpoint-range | min-width と max-width |
スタイルシートは以下のようなります。
$sizes: xl, lg, md, sm, xs;
// responsive
$breakpoint-up: (
'xs': 'screen and (min-width: 321px)',
'sm': 'screen and (min-width: 376px)',
'md': 'screen and (min-width: 501px)',
'lg': 'screen and (min-width: 961px)',
'xl': 'screen and (min-width: 1201px)',
) !default;
// max-width
$breakpoint-down: (
'xs': 'screen and (max-width: 320px)',
'sm': 'screen and (max-width: 375px)',
'md': 'screen and (max-width: 500px)',
'lg': 'screen and (max-width: 960px)',
'xl': 'screen and (max-width: 1200px)',
) !default;
$breakpoint-range: (
'xs': 'screen and (min-width: 0px) and (max-width: 320px)',
'sm': 'screen and (min-width: 321px) and (max-width: 375px)',
'md': 'screen and (min-width: 376px) and (max-width: 500px)',
'lg': 'screen and (min-width: 501px) and (max-width: 960px)',
'xl': 'screen and (min-width: 961px) and (max-width: 1200px)',
) !default;
// @mixinの定義
@mixin mq-up($size: md) {
@media #{map-get($breakpoint-up, $size)} {
@content;
}
}
@mixin mq-down($size: md) {
@media #{map-get($breakpoint-down, $size)} {
@content;
}
}
@mixin mq-range($size: md) {
@media #{map-get($breakpoint-range, $size)} {
@content;
}
}
呼び出し
呼び出すときは、@includeでmixin名を指定して呼び出します。
@import(または同一ファイル内の場合)
@include mq-up('サイズ'){ 処理 }
@include mq-down('サイズ'){ 処理 }
@include mq-range('サイズ'){ 処理 }
@useで呼び出す場合
@include 名前空間.mq-up('サイズ'){ 処理 }
@include 名前空間.mq-down('サイズ'){ 処理 }
@include 名前空間.mq-range('サイズ'){ 処理 }