12周年記念パーティ開催! 2024/5/10(金) 19:00

半歩先のメディアクエリを押さえる 第1回 仕様の概要と表記

レスポンシブなWebサイトに使われ、普段触れることの多いと思われるメディアクエリは、現在も新しいバージョンが策定されています。今回はまず、全体的な仕様、メディアタイプ、メディア特性を押さえます。

発行

著者 坂巻 翔大郎 フロントエンド・エンジニア
半歩先のメディアクエリを押さえる シリーズの記事一覧

はじめに

Media Queries(以降、メディアクエリ)を使用すれば、コンテンツを各デバイスの画面幅や向きなどに応じて表示を変えることができます。レスポンシブなデザインのサイトに使用されることも多く、普段の業務で触れる人も多いでしょう。

勧告済みのもっとも新しい仕様はMedia Queries Level 3*で、現在も次期バージョン(Media Queries Level 4、Level 5)が策定されています。ブラウザへの実装も徐々に始まっています。利用頻度の高い仕様ですので、仕様の全体像をとらえ、将来的にどういった仕様が実装される予定なのか把握しておくことは重要です。

*注:Media Queries Level 3

仕様書のタイトルは「Media Queries」で、Level 3であることは明記されていません。しかしながら、編集者草案ではLevel 3と明記されていました。仕様書の進捗をわかりやすくするために、便宜的に上記のような表記にしています。

メディアクエリとは

まずは、ざっとメディアクエリのおさらいをしておきましょう。

メディアクエリは、2つの要素から構成されます。

  1. 表示媒体(コンピュータースクリーン・スマートフォン・紙など)の種類であるメディアタイプ
  2. 表示媒体の画面幅や向きなどのメディア特性を使用し、CSSの適用される範囲を制御する一つ以上の式(評価結果は真偽値)

メディアタイプに一致し、かつメディアクエリに含まれる式のすべてが真であるときに、メディアクエリの結果が真となり、対応するスタイルが適用されます。たとえば、ある画面幅にスタイルが適用されるメディアクエリは次のように記述できます。

/* 300px以上、700px以下に適用される */
@media screen and (min-width: 300px) and (max-width: 700px) {
  body { background-color: tomato; }
}

ここでは、表示先のスクリーンが300px以上かつ700px以下であるときに、スタイルが適用されます。

HTMLやJavaScriptでも使える

また、スタイルシート内だけでなく、HTMLのlinkstylesource要素でもmedia属性を使用して、メディアクエリを指定できます。

<!-- 700px以下であればスタイルシートが適用される -->
<link rel="stylesheet" media="(max-width: 700px)" href="700width.css">
<!-- 印刷媒体であればスタイルシートが適用される -->
<link rel="stylesheet" media="print" href="print.css">

<!-- 700px以下であればスタイルルールが適用される -->
<style media="(max-width: 700px)">
  body { background-color: tomato; }
</style>

<!-- 700px以下であればsample-small.pngが適用される -->
<picture>
  <source srcset="sample-small.png" media="(max-width: 700px)">
  <img src="sample.png" alt="サンプル画像">
</picture>

link要素などは馴染みのあるものかもしれません。picture要素*の子要素としてのsource要素はmedia属性をもつことができます。

picture要素

picture要素についてはちょっとお先にHTML 5.1 第3回 picture要素 1で解説しています。

さらに、JavaScriptからメディアクエリを扱うインターフェース*が用意されています。

JavaScriptのインターフェース

JavaScriptのインターフェースに関しては、賢いMedia Queries管理 第2回 MediaQueryListとwindow.matchMediaで解説しています。

const mql = window.matchMedia("(max-width: 700px)");
if (mql.matches) {
  console.log('700px以下');
}

CSS・HTML・JSといったさまざまな部分でメディアクエリを利用することができます。本記事では、そのメディアクエリの理解を深めるために、メディアタイプやメディア特性、andなどのキーワードについて解説していきます。

メディアタイプ

メディアタイプは、表示媒体の種類です。たとえば、プリンターや印刷プレビューであったり、スクリーンリーダーなどが挙げられます。

Media Queries Level 4以降では、いくつかのメディアタイプが非推奨*となりました。

*注:非推奨になったメディアタイプ

ttytvprojectionhandheldbrailleembossedauralはMedia Queries Level 4から非推奨となります。非推奨のメディアタイプを使用した場合、有効なメディアタイプと認識しますが、何にも合致しないものとして扱われるようになります。

Level 4で定義されているメディアタイプは次の4種類です。以前よりシンプルになりましたね。

