メディアクエリの書く順番で困っていませんか?モバイルファーストとデスクトップファーストの実装戦略|現場で使える実践テクニック

C
クリオ
Web制作ディレクター / フロントエンジニア

こんにちは!
今日は「メディアクエリの書く順番で結果が変わる話」について解説します。

これ、めっちゃ大事なのに意外と見落とされてるんですよね。
特に後輩の人のコードレビューをすると、CSSが意図した通りに効いていない原因がこれだったりするんです。

僕が経験した「メディアクエリの罠」

昔、僕が駆け出しエンジニアだった頃の話なんです。
あるプロジェクトで、スマートフォン用のスタイルをPCのスタイルの後に書いてたんですよ。

その時のコードがこんな感じです:

/* PC用(先に書いた) */
.button {
  padding: 15px 30px;
  font-size: 16px;
}

/* スマートフォン用(後に書いた) */
@media (max-width: 768px) {
  .button {
    padding: 10px 15px;
    font-size: 14px;
  }
}

一見、大丈夫に見えますよね。
でも実装を進めていく中で、いろんなプロパティが競合し始めて、どれが効いてるのか分からなくなっちゃったんです。

先輩に相談したら、「クリオ、メディアクエリの書く順番を統一しよう」って言われました。
その時初めて気づいたんです。
メディアクエリの書き方には戦略があるんだって。

モバイルファーストの書き方とメリット

今は、ほとんどのプロジェクトでモバイルファースト戦略を使っています。
これは「スマートフォン用のスタイルを基本にして、大きい画面に向かって min-width で拡張していく」という考え方です。

実装パターンはこんな感じになります:

/* スマートフォン用(基本形) */
.button {
  padding: 10px 15px;
  font-size: 14px;
  display: block;
  width: 100%;
}

/* タブレット以上 */
@media (min-width: 769px) {
  .button {
    padding: 15px 30px;
    font-size: 16px;
    display: inline-block;
    width: auto;
  }
}

/* デスクトップ以上 */
@media (min-width: 1024px) {
  .button {
    padding: 18px 40px;
    font-size: 18px;
  }
}

このモバイルファーストのメリット、ほんま多いんですよ:

  • スタイルの優先順位が分かりやすい
    基本形から始まるから、どこまでが必須で何が追加装飾かが明確です。
  • CSSの継承がちゃんと機能する
    小さい画面のスタイルが基礎になるから、大きい画面では必要な分だけ上書きすればいいんです。
  • ファイルサイズが最適化される
    スマートフォンでは不要な大きい画面用のCSSが読み込まれないわけではないですが、構造が効率的になります。
  • 後で変更するときに変更漏れが少ない
    視覚的に流れが分かるから、「あ、ここも変わるんだ」って気づきやすいんです。

デスクトップファーストの書き方とよくあるハマりポイント

ただし、プロジェクトによってはデスクトップファーストで実装することもあります。
既存のサイトのリニューアルとか、デザイナーがPC中心に考えてるケースですね。

デスクトップファーストの場合は、max-width を使って「この幅以下では異なるスタイルを適用する」という書き方になります:

/* デスクトップ用(基本形) */
.button {
  padding: 18px 40px;
  font-size: 18px;
  display: inline-block;
  width: auto;
}

/* タブレット以下 */
@media (max-width: 1023px) {
  .button {
    padding: 15px 30px;
    font-size: 16px;
  }
}

/* スマートフォン以下 */
@media (max-width: 768px) {
  .button {
    padding: 10px 15px;
    font-size: 14px;
    display: block;
    width: 100%;
  }
}

ここで「よくある勘違い」があるんです。
デスクトップファーストの時に max-width の値を間違えると、めっちゃ困ったことになります。

例えば、@media (max-width: 768px)@media (max-width: 767px) の違いって、たった1pxなんですが、これがスマートフォンとタブレットの切り替わりポイントになっちゃうんですよ。
768pxのデバイスで、どちらが効くか効かないかが変わるんです。

僕が最初に失敗したのは、複数人でコードを書く時に、各メンバーが 768px769px767px みたいにバラバラのブレイクポイントを使ってたんです。
テスト時に「なぜか768pxでだけスタイルが崩れる」っていう謎の現象が起きました。

実装時に気をつけるべき3つのこと

1. チーム全体で「モバイルファースト」か「デスクトップファースト」かを決める

これをしないと、各エンジニアが好きな方で書いちゃうんですよ。
プロジェクトの開始時に、必ずドキュメントに書いておくといいですよ。

「このプロジェクトはモバイルファーストで実装します。ブレイクポイントは 769px1024px1440px とします」って明記しておくと、めっちゃ後々楽になります。

2. ブレイクポイントの値をCSS変数や定数で一元管理する

SCSSやCSS変数を使って、ブレイクポイントを定義しておくと良いですよ。
例えばこんな感じです:

/* _variables.scss */
$breakpoint-sm: 576px;
$breakpoint-md: 768px;
$breakpoint-lg: 1024px;
$breakpoint-xl: 1440px;

@mixin media-sm {
@media (min-width: $breakpoint-sm) {
@content;
}
}

@mixin media-md {
@media (min-width: $breakpoint-md) {
@content;
}
}

/* 使用例 */
.button {
padding: 10px