レスポンシブ ウェブ デザインの基本

ユーザーが閲覧するデバイスのニーズと機能に対応できるサイトの作成方法

モバイル デバイスを使用したウェブ ブラウジングは、天文学的なペースで増え続けています。こうしたデバイスはディスプレイ サイズに制約があることが多く、画面上でのコンテンツの配置方法について異なるアプローチが必要になります。

元々 Ethan Marcotte in A List Apart によって定義されたレスポンシブ ウェブ デザインは、ユーザーのニーズとユーザーが使用しているデバイスに対応します。レイアウトはデバイスのサイズと機能に応じて変わります。たとえば、スマートフォンではコンテンツが 1 列で表示されますが、タブレットでは同じコンテンツが 2 列で表示されます。

この動画では、利用可能な画面のスペースに合わせて、デザインが狭いビューポートから広いビューポートへと変化しています。

スマートフォン、ファブレット、タブレット、パソコン、ゲーム機、テレビ、さらにはウェアラブルまで、さまざまな画面サイズが存在します。画面サイズは常に変化しているため、現在だけでなく将来も、あらゆる画面サイズにサイトが適応できるようにすることが重要です。さらに、デバイスには、私たちが操作するさまざまな機能があります。たとえば、訪問者の中にはタッチスクリーンを使用する人もいます。最新のレスポンシブ デザインでは、これらすべての要素を考慮して、すべてのユーザーにとってエクスペリエンスを最適化しています。

ビューポートを設定する

さまざまなデバイス向けに最適化されたページでは、ドキュメントのヘッダーにビューポートのメタタグを含める必要があります。meta ビューポート タグを使用すると、ページのサイズとスケーリングの制御方法をブラウザに指示できます。

最適なエクスペリエンスを提供するため、モバイル ブラウザはパソコン画面の幅(通常は約 980px)でページをレンダリングします。次に、フォントサイズを大きくし、画面に合わせてコンテンツを拡大することで、コンテンツの見栄えを良くします。つまり、ユーザーはフォントサイズに一貫性がないように見え、コンテンツを表示して操作するためにダブルタップやピンチ操作によるズームが必要になることがあります。

<!DOCTYPE html>
<html lang="en">
  <head>
    …
    <meta name="viewport" content="width=device-width, initial-scale=1">
    …
  </head>
  …

メタ ビューポート値 width=device-width を使用すると、画面の幅をデバイス非依存ピクセルで合わせるようにページに指示します。デバイス(または密度)に依存しないピクセルとは、単一のピクセルの表現であり、高密度画面では多くの物理ピクセルで構成される場合があります。これにより、小型のスマートフォンと大型のデスクトップ モニターのどちらで表示しても、さまざまな画面サイズに合わせてページのコンテンツをリフローできます。

非常にズームアウトしてテキストが読みにくいページのスクリーンショット。
ビューポート メタタグのないデバイスでページがどのように読み込まれるかを示す例。Glitch での例をご覧ください
同じページのスクリーンショットに、読みやすいサイズのテキストが表示されています。
ビューポート メタタグのあるデバイスでページが読み込まれる方法の例。Glitch での例をご覧ください

一部のブラウザでは、横向きに回転してもページの幅は一定に保たれ、リフローではなくズームによって画面全体に表示されます。値 initial-scale=1 を追加すると、デバイスの向きに関係なく、CSS ピクセルとデバイス非依存ピクセルを 1 対 1 の関係で確立するようにブラウザが指示され、ページで横向きの幅全体を活用できるようになります。

Lighthouse の監査項目では、width または initial-scale<meta name="viewport"> タグが設定されていない場合、HTML ドキュメントでビューポート メタタグが正しく使用されているかどうかを確認するプロセスを自動化できます。

アクセス可能なビューポートを確保する

initial-scale の設定に加えて、ビューポートには次の属性も設定できます。

  • minimum-scale
  • maximum-scale
  • user-scalable

これらが設定されている場合、ユーザーがビューポートをズームできなくなり、ユーザー補助の問題が発生する可能性があります。そのため、これらの属性の使用はおすすめしません。

コンテンツのサイズをビューポートに合わせる

パソコンとモバイル デバイスのどちらでも、ユーザーはウェブサイトを垂直方向にスクロールすることに慣れていますが、水平方向にはスクロールしません。ページ全体を表示するためにユーザーが水平方向にスクロールしたりズームアウトしたりしなければならないと、ユーザー エクスペリエンスが低下します。

