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

インターネットを利用する携帯電話ユーザーの増加に伴い、さまざまな画面サイズに対応したコンテンツ レイアウトの重要性が高まっています。レスポンシブ ウェブ デザインは、もともと Ethan Marcotte が A List Apart で定義したもので、サイトのレイアウトをユーザーが使用しているデバイスに合わせて変更することで、ユーザーのニーズとデバイスの機能に対応するデザイン戦略です。たとえば、レスポンシブ サイトでは、スマートフォンでは 1 列、タブレットでは 2 列、パソコンでは 3 列または 4 列でコンテンツを表示できます。

画面が広くなると、ウィジェットの形状が変化します。

インターネット対応デバイスにはさまざまな画面サイズがあるため、サイトは既存の画面サイズにも将来の画面サイズにも対応することが重要です。最新のレスポンシブ デザインでは、タッチスクリーンなどの操作モードも考慮されます。この目標は、すべてのユーザーのエクスペリエンスを最適化することです。

ビューポートを設定する

さまざまなデバイス向けに最適化されたページには、ドキュメントの head にビューポート メタタグを含める必要があります。このタグは、ページのサイズと拡大縮小を制御する方法をブラウザに指示します。

モバイル ブラウザでは、最適なユーザー エクスペリエンスを提供するため、パソコン画面の幅(通常はおよそ 980px。デバイスによって異なります)でページをレンダリングし、フォントサイズを大きくして画面に収まるようにコンテンツを縮小する、といった調整を試みます。この調整により、フォントの統一感が失われ、コンテンツを表示して操作するためにズームが必要になることがあります。

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

メタ ビューポート値 width=device-width を使用すると、デバイス非依存ピクセル(DIP)で画面の幅に一致するようにページに指示されます。DIP は標準の視覚ピクセル単位です(高密度画面では多くの物理ピクセルで構成されることがあります)。これにより、ページはさまざまな画面サイズに合わせてコンテンツをリフローできます。

ズームアウトしすぎてテキストが読みにくいページ。
ビューポート メタタグのないページは、非常に縮小されて読み込まれるため、テキストが読みにくくなります。
テキストが読めるサイズで表示された同じページ。
ビューポート メタタグを設定すると、ズームインせずにページを読めるようになります。

一部のブラウザでは、横向きモードに回転したときにページの幅が一定に保たれ、リフローではなく画面全体に拡大されます。値 initial-scale=1 を追加すると、デバイスの向きに関係なく CSS ピクセルとデバイス非依存ピクセルの間に 1:1 の関係を設定するようブラウザに指示し、ページで横向きの幅を最大限に活用できるようになります。

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

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

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

meta viewport タグを使用してモバイルサイトを開発する際に、指定したビューポートに収まらないページ コンテンツを誤って作成してしまうことはよくあります。たとえば、ビューポートよりも幅の広い画像を表示すると、水平スクロールが発生する可能性があります。これを回避するには、コンテンツをビューポート内に収まるように調整します。

コンテンツのサイズとビューポートのサイズが一致していませんという Lighthouse の監査では、オーバーフローしているコンテンツを検出するプロセスを自動化できます。

画像

固定サイズの画像は、ビューポートよりも大きい場合、ページをスクロールさせます。すべての画像に 100%max-width を指定することをおすすめします。これにより、画像が利用可能なスペースに合わせて縮小され、元のサイズを超えて拡大されるのを防ぐことができます。

ほとんどの場合、スタイルシートに以下を追加することで、この処理を行うことができます。

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

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

max-width: 100% を設定した場合でも、ブラウザが画像を読み込む前にスペースを確保できるように、<img> タグに width 属性と height 属性を追加することをおすすめします。これにより、レイアウト シフトを防ぐことができます。

レイアウト

画面の寸法と CSS ピクセルでの幅はデバイスによって大きく異なるため(スマートフォンとタブレット、さらにはスマートフォン同士でも異なります)、コンテンツが特定のビューポート幅に依存して適切にレンダリングされるべきではありません。

以前は、レイアウト要素をパーセンテージで設定する必要がありました。ピクセル単位の測定値を使用すると、小さな画面でユーザーが横にスクロールする必要があります。

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

パーセンテージを使用すると、各列が常に画面幅の同じ割合を占めるため、小さい画面では列が狭くなります。

flexbox、グリッド レイアウト、マルチカラムなどの最新の CSS レイアウト技術を使用すると、このような柔軟なグリッドを簡単に作成できます。

