In 'n' Out

知識を取り込み、そして発信する

メディアクエリ

メディアクエリとは

Webページをさまざまな画面サイズで見たとき、デザインやレイアウトが崩れないように調整する仕組みがメディアクエリです。
CSSに条件を指定することで、スマホ・タブレット・PCなどの表示幅に応じてスタイルを切り替えられます。
メディアクエリはレスポンシブデザインの中核的な技術であり、画面幅や解像度、向きなどを条件にCSSを適用できます。

メディアクエリの基本

画面幅や条件に応じてCSSを切り替える構文です。
条件を指定して適用スタイルを制御できます。
ここでは、メディアクエリをCSSでどのように記述するかを見ていきます。

基本構文

@media(条件){
    セレクタ{
        プロパティ:値;
    }
}

条件の部分に幅や高さを指定することで、対象の画面サイズに応じたスタイルを適用できます。

条件:min-width

構文

@media(min-width:幅){
    セレクタ{
        プロパティ:値;
    }
}

min-widthで指定した幅よりも画面幅が大きい場合に、{}(ブレース)内のセレクタにスタイルを適用します。

条件:min-width+max-width

構文

@media(min-width:幅) and (max-width:幅){
    セレクタ{
        プロパティ:値;
    }
}

min-widthで指定した幅よりも画面幅が大きく、かつmax-widthで指定した幅よりも画面幅が小さい場合に、{}(ブレース)内のセレクタにスタイルを適用します。

コード例

@media(min-width: 769px) and (max-width: 1280px) {
    body{
        background-color: #ff0000;
        color: #ff0000;
    }
}
        
@media(max-width: 768px){
    body{
        background-color: #0000ff;
        color: #ffff00;
    }
}

出力・動作例

デフォルトは白背景に黒い文字で表示されます。
1つ目の条件である(min-width: 769px) and (max-width: 1280px)は、最小サイズが幅769px、最大サイズが幅1280pxという条件になります。
つまり、769px以上1280px以下では赤背景に白文字になります。
2つ目の条件である(max-width: 768px)は、最大サイズが幅768pxという条件、つまり768px以下では青背景に黄色文字になります。

link要素によるCSS切り替え

レスポンシブ対応では、画面幅や条件に応じてCSSを切り替える必要があります。
その方法は@mediaだけではなく、HTML側で読み込むCSSファイル自体を切り替える方法も存在します。
HTMLではlink要素を使って外部CSSファイルを読み込みますが、link要素にmedia属性を指定することで、条件に応じてCSSを適用できます。

基本構文

<link rel="stylesheet" href="任意のcss1">
<link rel="stylesheet" href="任意のcss2" media="条件">

link要素はHTMLの読み込み時に評価され、media属性の条件を満たした場合のみCSSが適用されます。
条件を満たさない場合、CSSファイル自体は読み込まれますが、スタイルは適用されません。
先の記事で取り扱ったCSSのコード例を下記に記述します。

コード例

<link rel="stylesheet" href="pc.css">
<link rel="stylesheet" href="tablet.css" media="(min-width:769px) and (max-width:1280px)"">
<link rel="stylesheet" href="sp.css" media="(max-width:768px)">
/*pc.css*/
body{
    /*デフォルトなので指定なし*/
}

/*tablet.css*/
body{
    background-color: #ff0000;
    color: #ff0000;
}

/*sp.css*/
body{
    background-color: #0000ff;
    color: #ffff00;
}

media属性には@mediaと同じ条件式を指定できます。
挙動は先ほどの@mediaと同じで幅が1280pxになるとpc.cssからtablet.cssが適用され、幅が768pxになるとtablet.cssからsp.cssにCSSが切り替わります。
この方法ではCSSファイルを役割ごとに分離できるため、記述量が多い場合でも管理しやすくなります。
一方で、CSSが複数ファイルに分かれるため、全体像を把握しにくくなることがあります。
同じセレクタが複数のCSSファイルに存在する場合、条件が重なった状態では後から読み込まれたCSSが優先されます。
そのため、共通スタイルと画面別スタイルの責務を明確に分けることが重要です。

レスポンシブの考え方

@mediaとlink要素によるCSS切り替えは、どちらもレスポンシブ対応の方法です。
ここでは、それぞれをどう使い分けるかという設計上の考え方をまとめます。
CSSの切り替え方には、大きく分けて2つの考え方があります。

CSS切り替えの考え方

まずは@mediaで切り替える考え方。
1つのCSSファイルの中で条件を指定し、必要な部分だけスタイルを切り替えます。
差分だけを書けるため、CSS量が少ない場合や構造が単純な場合に向いています。

次にCSSファイルを分けて切り替える考え方。
画面サイズや役割ごとにCSSファイルを分離し、必要なものだけを読み込みます。
管理単位が明確になり、規模が大きい場合や長期運用に向いています。

どちらが正しいか

この2つは優劣の関係ではありません。
どこまで管理しやすいかで選ぶものです。
CSSが少ない段階では@mediaで十分ですが、CSSが増えてくると、1ファイルにまとめること自体が負担になります。

設計判断の目安

CSSが少ない場合は@mediaで対応できます。
CSSが増えてきた場合は、ファイルを分けた方が管理しやすくなります。
チーム制作や長期運用では、CSSを分ける設計が有効です。

レスポンシブ対応で大切なこと

レスポンシブとは、単に画面サイズに対応することではありません。
後から変更しやすい構造を作ることが本質です。
@mediaを使うか、CSSを分けるか、どちらを選ぶかは今の規模とこれからの運用を見て判断します。

metaタグのviewport

metaタグのviewportは、スマートフォンやタブレットでWebページを表示する際に、ブラウザがどの幅を基準にレイアウトを計算するかを指定するための設定です。
レスポンシブ対応では、この設定が入っていることが前提になります。

構文

<meta name="viewport" content="width=device-width, initial-scale=1.0">

width=device-widthは、ビューポートの幅を端末の画面幅に合わせる指定です。
これにより、スマートフォンでは端末の横幅を基準としてレイアウトが計算されます。
initial-scale=1.0は、初期表示時の拡大率を指定します。
等倍表示を意味し、意図しない拡大や縮小を防ぎます。
この2つを指定することで、画面幅とCSSの指定が直感的に対応するようになります。

コード例

<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>

metaタグのviewportは、必ずhead要素の中に記述する必要があります。
これは、ブラウザがページのレイアウトを計算する段階で参照される情報だからです。
HTMLは、上から順に読み込まれます。
metaタグのviewportがbody要素内に記述されていたり、head要素の後半に置かれていると、、ブラウザは正しい画面幅の情報を取得できません。
その結果、CSSやメディアクエリが想定とは異なる条件で評価され、レイアウトが崩れる原因になります。

特にスマートフォンでは、viewportの設定が反映されるタイミングが重要です。
head内で最初に近い位置にviewportを指定しておくことで、ページ全体が正しい画面幅を基準に描画されます。
なお、metaタグのviewportはページごとに1つだけ指定します。
複数記述した場合、どの設定が有効になるかは保証されず、ブラウザごとに挙動が異なる可能性があります。
このように、metaタグのviewportは記述内容だけでなく、記述する場所も含めて正しく設定することが、レスポンシブ対応の前提条件となります。