メディアタイプ 意味
all すべてに合致する
print プリンタや、ブラウザの印刷プレビューに合致する
screen printにもspeechにも合致しないものすべてに合致する。
speech スクリーンリーダーなどの読み上げるものに合致する

各メディアタイプを使用すれば、それぞれの条件に合致する場合のみ、特定のスタイルを適用することができます。たとえば、link要素で印刷時だけ適用されるスタイルシート(print.css)を指定するには、次のようにmedia="print"と指定します。

<link rel="stylesheet" media="print" href="print.css">

注意したいのは、このprint.cssの中で@media print { }を使用するのは冗長な点です。使用してもスタイルは適用されますが、すでにprint.css自体が印刷時にのみ適用されるため、ただ冗長な記述となってしまいます。

メディア特性

メディア特性は、ブラウザや表示するデバイスがもつ特定の機能を意味します。

記述形式

メディア特性には3種類の記述形式があります。

記述形式 記述例 記述例の意味
mf-plain @media (orientation: portrait) 表示媒体の向きが縦であるかを判別する
mf-boolean @media (hover) ホバーが可能であるかを判別する
mf-range @media (width <= 100px) 表示媒体の幅が100px以下であるかを判別する

1つ目のmf-plainは、特性名に対する特性値を記述します。2つ目のmf-booleanは、特性名のみを記述します。そして、mf-rangeはLevel 4から導入された範囲を示す記述形式です。(400px <= width <= 700px)といった比較演算子を用いた記述が可能になります。ただし、執筆現在(2017年10月上旬)では、mf-rangeに対応したブラウザはありません。

メディア特性の記述について

メディア特性の記述は、いくつか覚えておかなければならないことがあります。

メディア特性には型がある

メディア特性には2つの型があります。離散型と範囲型です。

離散型は、orientation:portraitのように特定の値を取るものか、あるいは、grid:0grid:1のように真偽値を取るものを指します。

範囲型は、(min-width: 300px)のように大小を比較できるものを指します。範囲を示す形式はLevel 4以前のmin-/max-接頭辞を用いた(min-width: 100px)という形式と、Level 4以降のmf-rangeにある(width >= 100px)という形式があります。

メディア特性は丸括弧で括る

メディア特性は常に丸括弧で(orientation:portrait)のように括られます。1つの()の中には1つのメディア特性しか入りません。

メディア特性は値を省略できる

前述の表のmf-booleanにあるように、特性値は省略が可能です。

/* ホバーが可能な媒体に適用 */
@media (hover: hover) { }
@media (hover) { }

このようにコロンと特性値を省略してメディア特性名のみにすることができます。値を省略した場合は真偽での判断となります。

notand,などのキーワードと組み合わせる

メディア特性の前にnotキーワードを前置すれば、否定形にすることができます。

/* ホバーが可能ではない媒体に適用 */
@media not (hover) { }

複数のメディア特性を組み合わせる場合は、特性と特性をキーワードで繋げます。すべての式が真であるときに、メディアクエリが真となる場合は、次のようにandを用います。

/* 縦長でありホバーが可能な媒体に適用 */
@media (orientation:portrait) and (hover) { }

また、どれかの式が真であるときに、メディアクエリが真となる場合は、,を用います。

/* 縦長または、ホバーが可能な媒体に適用 */
@media (orientation: portrait), (hover) { }

これらのキーワードについては、次回以降であらためて取り上げます。

不正な記述はnot allに置き換えられる

次の3つのメディアクエリは、それぞれ不正な記述を含んでいます。

/* A */ @media (hover, pointer), print { }
/* B */ @media (max-weight: 3kg), (hover) { }
/* C */ @media (min-orientation: portrait) { }

Aのメディアクエリは1つの()の中に複数のメディア特性が入っている部分が不正な記述になります。Bのメディアクエリは、max-weight: 3kgという未知のメディア特性と値がある部分が不正な記述です。Cのメディアクエリは、orientationmin-接頭辞をつけることができないため不正となります。

これらの不正となった部分はすべてnot allに置き換えられ、次のように扱われます。

/* A */ @media not all, print { /* 印刷媒体に適用 */ }
/* B */ @media not all, (hover) { /* ホバーが可能な媒体に適用 */ }
/* C */ @media not all { /* 何にも適用されない */ }

また、@media (hover, speech { }のように、括弧を閉じなかった場合、閉じ括弧が見つかるまでのスタイルシートがnot allに置換されます。

まとめ

今回はメディアクエリの仕様のうち、メディアタイプ、メディア特性がどういったものであるか解説をしました。次回以降では、メディア特性をカテゴリに分けて紹介します。