Skip to content
This page has been auto-translated and may contain errors.View in English

レスポンシブデザイン

docs.scrimba.com

ノートパソコンでページを作成し、見栄えが良いと思ったら、誰かがそれをスマートフォンで開く。注意深く配置したカラムが今は狭いスリバーに押しつぶされ、テキストは端からはみ出し、本来はないはずの水平スクロールバーが表示される。サイトの別のスマートフォン版を作成した人はいません。ページは1つで、380ピクセルのスマートフォンと1400ピクセルのモニターの両方で、すべてを重複して配信することなく見栄え良くする必要があります。その適応性がレスポンシブデザインであり、ほとんどは既に持っているツールから構築されます。

レスポンシブデザインの意味とビューポート

**レスポンシブ**ページは、どんな画面に表示されても、自分自身を変形させるのに適したページです。同じHTMLと同じCSSがスマートフォン、タブレット、デスクトップに対応し、何もはみ出さず、何も窮屈に感じないようにレイアウトが調整されます。3つのサイトを構築しているのではありません。曲がるサイトを1つ構築しているのです。

すべてが機能する前に、ブラウザはHTMLの中で1つの命令が必要です。スマートフォンはかつてデスクトップ幅のふりをして、ページ全体を縮小して適応させていました。そのため古いサイトは小さく、ズームアウトされたメスのように表示されていました。HTMLの<head>にある次の1行は、スマートフォンに代わりにその実際の幅を使用するよう指示しています:

html
<meta name="viewport" content="width=device-width, initial-scale=1" />

これがないと、CSSは架空の広い画面をスタイリングしており、注意深くレイアウトされたものは機会を得られません。

レスポンシブデザインとは、ビューポート(ブラウザウィンドウ内のページの表示領域)のサイズに合わせてレイアウトを適応させる単一のコードベースを意味しています。HTMLのセットは1つ、スタイルシートは1つです。変わるのは、そのスタイルシートが与えられたスペースにどのように応答するかです。別のモバイルとデスクトップのサイトの代替案は、メンテナンスを倍にするもので、業界が何年も前にレスポンシブを採用した理由です。

開始要件はHTMLヘッドのビューポートメタタグです。ブラウザが配置する幅をデバイスの実際の幅に設定し、モバイルブラウザが偽のデスクトップ幅でレンダリングしてスケールダウンするのを止めます:

html
<meta name="viewport" content="width=device-width, initial-scale=1" />

width=device-widthはレイアウトビューポートをスクリーンに一致させ、initial-scale=1は初期ズームを100%に設定します。これを省略すると、正しいCSSがいくらあってもレイアウトを救うことはできません。なぜなら、ブラウザが間違った幅に対して測定しているからです。

レスポンシブデザインは、固定の少数の画面をターゲットにするのではなく、**ビューポート**サイズの連続範囲に合わせてレイアウトを適応させる1つのドキュメントを構築する実装です。ビューポートは、ブラウザがページをレイアウトしてペイントするのに使用する領域で、その幅はすべての相対単位、パーセンテージ、メディアクエリが最終的に解決される値です。その幅を間違えると、下流のすべてが間違った値に対して測定しています。

これは、ビューポートメタタグが防止するものそのものです。モバイルブラウザは従来、レイアウトビューポート(CSSが配置される幅)とビジュアルビューポート(実際に画面に表示されるもの)を区別し、レイアウトビューポートをデフォルトで約980pxに設定して、レガシーなデスクトップのみのサイトがレンダリングされてからズームアウトして適応するようにしていました。メタタグはそのギャップを埋めます:

html
<meta name="viewport" content="width=device-width, initial-scale=1" />

width=device-widthはレイアウトビューポートをデバイス自身のCSS-ピクセル幅に結びつけ、initial-scale=1は初期ズームをピン留めして、2つのビューポートが調整された状態で開始するようにします。HTMLヘッドに属し、リラックスではなく前提条件です。これなしでブラウザは、390pxのスマートフォンで約980pxに対してメディアクエリとパーセンテージを評価するため、min-width: 40remクエリは発動すべきでない時に発動し、テストしたレイアウトは表示されません。この章のすべてはそのタグが存在していることを前提としています。

