知ってた?JavaScriptでメディアクエリを利用するちょっとしたテクニック

2017/08/30

Craig Buckler

168

Articles in this issue reproduced from SitePoint
Copyright © 2017, All rights reserved. SitePoint Pty Ltd. www.sitepoint.com. Translation copyright © 2017, KADOKAWA ASCII Research Laboratories, Inc. Japanese syndication rights arranged with SitePoint Pty Ltd, Collingwood, Victoria,Australia through Tuttle-Mori Agency, Inc., Tokyo

Web制作ですっかり定番となったメディアクエリを使ったレスポンシブ Webデザイン。JavaScriptで実装している機能をメディアクエリと連携させるためのちょっとしたテクニックを紹介します。

テーブルタグがCSSに変わり、レスポンシブデザインは心躍るコンセプトの1つです。レスポンシブデザインはメディアクエリで閲覧中の機器の画面幅、高さ、向き、解像度、アスペクト比、色深度などを把握し、応じたスタイルシートを適用しています。

以下の例はcssbasic.cssをすべてのデバイスに適用して、水平方向の画面幅が500ピクセル以上なら、csswide.cssも適応します。

<link rel="stylesheet" media="all" href="cssbasic.css" />
<link rel="stylesheet" media="(min-width: 500px)" href="csswide.css" />

インターネット上の多くのWebサイトがメディアクエリを活用しています。ブラウザーの幅を変えれば、Webページのレイアウトも変化します。

メディアクエリで、CSSによるデザイン分岐や要素のサイズ変更が容易になりましたが、小さな画面の場合だけ短いヘッドラインを表示したり、JavaScriptライブラリーの利用を減らしたり、ウィジェットの動作を変更したり、コンテンツや機能を変更したりするにはどうすれば良いでしょう?

JavaScriptでviewportサイズを調べるのは少し手間です。

  • 大半のブラウザーはwindow.innerWidthwindow.innerHeightに対応している
  • しかしIE6、7、8、9の互換モードでは、document.body.clientWidthおよびdocument.body.clientHeightの記述が必要
  • window.onresize
  • 主要ブラウザーはdocument.documentElement.clientWidthおよびdocument.documentElement.clientHeightに対応しているが、一貫しない。ブラウザーやモードにより、ウィンドウ幅が返ってきたりドキュメントサイズが返ってきたりする

うまくviewportのサイズ変更を検知しても、向きや縦横比などを計算しなければなりません。さらにCSSのメディアクエリのルールを適用したとき、計算が想定した通りに反映される保証はありません。

JavaScriptにおけるメディアクエリの書き方

JavaScriptでCSS3メディアクエリのステート変化に対応できます。鍵になるAPIはwindow.matchMediaです。CSSメディアクエリと同じ「メディアクエリ文字列」が渡されます。

const mq = window.matchMedia( "(min-width: 500px)" );

matchesプロパティは問い合わせの結果に応じてtrueもしくはfalseを返します。

if (mq.matches) {
  // window width is at least 500px
} else {
  // window width is less than 500px
}

変更を検知したときに実行するイベントリスナーを追加できます。

// media query event handler
if (matchMedia) {
  const mq = window.matchMedia("(min-width: 500px)");
  mq.addListener(WidthChange);
  WidthChange(mq);
}

// media query change
function WidthChange(mq) {
  if (mq.matches) {
    // window width is at least 500px
  } else {
    // window width is less than 500px
  }

}

イベント定義後にイベントハンドラを直接呼ぶため、ページが読み込まれる間もしくは読み込み後にコードを初期化します。ユーザーがブラウザーの大きさを変更しない限りWidthChange()は呼ばれません。

執筆時点ではmatchMediaは主要ブラウザーの多くで対応しています。本番サイトで使わない手はありません。

以下のデモでブラウザーのサイズを変えるか、サンプルコードをダウンロードして、横幅が500ピクセル以上の場合とそれより小さい場合とで文字の表示が変化するのを確かめてください。

※2011年10月12日に公開した記事を更新しました。変更点は最新情報の追加、冒頭画像の追加、CodePenデモです。

(原文:How to use Media Queries in JavaScript

[翻訳:西尾 健史/編集:Livit

Copyright © 2017, Craig Buckler All Rights Reserved.

Craig Buckler

Craig Buckler

イギリス人のWebコンサルタントで、1995年にIE2.0向けにはじめてのWebサイトを製作。それ以降、Webの標準化とアクセシビリティ向上、HTML5の優れた事例を紹介・提唱してきました。SitePointでは1,000以上の記事を書いています。Twitterのアカウントは@craigbuckler

Loading...