メタ ビューポート タグを使用してモバイルサイトを開発する際、指定したビューポートに収まらないページ コンテンツを誤って作成してしまうことがよくあります。たとえば、画像がビューポートよりも広い幅で表示されると、ビューポートが水平方向にスクロールすることがあります。ユーザーが水平方向にスクロールしなくても済むように、このコンテンツはビューポートの幅に収まるように調整する必要があります。

Lighthouse の監査は、コンテンツのサイズがビューポートに合わない場合に役立ちます。オーバーフローするコンテンツを検出するプロセスを自動化できます。

画像

画像のサイズは固定されており、そのサイズがビューポートよりも大きい場合はスクロールバーが表示されます。この問題に対処するには、すべてのイメージに 100%max-width を設定するのが一般的な方法です。これにより、ビューポート サイズが画像よりも小さい場合、画像がスペースに合わせて縮小されます。ただし、width ではなく max-width100% であるため、画像が元のサイズより大きく引き伸ばされることはありません。通常は、画像でスクロールバーの表示に問題が生じないように、スタイルシートに以下を追加しても安全です。

img {
  max-width: 100%;
  display: block;
}

画像のサイズを img 要素に追加する

max-width: 100% を使用するときは、画像の実際のサイズをオーバーライドしますが、<img> タグに width 属性と height 属性を使用する必要があります。最近のブラウザでは、この情報を使用して画像の読み込み前のスペースを確保し、コンテンツの読み込み時のレイアウト シフトを回避できます。

レイアウト

画面サイズと CSS ピクセルの幅はデバイスによって大きく異なるため(スマートフォンとタブレット、さらにスマートフォン間でも)、コンテンツを適切にレンダリングするために特定のビューポートの幅に依存しないようにしてください。

これまでは、この必須設定要素を使用してレイアウトをパーセンテージで作成していました。以下の例では、ピクセルを使用してサイズ調整されたフローティング要素を含む 2 列のレイアウトを示しています。 ビューポートが列の幅の合計より小さくなったら、コンテンツを表示するために水平方向にスクロールする必要があります。

2 番目の列の大部分がビューポートの外側にある 2 列レイアウトのスクリーンショット
ピクセルを使用したフローティング レイアウト。Glitch での例をご覧ください

幅にパーセンテージを使用することで、列は常にコンテナの特定のパーセンテージに維持されます。つまり、スクロールバーが作成されるのではなく、列の幅が狭くなります。

Flexbox、グリッド レイアウト、マルチコルなどの最新の CSS レイアウト手法を使用すると、これらの柔軟なグリッドを簡単に作成できます。

Flexbox

このレイアウト方法は、サイズの異なるアイテムのセットがあり、それらを 1 行または 1 行に無理なく収めたい場合に最適です。小さいアイテムはスペースが小さく、大きいアイテムはスペースが広くなります。

.items {
  display: flex;
  justify-content: space-between;
}

レスポンシブ デザインでは、Flexbox を使用してアイテムを 1 行として表示したり、使用可能なスペースが減って複数の行にラップしたりできます。

Flexbox の詳細をご確認ください

CSS グリッド レイアウト

CSS グリッド レイアウトを使用すると、柔軟なグリッドを簡単に作成できます。 前述のフローティングの例では、割合で列を作成するのではなく、グリッド レイアウトと、コンテナ内の利用可能なスペースの一部を表す fr ユニットを使用できます。

.container {
  display: grid;
  grid-template-columns: 1fr 3fr;
}

グリッドは、適切な数だけアイテムを配置した通常のグリッド レイアウトの作成にも使用できます。画面サイズが小さくなると、利用可能なトラックの数は少なくなります。 以下のデモでは、各行に収まる数のカードを使用しています。最小サイズは 200px です。

CSS グリッド レイアウトの詳細

複数列レイアウト

レイアウトのタイプによっては、複数列レイアウト(マルチ列)を使用できます。column-width プロパティを使用すると、レスポンシブな列数を作成できます。以下のデモでは、別の 200px 列用のスペースがあれば、列が追加されています。

Multicol の詳細

CSS メディアクエリを使用して応答性を高める

特定の画面サイズに対応するために、上記の手法では可能な範囲を超えてレイアウトを大幅に変更しなければならない場合があります。ここで役に立つのがメディアクエリです。