Junoレスポンシブデザインの意味とビューポート レスポンシブページは、単一のHTMLとCSSセットからスマートフォンからデスクトップまであらゆる画面に対応する1つのページです。CSSが正当な機会を得る前に、HTMLヘッドはビューポートメタタグが必要です。これはスマートフォンに対してデスクトップのふりをするのではなく、実際の幅を使用するよう指示しています。これなしではCSSがどれほど優れていても、レイアウトは壊れたように見えます。
Junoレスポンシブデザインの意味とビューポート レスポンシブとはビューポート(表示ページ領域)に適応する1つのコードベースを意味し、別のモバイルとデスクトップビルドではありません。HTMLヘッドのビューポートメタタグが開始要件です。width=device-widthにより、ブラウザが実際のスクリーン幅に対して配置されるようにします。これをスキップすると、メディアクエリが偽のデスクトップ幅に対して発動し、正しいCSSでも見栄えが悪くなります。
Junoレスポンシブデザインの意味とビューポート すべてのパーセンテージとメディアクエリはビューポート幅に対して解決されるため、ビューポートメタタグは良いアイデアではなく前提条件です。width=device-width, initial-scale=1はレイアウトビューポートをレガシーな980pxのデフォルトではなくデバイスの実際の幅に結びつけます。スマートフォンではこれを忘れると、min-width: 40remクエリが発動すべきでない時に発動し、テストしたレイアウトはレンダリングされません。

流動的レイアウトを最優先に

本能的には特殊なスマートフォンルールをすぐに使用したくなりますが、多くのレスポンシブ性は1つのルールを書く前から無料で提供されます。**流動的**な値(スペースと共に伸び縮みするもの)で構築すると、レイアウトは既に適応しています。

ほとんどのボックスに2つの習慣が対応します。幅をパーセンテージとして設定して、ボックスが固定されたピクセル数ではなくそのコンテナのシェアを取得し、max-widthを使用して何かが小さい画面では縮小できますが、大きい画面では快適な読みやすさサイズを超えて成長することはありません:

css
.container {
  width: 90%;              /* 持っているスペースの90%を占める */
  max-width: 60rem;        /* しかし大きい画面では60remより広くならない */
  margin: 0 auto;          /* 中央揃え */
}

スマートフォンではこのコンテナは狭い画面の90%です。モニターでは60remで成長を停止し、中央に配置されます。スマートフォンルールを書きませんでした。値が適応しました。

メディアクエリの前に、**流動的**な値からレイアウトを構築してスペース変化に合わせて柔軟に対応するようにします。相対単位とパーセンテージにより、要素は固定サイズではなくコンテナのシェアを取得でき、flexboxgridは既にスペース変化に応じて子要素をリフローさせます。良い流動的レイアウトは、画面と戦っていないため、厳密なレイアウトよりはるかに少ないブレークポイントが必要です。

流動的レイアウトが対応しなくなった後にのみメディアクエリに達してください。パーセンテージとmax-widthは幅を処理し、1つのグリッドパターンはメディアクエリなしでも一般的なカード壁のケースを処理します:

css
.card-grid {
  display: grid;
  gap: 1.5rem;
  /* 16rem最小で収まるだけ多くのカラム、残りのスペースを均等に共有 */
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}

repeat(auto-fit, minmax(16rem, 1fr))は「最小16remで、できるだけ多くのカラムを合わせて、行を埋めるようにそれらを伸ばす」と言っています。広い画面では3カラム、タブレットでは2カラム、スマートフォンでは1カラム、そしてメディアクエリは1つもありません。これらの値に優先される相対単位はサイズ単位でカバーされます。

最も強力なレスポンシブレイアウトは、単一のメディアクエリが書かれる前は大部分が**流動的**です。なぜなら、ブレークポイントは離散的なジャンプであり、ほとんどの仕事は継続的だからです。パーセンテージ、max-widthflexboxgridに組み込まれた本質的なサイジングにより、レイアウトはビューポートをスムーズに追跡でき、メディアクエリはデザインが本当に形を変える必要があるポイントのみを処理し、リサイズの毎ピクセルではなくなります。

稼ぎを得るパターンは自己調整グリッドです。なぜなら、それは一連のブレークポイント全体を1つの宣言に圧縮するからです:

css
.card-grid {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}