Flexbox

Flexbox は、さまざまなサイズのアイテムのセットがあり、それらを 1 行または複数行に収めたい場合に便利です。サイズの小さいアイテムは占有スペースが小さく、サイズの大きいアイテムは占有スペースが大きくなります。

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

Flexbox を使用すると、アイテムを 1 行で表示したり、使用可能なスペースが減少すると複数行に折り返したりできます。

詳しくは、Flexbox の詳細をご覧ください。

CSS グリッド レイアウト

CSS グリッド レイアウトでは、柔軟なグリッドを作成できます。グリッド レイアウトと fr 単位(コンテナ内の使用可能なスペースの一部を表す)を使用すると、前に示したフローティングの例を改善できます。

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

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

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

複数列レイアウト

一部のレイアウト タイプでは、複数列レイアウト(Multicol)を使用できます。このレイアウトでは、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

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

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

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

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

これらの新しい機能は、すべての最新ブラウザで十分にサポートされています。詳しくは、hoverany-hoverpointerany-pointer の MDN ページをご覧ください。

any-hoverany-pointer を使用する

any-hoverany-pointer の機能は、ユーザーが要素にポインタを合わせることができるか(一般に「ホバー」と呼ばれる)、デバイスの主な操作方法ではない場合でもポインタをまったく使用できるかをテストします。たとえば、タッチスクリーン ユーザーにマウスへの切り替えを強制しないようにするなど、これらの使用には十分に注意してください。ただし、ユーザーがどのようなデバイスを使用しているかを判断することが重要な場合は、any-hoverany-pointer が役立ちます。たとえば、タッチスクリーンとトラックパッドを備えたノートパソコンは、ホバー機能に加えて、粗いポインタと細かいポインタを一致させる必要があります。

ブレークポイントの選択方法

デバイス クラス、プロダクト、ブランド名、オペレーティング システムに基づいてブレークポイントを定義しないでください。これにより、コードの保守が難しくなります。代わりに、コンテンツがコンテナに合わせてレイアウトを変更する方法を決定します。

小規模から始めて、徐々に拡大して主要なブレークポイントを選択する

まず、コンテンツが小さい画面サイズに収まるように設計し、ブレークポイントが必要になるまで画面を拡大します。これにより、ページ上のブレークポイントの数を最小限に抑え、コンテンツに基づいて最適化できます。

次の例では、このページの冒頭にある天気予報ウィジェットの例について説明します。最初のステップは、小さな画面で天気予報が適切に表示されるようにすることです。

モバイル幅の天気アプリ
幅が狭いアプリ。

次に、要素間の空白が多すぎてウィジェットが適切に表示されなくなるまで、ブラウザのサイズを変更します。判断は主観的ですが、600px より広い範囲は広すぎます。

アイテム間の間隔が広い天気アプリ
このサイズでは、アプリのレイアウトを変更する必要があるでしょう。

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

@media (max-width: 600px) {

}

@media (min-width: 601px) {

}

最後に、CSS をリファクタリングします。600pxmax-width のメディアクエリ内に、小さい画面専用の CSS を追加します。601pxmin-width のメディアクエリ内に、大画面用の 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;
  }
}

コンテンツを非表示にしない(:#avoid-hiding-content)

画面サイズに応じて非表示または表示するコンテンツを選択する際は、注意が必要です。画面に収まらないという理由だけでコンテンツを非表示にしないでください。画面サイズでは、ユーザーが何を求めているかを予測できません。たとえば、花粉症の人が外出できるかどうかを判断するために必要な花粉の飛散数が天気予報から削除された場合、花粉症の人にとっては深刻な問題となります。

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

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

天気アプリを開き、幅 822 ピクセルを選択した状態の DevTools。
DevTools で、ビューポートのサイズを大きくした天気アプリが表示されている。
天気アプリを開いた状態で、幅が 436 ピクセルに選択されている DevTools。
ビューポートのサイズが狭い状態で天気アプリを表示している DevTools。

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

  1. DevTools を開きます
  2. [デバイスモード] をオンにします。デフォルトでは、レスポンシブ モードで開きます。
  3. メディアクエリを表示するには、デバイスモード メニューを開き、[メディアクエリを表示] を選択します。ブレークポイントがページの上に色付きのバーとして表示されます。
  4. バーのいずれかをクリックすると、そのメディアクエリがアクティブな状態でページが表示されます。バーを右クリックすると、そのメディアクエリの定義に移動します。