メディアクエリは、CSS スタイルに適用できるシンプルなフィルタです。コンテンツをレンダリングするデバイスの種類や、デバイスの機能(幅、高さ、向き、ホバー機能、デバイスがタッチスクリーンとして使用されているかどうかなど)に基づいて、スタイルを簡単に変更できます。

印刷にさまざまなスタイルを設定するには、次のように出力の「タイプ」を指定して、印刷スタイルにスタイルシートを含める必要があります。

<!DOCTYPE html>
<html lang="en">
  <head>
    …
    <link rel="stylesheet" href="print.css" media="print">
    …
  </head>
  …

または、メディアクエリを使用してメインのスタイルシートに印刷スタイルを含めることもできます。

@media print {
  /* print styles go here */
}

レスポンシブ ウェブ デザインでは、通常、小さい画面用に別のレイアウトを提供するために、または訪問者がタッチスクリーンを使用していることを検出すると、デバイスの機能をクエリします。

ビューポートのサイズに基づくメディアクエリ

メディアクエリを使用すると、小さな画面から大画面まで、またどのような画面にも特定のスタイルを適用できるレスポンシブなエクスペリエンスを実現できます。したがって、ここで検出している機能は画面サイズであるため、次のことをテストできます。

  • widthmin-widthmax-width
  • heightmin-heightmax-height
  • orientation
  • aspect-ratio

これらの機能はすべてブラウザ サポートに優れています。ブラウザ サポート情報などの詳細については、MDN の高さ向きアスペクト比をご覧ください。

デバイスの機能に基づくメディアクエリ

利用可能なデバイスの範囲を考えると、すべての大型デバイスが通常のデスクトップ パソコンやノートパソコンである、または小型のデバイスでタッチスクリーンしか使用していないと仮定することはできません。メディアクエリの仕様に新たに追加されたいくつかの機能では、デバイスの操作に使用されるポインタのタイプや、ユーザーが要素にカーソルを合わせられるかどうかなどの機能をテストできます。

  • hover
  • pointer
  • any-hover
  • any-pointer

通常のデスクトップ パソコン、スマートフォンやタブレットなど、さまざまなデバイスでこのデモを表示してみてください。

これらの新機能は、すべての最新ブラウザで適切にサポートされています。hover任意のマウスオーバーポインタ任意のポインタの MDN ページをご覧ください。

any-hoverany-pointer の使用

any-hover 機能と any-pointer 機能は、ユーザーがホバーできるかどうか、またはデバイスの主要な操作方法でない場合でも、そのタイプのポインタを使用できるかどうかをテストします。これらを使用するときは特に注意してください。 タッチスクリーンを使用しているときにマウスに切り替わらせるのは、あまり便利ではありません。 ただし、ユーザーが所有するデバイスの種類を把握する必要がある場合は、any-hoverany-pointer が役立つ場合があります。たとえば、タッチスクリーンとトラックパッドを備えたノートパソコンは、ホバー機能に加えて、粗いポインタと細かなポインタにも適合する必要があります。

ブレークポイントを選択する方法

デバイスクラスに基づいてブレークポイントを定義しないでください。現在使用されている特定のデバイス、製品、ブランド名、オペレーティング システムに基づいてブレークポイントを定義すると、メンテナンスが悪夢となる可能性があります。コンテナに合わせてレイアウトをどのように調整するかは、コンテンツ自体で決定する必要があります。

小さなブレークポイントから始めて、徐々にメジャー ブレークポイントを設定する

まず小さな画面サイズに合うようにコンテンツをデザインしてから、ブレークポイントが必要になるまで画面を拡大します。これにより、コンテンツに基づいてブレークポイントを最適化し、最小限のブレークポイント数を維持できます。

最初に見た例の天気予報を見てみましょう。まず、小さな画面で見栄えが良くなるように予測を行います。

モバイル幅の天気アプリのスクリーンショット
幅の狭いアプリ。

次に、要素間の空白が過剰になり、天気予報の見た目が悪くなるまで、ブラウザのサイズを変更します。やや主観的な判断ですが、600px より大きすぎることは明らかです。

アイテム間が大きく隙間がある天気アプリのスクリーンショット
デザインを調整する必要があると感じた時点のアプリ。

600px にブレークポイントを挿入するには、コンポーネントの CSS の最後に 2 つのメディアクエリを作成します。1 つはブラウザが 600px 以下の場合、もう 1 つはブラウザの幅が 600px より広い場合に使用するクエリです。