minmax(16rem, 1fr)は各トラックに16remの下限と自由スペースの1つの等しいシェアの上限を与え、auto-fitはその下限に適応する限りの多くのトラックを作成し、行を埋めるためにそれらを拡張します。カラムカウントはコンテナ幅から自動的に削除されるため、3つのブレークポイントを取得するレイアウトはなくなります。1つの精度メモ:auto-fitは空のトラックを圧縮して現在のアイテムが残りのスペースを埋めるように拡張されるのに対し、auto-fillは空のトラックを予約済みにしておくため、アイテムが左余りスペースに成長するのを望むときはauto-fitを選択し、安定したグリッドを望むときはauto-fillを選択します。これらのremfr値がどのように解決されるかについてはサイズ単位を参照してください。

Juno流動的レイアウトを最優先に 多くのレスポンシブ性は特殊なルールを書く前は無料です。パーセンテージを使用してボックスがスペースのシェアを取得し、max-widthを使用してスマートフォンでは縮小して、モニターでは過度に拡大しないようにします。これら2つの値はレイアウトを自分で適応させます。流動的に構築すれば、次に来る電話固有のルールがはるかに少なくなります。
Juno流動的レイアウトを最優先に ブレークポイントを構築する前に流動的に構築してください。パーセンテージとmax-widthは幅を処理し、flexboxとgridは既に自分でリフローします。記憶するための1つのグリッド行はrepeat(auto-fit, minmax(16rem, 1fr))で、メディアクエリがなくレスポンシブカード壁を提供します。流動的レイアウトが本当に対応しなくなった後にのみクエリに達してください。
Juno流動的レイアウトを最優先に ブレークポイントは離散的なジャンプですが、リサイズは継続的なため、パーセンテージ、max-width、本質的なフレックスとグリッドサイジングに平滑な部分を実行させ、メディアクエリを実際の形の変更のために節約してください。repeat(auto-fit, minmax(16rem, 1fr))は複数のブレークポイントを1行に圧縮します。auto-fitは空のトラックを圧縮してアイテムを拡張することを覚えておく一方、auto-fillはそれらを予約済みにしておきます。

メディアクエリ

時々流動的な値は十分ではなく、レイアウトが実際に特定のサイズで変更される必要があります。例えば、スマートフォンでは垂直にスタックするメニューがデスクトップでは列に配置されるメニュー。それが**メディアクエリ**の目的です。設定した条件をスクリーンが満たすときのみ適用されるCSSブロック。

小さい画面のスタイルを通常のCSSとして開始し、より広い画面の変更をレイアウトするクエリを追加してください:

css
.nav {
  display: flex;
  flex-direction: column;   /* 小さい画面ではスタック */
}

@media (min-width: 40rem) {
  .nav {
    flex-direction: row;    /* スペースがあれば並べる */
  }
}

@media (min-width: 40rem)内のルールは、スクリーンが少なくとも40remの幅になると切り替わります。その下では、プレーンな.navルールが適用され、メニューはスタックします。

**メディアクエリはルールのセットを条件(ほとんどの場合、幅テスト)でラップし、条件が成立する場合のみそれらのルールが適用されます。採用するパターンはモバイルファースト**です。クエリなしで最小画面の基本スタイルを記述し、min-widthを使用して上向きに増強をレイアウトしてください。

css
.layout {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;      /* 基本:単一カラム、小さい画面 */
}

@media (min-width: 40rem) {
  .layout {
    grid-template-columns: 1fr 1fr; /* スペースがあれば2カラム */
  }
}

モバイルファーストはきれいさ以上のためにも重要です。基本スタイルは常に適用されるため、最も単純で最も信頼できるレイアウトを作成することは、最小で最も制約のあるデバイスが デフォルトで最も安全な体験を得ることを意味し、各クエリは機能のみを追加します。別の方法で構築する(デスクトップファースト、機能を削除するmax-widthクエリ)と、モバイルビューが壊れた後付けになる傾向があります。

**メディアクエリはメディア条件が真と評価される場合のみルールのブロックを適用し、レスポンシブレイアウトではその条件はほぼ常にビューポート幅テストです。保有されている規律はモバイルファースト**です。無条件の基本スタイルは狭いレイアウトを説明し、すべてのmin-widthクエリはその上に純粋に追加されます。

css
.layout {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;       /* 基本、どこでも適用 */
}

@media (min-width: 40rem) {         /* タブレット以上 */
  .layout { grid-template-columns: 1fr 1fr; }
}

@media (min-width: 64rem) {         /* デスクトップ以上 */
  .layout { grid-template-columns: 1fr 2fr 1fr; }
}

減算的なmax-widthより加算的なmin-widthを優先する理由は、カスケードです。これらのクエリは特異性を共有するため、後に発動したものが以前のものをオーバーライドするため、小から大へ順序付けることで、より広い各ブレークポイントが適用される場所でクリーンに勝ちます。保持する価値のある2つの精度があります。条件でpxよりremを優先してブレークポイントがユーザーのフォントサイズを追跡し、幅クエリがレイアウトビューポートを読むことを知ってください。これはビューポートメタタグがそれをデバイス幅に固定したため、そしてのみ正しいです。min-widthスタックの中央の迷ったmax-widthクエリは、ルールが神秘的に適用を停止する通常の原因です。なぜなら、それは拡張するのではなく順序付けと戦っているからです。

Junoメディアクエリ メディアクエリは、スクリーンが少なくとも40remの幅のように条件を満たす場合のみ切り替わるCSSブロックです。小さい画面スタイルを通常のCSSとして最初に記述し、@media (min-width: ...)を使用してより大きい画面の変更を追加します。そのようにスマートフォンビューは開始点であり、その後付けパッチではありません。
Junoメディアクエリ メディアクエリは、通常は幅が成立する条件のみに適用ルールを適用します。モバイルファーストで始めてください。クエリなしで最小画面の基本スタイル、その後min-widthを使用してレイアウトして、各クエリのみを追加します。その方法でmax-widthを構築してスマートフォンビューは壊れた後付けになる傾向があります。
Junoメディアクエリ モバイルファーストは狭いレイアウトの無条件基本スタイルと小から大へスタックした加算的なmin-widthクエリを意味し、カスケードが各ブレークポイントをクリーンに解決します。条件でremを使用してユーザーのフォントサイズを追跡し、幅クエリがメタタグを固定したレイアウトビューポートを読むことを覚えてください。min-widthスタックの孤独なmax-widthは、ルールが静かに適用を停止する古典的な理由です。

ブレークポイントの選択

**ブレークポイント**は、メディアクエリが開始されレイアウトが変更される幅です。選択する誘惑的な方法は、人気のあるスマートフォンまたはタブレットの幅を調べてそれに一致させることです。これが罠です。数百のデバイスサイズがあり、毎年変更され、それらを追いかけることは勝つことができないゲームです。

より良い質問は、このレイアウトがどのような幅で見栄えが悪くなり始めるのかです。ブラウザを遅くゆっくり広げて見てください。テキストが長すぎて快適に読めなくなったり、2つのカラムが狭すぎたりする場合、それがブレークポイントが属する場所で、それが何番号であろうと関係なく。

css
/* ブレークポイントが選ばれたのはテキストがここで広すぎるために、 */
/* スマートフォンがこのサイズであるという理由ではなく */
@media (min-width: 45rem) {
  .article { max-width: 38rem; }
}

**ブレークポイント**はビューポート幅で、レイアウトを変更します。デバイス名を一致させるのではなく、自分のコンテンツを見て選んでください。「768pxなぜならそれはiPad」のような丸い数字は権威的に見えて罠です。デバイスランドスケープは絶えず変化し、昨年の人気サイズにチューニングされたレイアウトは今年のサイズで破損します。

コンテンツに決めさせてください。ウィンドウをリサイズして、デザインが実際にストレスを感じる幅に、ラインが長すぎる、カードが窮屈すぎる、ナビゲーションがスペースを使い果たす。通常、サイト全体で2つか3つだけが必要です:

css
/* コンテンツ駆動:このラインは約75文字に当たって読みづらくなった */
@media (min-width: 42rem) {
  .prose { max-width: 65ch; }   /* スペースがあれば測定量をキャップ */
}

/* コンテンツ駆動:サイドバーレイアウトはここでのみスペースを稼ぐ */
@media (min-width: 60rem) {
  .page { grid-template-columns: 16rem 1fr; }
}