@media (max-width: 600px) {

}

@media (min-width: 601px) {

}

最後に、CSS をリファクタリングします。max-width600px のメディアクエリ内に、小さい画面専用の CSS を追加します。min-width601px のメディアクエリ内に、大画面用の CSS を追加します。

必要に応じてマイナー ブレークポイントを設定する

レイアウトが大幅に変わる場合は、メジャー ブレークポイントを選択することに加えて、軽微な変更に合わせて調整することも有効です。たとえば、メジャー ブレークポイント間では、要素のマージンやパディングを調整したり、フォントサイズを大きくしてレイアウトに自然に見えるようにしたりすると便利です。

まず、小画面レイアウトを最適化しましょう。ここでは、ビューポートの幅が 360px より大きいときにフォントを大きくします。次に、十分なスペースがあれば、高温と低温度を分離して、上下に並ぶのではなく同じ行に表示できます。また、天気アイコンを少し大きくしましょう。

@media (min-width: 360px) {
  body {
    font-size: 1.0em;
  }
}

@media (min-width: 500px) {
  .seven-day-fc .temp-low,
  .seven-day-fc .temp-high {
    display: inline-block;
    width: 45%;
  }

  .seven-day-fc .seven-day-temp {
    margin-left: 5%;
  }

  .seven-day-fc .icon {
    width: 64px;
    height: 64px;
  }
}

同様に、大画面の場合は、画面幅全体を使い果たさないように、予測パネルの最大幅に制限することをおすすめします。

@media (min-width: 700px) {
  .weather-forecast {
    width: 700px;
  }
}

テキストが読みやすいように最適化する

従来の可読性理論では、理想的な列は 1 行あたり 70 ~ 80 文字(英語では約 8 ~ 10 語)にすることが推奨されています。そのため、テキスト ブロックの幅が約 10 単語を超えるたびに、ブレークポイントを追加することを検討してください。

モバイル デバイスで表示されたテキストページのスクリーンショット
モバイル デバイスで読み上げられたテキスト。
パソコンのブラウザに表示されたテキストのページのスクリーンショット
行の長さを制限するブレークポイントが追加された、パソコンのブラウザで読み上げられるテキスト。

上記のブログ投稿の例を詳しく見てみましょう。 小さい画面では 1em の Roboto フォントが 1 行あたり 10 語になりますが、大きい画面ではブレークポイントが必要です。この場合、ブラウザの幅が 575px より大きい場合、理想的なコンテンツの幅は 550px です。

@media (min-width: 575px) {
  article {
    width: 550px;
    margin-left: auto;
    margin-right: auto;
  }
}

コンテンツを単に非表示にすることは避ける

画面サイズに応じて、どのコンテンツを表示または非表示にするかを選択する際は注意が必要です。 画面に収まらないという理由だけでコンテンツを非表示にするのではなく、画面サイズは、ユーザーが何を求めているかを正確に示すものではありません。たとえば、天気予報から花粉数を除外することは、春のアレルギー患者にとって、外に出られるかどうかを判断するために情報を必要とする深刻な問題となる可能性があります。

Chrome DevTools でメディアクエリ ブレークポイントを表示する

メディアクエリ ブレークポイントを設定したら、サイトがどのように表示されるかを確認します。ブラウザ ウィンドウのサイズを変更してブレークポイントをトリガーできますが、Chrome DevTools には、さまざまなブレークポイントでページがどのように見えるかを簡単に確認できる機能が組み込まれています。

天気情報アプリが開かれ、幅 822 ピクセルが選択されている DevTools のスクリーンショット。
広いビューポート サイズで天気アプリを表示している DevTools。
天気情報アプリが開かれ、幅 436 ピクセルが選択されている DevTools のスクリーンショット。
DevTools に天気アプリが表示され、小さいビューポートのサイズで表示されている。

さまざまなブレークポイントでページを表示するには:

DevTools を開いて、[Device Mode] をオンにします。デフォルトではレスポンシブ モードで開きます。

メディアクエリを表示するには、[Device Mode] メニューを開き、[Show media クエリ] を選択してブレークポイントを色付きのバーとしてページに表示します。

いずれかのバーをクリックすると、そのメディアクエリがアクティブな状態でページが表示されます。 バーを右クリックすると、メディアクエリの定義にジャンプします。