**ブレークポイント**はデザインが形を変える場所で、耐久性のある選択方法はデバイス仕様シートではなくコンテンツが設定することです。名前付きデバイス幅を照合することは構造的な理由で脆いです。スクリーンサイズの母集団は大きく、毎年ドリフトするため、特定のデバイス寸法にキー設定されたレイアウトは移動目標にキー設定され、スケジュールに従って腐ります。コンテンツで正当化されたブレークポイント「測定値が読みやすいラインの長さを超えたここ」は、次にどのハードウェアが出荷されても正当化されたままです。

実際には、これはリサイズしてレイアウトがストレスを感じるまで配置してブレークポイントを配置することを意味し、ほとんどのサイトはほんの一握り必要です:

css
/* 行が読みやすい長さを超える場所で測定値をキャップ、約65文字 */
@media (min-width: 42rem) {
  .prose { max-width: 65ch; }
}

/* メインカラムがスペアの幅を持つことができる場所のみサイドバーを導入 */
@media (min-width: 60rem) {
  .page { grid-template-columns: 16rem 1fr; }
}

上級の動きは、流動的なタイプとスペーシングのためにclamp()に頼るため、より少ないブレークポイントが全く必要です。clamp(min, preferred, max)はビューポートでスケールするが両端で境界付けられる値を選択するため、見出しとギャップはスムーズに成長し、各クエリで飛び跳ねません:

css
h1 {
  /* 1.75remを下回ることはなく、3remを上回ることはなく、その間に流動的 */
  font-size: clamp(1.75rem, 4vw + 1rem, 3rem);
}

それはほとんどのタイプグラフィックスケーリングをブレークポイントなしで全くカバーしています。サイズ単位vw項がどのように解決されるかと、タイポグラフィでタイプスケール側を参照してください。3つの関連ツールは、これを完成させます。コンテナクエリはビューポートではなく独自のコンテナの幅によってコンポーネントをスタイリングするため、カードはページ全体ではなく、それが座っているカラムに応答することができます。これは、ビューポートベースのメディアクエリへのコンポーネント用レスポンスの対応物です。prefers-reduced-motionクエリにより、システムをリクエストするリーダーのアニメーションをカットでき、prefers-color-schemeによりシステムライトまたはダークプリファレンスを尊重でき、どちらもメディアクエリとして記述されます:

css
@media (prefers-reduced-motion: reduce) {
  * { animation: none; transition: none; }  /* OSの設定を尊重 */
}

@media (prefers-color-scheme: dark) {
  body { background: #111; color: #eee; }
}

画像の場合、レスポンシブ性はHTMLに移動します。srcset属性により、ブラウザは画面ごとに適切にサイズされたファイルを選択できます。これはHTMLレスポンシブ画像の章でCSSではなくカバーされます。

Junoブレークポイントの選択 ブレークポイントはレイアウトが変更される幅で、罠は特定のスマートフォンまたはタブレットに一致させることを選択することです。追いかけるデバイスサイズが多すぎて、毎年変更されます。ブラウザをゆっくり広げてレイアウトが実際に見栄えが悪くなり始める幅にブレークポイントを追加します。それが何番号であろうと関係なく。
Junoブレークポイントの選択 コンテンツがブレークポイントを選んであげてください。デバイス名ではなく。ラインが長すぎたり、カードが窮屈すぎたりしている場合は実際の信号であり、768pxのような丸いデバイス幅は移動目標であり、スケジュール上腐ります。デザインがストレスを感じるまでリサイズしてそこにブレークポイントを配置します。ほとんどのサイトは全体を通して2つか3つだけが必要です。
Junoブレークポイントの選択 コンテンツ駆動ブレークポイントは、スクリーン母集団が毎年ドリフトするため、生き残ります。デバイス寸法にキー設定されたものはスケジュール上腐ります。流動的なタイプとスペーシングのためにclamp()に頼ってはるかに少ないブレークポイントが全く必要なため、コンポーネントレベルではなくビューポートレベルのスタイリングのためのコンテナクエリを頭に入れ、prefers-reduced-motionprefers-color-schemeを尊重してください。画像の場合、レスポンシブ性はCSS、HTMLsrcsetではなく生きています。