好みのメディアクエリを使用してユーザー適応インターフェースを構築

1. 始める前に

211ff61d01be58e.png

最近では、ユーザーがデバイスで多くの設定を行っています。OS やアプリを自分のもののように感じたいと考えています。ユーザー適応型インターフェースとは、これらの設定を使用してユーザー エクスペリエンスを向上させ、より親しみやすく、自分だけのもののように感じられるようにする準備が整っているインターフェースのことです。正しく行われると、ユーザーはユーザー エクスペリエンスが適応していることや適応したことに気づかない可能性があります。

ユーザー設定

デバイスのハードウェアの選択は設定、オペレーティング システムの選択は選択、アプリとオペレーティング システムの色の選択は設定、アプリとオペレーティング システムのドキュメントの言語の選択は設定です。ユーザーの好みは増える一方です。ウェブページはすべてのものにアクセスできるわけではありません。それには正当な理由があります

CSS で使用できるユーザー設定の例をいくつかご紹介します。

CSS に近日中に導入予定のユーザー設定の例を次に示します。

メディアクエリ

CSS とウェブでは、メディアクエリを使用して適応性とレスポンシブ デザインを実現しています。メディアクエリは、条件が true の場合に一連のスタイルを含む宣言型条件です。最も一般的なのは、デバイスのビューポート サイズに関する条件です。サイズが 800 ピクセル未満の場合、そのケースに適したスタイルを適用します。

ユーザー適応型

適応しないインターフェースとは、ユーザーがアクセスしても何も変化せず、調整できないため、基本的にすべての人に同じエクスペリエンスを提供するものです。ユーザー適応型インターフェースでは、5 人のユーザーに対して 5 つの異なる外観とスタイルを設定できます。機能は同じですが、UI を調整できるユーザーにとっては、美観が向上し、インターフェースの使いやすさが向上します。

前提条件

作成するアプリの概要

この Codelab では、次の内容に適応するユーザー適応型フォームを作成します。

  • フォーム コントロールと周囲の UI 要素にライトとダークのカラーパターンを提供することで、システムのカラーパターン設定
  • 複数の種類のアニメーションを提供することで、システムのモーション設定をサポートします。
  • モバイルとパソコンのエクスペリエンスを提供するための、小画面と大画面のデバイス ビューポート
  • キーボード、スクリーン リーダー、タッチ、マウスなどのさまざまな入力タイプ
  • 任意の言語と読み取り/書き込みモード

de5d580a5b8d3c3d.png

学習内容

この Codelab では、ユーザー適応型フォームの作成に役立つ最新のウェブ機能について学びます。次の方法について学びます。

  • ライトモードとダークモードを作成する
  • アニメーション付きのユーザー補助対応フォームを構築する
  • レイアウト レスポンシブ フォーム
  • 相対単位と論理プロパティを使用する

f142984770700a43.png

この Codelab では、ユーザー アダプティブ インターフェースに焦点を当てます。関連のない概念やコードブロックについては詳しく触れず、コードはコピーして貼るだけの状態で提供されています。

必要なもの

  • Google Chrome 89 以降、またはお好みのブラウザ

19e9b707348ace4c.png

2. セットアップする

コードを取得する

このプロジェクトに必要なすべてのコードは GitHub リポジトリにあります。まず、コードを取得して、お好みの開発環境で開く必要があります。または、この Codepen をフォークして、そこから作業することもできます。

推奨: Codepen を使用する

  1. 新しいブラウザタブを開きます。
  2. https://codepen.io/argyleink/pen/abBMeeq にアクセスします。
  3. アカウントをお持ちでない場合は、アカウントを作成して作業内容を保存してください。
  4. [Fork] をクリックします。

代替案: ローカルで作業する

コードをダウンロードしてローカルで作業する場合は、Node.js バージョン 12 以降と、コードエディタを設定して準備しておく必要があります。

Git を使用する

  1. https://github.com/argyleink/Google-IO-2021-Workshop_User-Adaptive-Interfaces にアクセスします。
  2. リポジトリをフォルダに複製します。
  3. デフォルトのブランチは beginning です。

ファイルを使用する

  1. ダウンロードした zip ファイルをフォルダに解凍します。

プロジェクトを実行する

上記の手順のいずれかで確立したプロジェクト ディレクトリを使用します。

  1. npm install を実行して、サーバーの実行に必要な依存関係をインストールします。
  2. npm start を実行して、ポート 3000 でサーバーを起動します。
  3. 新しいブラウザタブを開きます。
  4. http://localhost:3000 に移動します。

HTML について

このレッスンでは、ユーザー適応型のインタラクティビティをサポートするために使用される HTML の側面について説明します。このワークショップでは、CSS に焦点を当てます。フォームやウェブサイトの作成を初めて行う場合は、提供された HTML を確認することをおすすめします。HTML 要素の選択は、アクセシビリティとレイアウトの点で重要になることがあります。

準備ができたら、このスケルトンを動的で適応性のあるユーザー エクスペリエンスに変換します。

de5d580a5b8d3c3d.png

3. アダプティブ インタラクション

Git ブランチ: beginning

このセクションを終えると、設定フォームは次のようになります。

  • ゲームパッド + キーボード
  • マウスとタッチ
  • スクリーン リーダーなどの支援技術

HTML の属性

ソースコードで提供されている HTML は、フォーム入力のグループ化、順序付け、ラベル付けに役立つセマンティック要素がすでに選択されているため、優れた出発点となります。

フォームはビジネスにとって重要なインタラクション ポイントであることが多いため、ウェブで利用できるさまざまな種類の入力に対応できることが重要です。たとえば、タッチ操作でモバイルで使用できるフォームを用意することが重要になる可能性があります。このセクションでは、レイアウトとスタイルの前に、アダプティブ入力のユーザビリティを確保します。

入力のグループ化

HTML の <fieldset> 要素は、類似する入力とコントロールをグループ化するためのものです。フォームには、音量と通知の 2 つのグループがあります。これはユーザー エクスペリエンスにとって重要であり、セクション全体をスキップできます。

要素の順序指定

要素の順序は論理的な順序で提供されます。これはユーザー エクスペリエンスにとって重要です。ゲームパッド、キーボード、スクリーン リーダーの技術で視覚的なエクスペリエンスの順序が同じか類似している必要があります。

キーボード操作

ウェブのユーザーは、Tab キーでフォームを移動することに慣れています。幸いなことに、期待される HTML 要素を提供すれば、ブラウザがその処理を行います。<button><input><h2><label> などの要素を使用すると、自動的にキーボードまたはスクリーン リーダーの移動先になります。

9fc2218473eee194.gif

上の動画では、タブキーと矢印キーを使用してインターフェース内を移動し、変更を加える方法を示しています。ただし、青いアウトラインが入力要素の周りにぴったりと表示されているため、次のスタイルを追加して、このインタラクションに少し余裕を持たせます。

style.css

input {
  outline-offset: 5px;
}

お試しください

  1. index.html で使用されている HTML 要素を確認します。
  2. ブラウザでデモページをクリックします。
  3. tab キーと shift+tab キーを押して、フォーム内の要素のフォーカスを移動します。
  4. キーボードを使用して、スライダーとチェックボックスの値を変更します。
  5. Bluetooth ゲームパッド コントローラを接続し、フォーム内の要素のフォーカスを移動します。

マウス操作

ウェブのユーザーは、マウスでフォームを操作することに慣れています。フォームでマウスを使用してみてください。スライダーとチェックボックスは機能しますが、もっと良い方法があります。マウスでクリックするには、チェックボックスが小さすぎます。

ab51d0c0ee0d6898.gif

ラベルとその入力を接続するための2 つのユーザー エクスペリエンス機能を確認してください。

1 つ目の機能は、操作対象のオプションがあることです。ラベルは小さな四角形よりもマウスでターゲットにしやすいです。

2 つ目の機能は、ラベルがどの入力に対応しているかを正確に把握できることです。現在、CSS がないため、属性を指定しない限り、どのラベルがどのチェックボックスに対応しているかを判断するのは非常に困難です。

この明示的な接続により、スクリーン リーダーの操作性も向上します。これについては次のセクションで説明します。

関連付けられていない: 要素を接続する属性がない

<input type="checkbox">
<label>...</label>

関連付け: 要素を接続する属性

<input type="checkbox" id="voice-notifications" name="voice-notifications">
<label for="voice-notifications">...</label>

提供された HTML では、すべての入力とラベルがすでに属性付けされています。このコンセプトが初めての場合は、さらに詳しく調べてみることをおすすめします。

お試しください

  1. ラベルにカーソルを合わせると、チェックボックスがハイライト表示されます。
  2. Chrome デベロッパー ツールでラベル要素を調べ、チェックボックスを選択できるクリック可能なサーフェス領域を可視化します。

スクリーン リーダーの操作

支援技術はこのフォームとやり取りでき、いくつかの HTML 属性を使用することで、ユーザー エクスペリエンスをよりスムーズにすることができます。

28c4a14b892c62d0.gif

Chrome でスクリーン リーダーを使用して現在のフォームを操作しているユーザーにとって、<picture> 要素での不要な停止があります(Chrome 固有ではありません)。スクリーン リーダーを使用しているユーザーは、視覚障がいが原因でスクリーン リーダーを使用している可能性が高いため、画像で停止しても役に立ちません。属性を使用して、スクリーン リーダーから要素を非表示にできます。

index.html

<picture aria-hidden="true">

スクリーン リーダーは、純粋に視覚的な要素をスキップするようになりました。

f269a73db943e48e.gif

スライダー要素 input[type="range"] には、特別な ARIA 属性 aria-labelledby="media-volume" があります。これにより、スクリーン リーダーがユーザー エクスペリエンスを向上させるために使用する特別な指示が提供されます。

お試しください

  1. オペレーティング システムのスクリーン リーダー テクノロジーを使用して、フォーム内のフォーカスを移動します。
  2. フォームでスクリーン リーダー ソフトウェアをダウンロードして試してみます。

4. アダプティブ レイアウト

Git ブランチ: layouts

このセクションを終えると、設定ページは次のようになります。

  • カスタム プロパティとユーザーの相対単位を使用してスペーシング システムを作成する
  • 柔軟でレスポンシブな配置と間隔を実現する CSS Grid を記述する
  • 国際的に適応可能なレイアウトには論理プロパティを使用する
  • メディアクエリを記述して、コンパクト レイアウトと広々としたレイアウトを切り替える

f142984770700a43.png

スペーシング

レイアウトを整えるための鍵は、間隔オプションのパレットを限定することです。これにより、コンテンツの自然な配置と調和が実現します。

カスタム プロパティ

このワークショップは、7 つのカスタム プロパティ サイズのセットに基づいて構築されています。

  • style.css の先頭に以下を配置します。

style.css

:root {
  --space-xxs: .25rem;
  --space-xs:  .5rem;
  --space-sm:  1rem;
  --space-md:  1.5rem;
  --space-lg:  2rem;
  --space-xl:  3rem;
  --space-xxl: 6rem;
}

名前は、ユーザーが空間を説明するために使用する言葉に近いものになっています。また、rem 単位は、適応し、ユーザーの環境設定を考慮した、読みやすい単位のサイズ設定にのみ使用します。

ページのスタイル

次に、ドキュメント スタイルを設定し、要素から余白を削除して、フォントを美しいサンセリフに設定する必要があります。

  • style.css に以下を追加します。

style.css

* {
  box-sizing: border-box;
  margin: 0;
}

html {
  block-size: 100%;
}

body {
  min-block-size: 100%;  
  padding-block-start: var(--space-xs);
  padding-block-end: var(--space-xs);
}

これで、スペーシングのカスタム プロパティを初めて使用できました。これで宇宙の旅が始まります。

タイポグラフィ

このレイアウトのフォントはアダプティブです。system-ui キーワードは、ユーザーのオペレーティング システムが最適なインターフェース フォントと判断したものをすべて使用します。

body {
  font-family: system-ui, sans-serif;
}

h1,h2,h3 { 
  font-weight: 500;
}

small {
  line-height: 1.5;
}

h1、h2、h3 のスタイルは軽微で、スタイルに関するものです。ただし、small 要素には、テキストが折り返される場合の追加の line-height が必要です。そうしないと、まとまりがなくなります。

論理プロパティ

bodypadding は、論理プロパティblock-startblock-end)を使用して辺を指定しています。この Codelab の以降の部分では、論理プロパティを多用します。rem 単位と同様に、ユーザーに適応します。このレイアウトは別の言語に翻訳でき、ユーザーが母国語で慣れている自然な書き方やドキュメントの方向を設定できます。論理プロパティを使用すると、スペース、方向、配置の定義を 1 つだけ指定して、このサポートを有効にできます。

ce5190e22d97156e.png

グリッドと flexbox はすでにフロー相対です。つまり、ある言語用に記述されたスタイルは、他の言語のコンテキストに合わせて適切に適用されます。適応型方向性。コンテンツはドキュメントの方向性を基準に流れます。

論理プロパティを使用すると、記述するスタイルを減らしながら、より多くのユーザーにリーチできます。

CSS グリッド レイアウト

grid CSS プロパティは、複雑なタスクに取り組むための多くの機能を備えた強力なレイアウト ツールです。シンプルなグリッド レイアウトをいくつか作成し、複雑なレイアウトを 1 つ作成します。また、マクロ レイアウトからマイクロ レイアウトまで、外側から内側に向かって作業します。間隔のカスタム プロパティは、パディングやマージンの値だけでなく、列のサイズやボーダーの半径などにも使用されるため、非常に重要になります。

以下は、Chrome DevTools で各 CSS グリッド レイアウトを一度にオーバーレイしたときのスクリーンショットです。

84e57c54d0633793.png

  1. style.css次の各スタイルを追加して、一緒に進めていきましょう。

<main>

main {
  display: grid;
  gap: var(--space-xl);
  place-content: center;
  padding: var(--space-sm);
}

デフォルトでは、Grid は各子要素を独自の行に配置するため、要素の積み重ねに最適です。また、gap を使用するというメリットもあります。以前、* セレクタを使用してすべての要素に margin: 0 を設定しましたが、これは間隔に gap を使用するようになったため重要です。ギャップは、コンテナ内のスペースを管理する単一の場所であるだけでなく、相対的なフローでもあります。

<form>

form {
  max-width: 89vw;
  display: grid;
  gap: var(--space-xl) var(--space-xxl);
  align-items: flex-start;
  grid-template-columns: 
    repeat(auto-fit, minmax(min(10ch, 100%), 35ch));
}

これはデザインの最も複雑なグリッド レイアウトですが、最もエキサイティングなレスポンシブな側面を考慮しています。

  • max-width は、レイアウト アルゴリズムがサイズを決定する際に使用する値を指定します。
  • gap はカスタム プロパティを使用しており、column-gap とは異なる row-gap を渡しています。
  • アイテムの高さが伸びないように、align-itemsflex-start に設定されています。
  • grid-template-columns には複雑な構文がありますが、目標は簡潔です。列 35ch の幅を 10ch 以上に保ち、空きがあれば列に配置し、なければ行に配置します。
  1. ブラウザのサイズ変更を試してみます。フォームが小さなビューポートの行に折りたたまれ、スペースがあれば新しい列にフローする様子をご覧ください。メディアクエリなしで適応します。メディアクエリを使用しないレスポンシブ スタイルのこの戦略は、コンポーネントやコンテンツ中心のレイアウトに特に役立ちます。

<section>

section {
  display: grid;
  gap: var(--space-md);
}

各セクションは、子要素の間に中程度のスペースがある行のグリッドにする必要があります。

header {
  display: grid;
  gap: var(--space-xxs);
}

各ヘッダーは、子要素間のスペースが非常に小さい行のグリッドにする必要があります。

<fieldset>

fieldset {
  padding: 0;
  display: grid;
  gap: 1px;
  border-radius: var(--space-sm);
  overflow: hidden;
}

このレイアウトは、カードのような外観を作成し、入力をグループ化します。次のセクションで色を追加すると、overflow: hiddengap: 1px が明確になります。

.fieldset-item

.fieldset-item {
  display: grid;
  grid-template-columns: var(--space-lg) 1fr;
  gap: var(--space-md);
  padding: var(--space-sm) var(--space-md);
}

このレイアウトは、アイコンとチェックボックスを関連するラベルとコントロールの中央に配置します。グリッド テンプレートの最初の列 var(--space-lg) は、アイコンよりも幅の広い列を作成します。これにより、子要素が中央に配置される場所ができます。

このレイアウトは、カスタム プロパティでどれだけの設計上の決定がすでに行われているかを示しています。パディング、ギャップ、列は、すでに定義した値を使用して、システムの調和内でサイズ設定されました。

.fieldset-item <picture>

.fieldset-item > picture {
  block-size: var(--space-xl);
  inline-size: var(--space-xl);
  clip-path: circle(50%);
  display: inline-grid;
  place-content: center;
}

このレイアウトは、設定、アイコンの円のサイズ、円形の作成、円内の画像の中心揃えを担当します。

画像>&amp;[checkbox] 配置" id="picture-[checkbox]-alignment" is-upgraded="" tabindex="-1"><picture> と [checkbox] の配置

.fieldset-item > :is(picture, input[type="checkbox"]) {
  place-self: center;
}

このレイアウトでは、:is 疑似セレクタを使用して、画像要素とチェックボックス要素の中央揃えを分離しています。

  1. 次のように、セレクタ picture > svg.fieldset-item svg置き換えます

.fieldset-item <svg>

.fieldset-item svg {
  block-size: var(--space-md);
}

これにより、SVG アイコンのサイズがサイズ表記の値に設定されます。

.sm-stack

.sm-stack {
  display: grid;
  gap: var(--space-xs);
}

このユーティリティ クラスは、チェックボックスのラベル要素がチェックボックスのヘルパー テキストを配置するためのものです。

input[type="checkbox"]

input[type="checkbox"] {
  inline-size: var(--space-sm);
  block-size: var(--space-sm);
}

これらのスタイルは、スペーシング セットの値を使用してチェックボックスのサイズを大きくします。

お試しください

  1. Chrome デベロッパー ツールを開き、[要素] パネルの HTML でグリッド バッジを見つけます。クリックするとデバッグツールがオンになります。
  2. Chrome デベロッパー ツールを開き、[スタイル] ペインのギャップにカーソルを合わせます。
  3. Chrome デベロッパー ツールを開き、[スタイル] ペインに移動して、[スタイル] から [レイアウト] に切り替えます。設定を切り替えたり、レイアウトをオンにしたりして、この領域を調べてみましょう。

メディアクエリ

次の CSS は、ビューポートのサイズと向きに基づいてスタイルを調整し、間隔や配置を最適化することを目的としています。ビューポートのコンテキストを考慮して、最適な状態にします。

<main>

@media (min-width: 540px) {
  main {
    padding: var(--space-lg);
  }
}

@media (min-width: 800px) {
  main {
    padding: var(--space-xl);
  }
}

これらの 2 つのメディアクエリは、ビューポートのスペースが広くなるほど main のパディングを大きくします。つまり、最初はコンパクトでパディングが少ない状態ですが、スペースが空くにつれて広くなっていきます。

<form>

form {
  --repeat: auto-fit;
  grid-template-columns: 
    repeat(var(--repeat), minmax(min(10ch, 100%), 35ch));
}

@media (orientation: landscape) and (min-width: 640px) {
  form {
    --repeat: 2;
  }
}

フォームは auto-fit でビューポート サイズにすでにレスポンシブに対応していましたが、モバイル デバイスでテストしたところ、デバイスを横向きにしても 2 つのフォーム グループが横並びになりませんでした。orientation メディアクエリとビューポート幅のチェックを使用して、この横向きのコンテキストに適応します。デバイスが横向きで、幅が 640 ピクセル以上の場合、auto-fit キーワードではなく数値を --repeat カスタム プロパティに切り替えて、2 列を強制します。

.fieldset-item

@media (min-width: 540px) {
  .fieldset-item {
    grid-template-columns: var(--space-xxl) 1fr;
    gap: var(--space-xs);
    padding: var(--space-md) var(--space-xl) var(--space-md) 0;
  }
}

このメディアクエリは、ビューポートのスペースがより多く利用できる場合の別のスペーシング拡張です。グリッド テンプレートでは、テンプレート内の大きなカスタム プロパティ(var(--space-xxl))を使用して最初の列が拡大されます。パディングは、より大きなカスタム プロパティにも適用されます。

お試しください

  1. ブラウザを拡大縮小すると、スペースが調整されます。
  2. モバイル デバイスでプレビューする
  3. モバイル デバイスで横向きでプレビューする

5. アダプティブ カラー

Git ブランチ: colors

このセクションを終えると、設定フォームは次のようになります。

  • ダークモードとライトモードの好みに適応
  • ブランドの 16 進数から派生したカラーパターンがある
  • アクセシブルな色を使用する

19e9b707348ace4c.png

HSL

次のセクションでは、HSL を使用してカラーシステムを作成し、ライトモードとダークモードのテーマを作成します。これは、CSS のコアコンセプトである calc() に基づいています。

HSL は、色相(Hue)、彩度(Saturation)、明度(Lightness)の略です。色相は時計の針のような角度で、彩度と明度はパーセンテージです。calc() は、パーセンテージと角度の計算を行うことができます。CSS でこれらのパーセンテージに対して明度と彩度の計算を行うことができます。カラーチャンネルの計算とカスタム プロパティを組み合わせると、バリエーションがベースカラーから計算されるモダンで動的なカラーパターンが実現します。これにより、コード内で多数の色を管理する必要がなくなります。

5300e908c0c33d7.png

カスタム プロパティ

このセクションでは、残りのスタイルで使用するカスタム プロパティのセットを構築します。:root タグで設定したスペーシングと同様に、色を追加します。

アプリのブランドカラーが #0af であるとします。最初のタスクは、この 16 進数色コード hsl(200 100% 50%) を HSL 色コードに変換することです。この変換により、ブランドのカラーチャンネルが HSL で明らかになります。この HSL を calc() で使用して、さまざまなサポート ブランドカラーを計算できます。

このセクションの次の各コードブロックは、同じ :root セレクタに追加する必要があります。

ブランド チャンネル

:root {
  --hue: 200;
  --saturation: 100%;
  --lightness: 50%;
}

3 つの HSL チャネルが抽出され、独自のカスタム プロパティに配置されています。

  1. 3 つのプロパティをそのまま使用して、ブランドカラーを再作成します。

ブランド

:root {
  --brand: hsl(
    var(--hue) 
    calc(var(--saturation) / 2)
    var(--lightness) 
  );
}

カラーパターンはデフォルトで暗いため、暗いサーフェスで使用する色を彩度を下げることをおすすめします(そうしないと、目がチカチカしたり、アクセスできなくなったりする可能性があります)。ブランドカラーの彩度を下げるには、色相と明度をそのまま使用し、彩度を calc(var(--saturation) / 2) で半分に減らします。これで、ブランドカラーがテーマに正しく反映され、使用できるように彩度が下げられました。

テキスト

:root {
  --text1: hsl(var(--hue) 15% 85%);
  --text2: hsl(var(--hue) 15% 65%);
}

ダークモードの読み取りテキストでは、ブランドの色相をベースとして使用しますが、そこからほぼ白の色を構築します。多くのユーザーはテキストが白だと思っているでしょうが、実際には非常に薄い青です。色相を維持することは、デザインの調和を生み出す強力な方法です。--text1 は 85% が白で、--text2 は 65% が白であり、どちらも彩度が非常に低くなっています。

  1. コードをプロジェクトに追加したら、Chrome デベロッパー ツールを開いて、これらのチャネル値の変更を試してみます。HSL とそのチャンネルがどのように相互作用するかを体感してください。好みに合わせて彩度を調整できます。

Surface

:root {
  --surface1: hsl(var(--hue) 10% 10%);
  --surface2: hsl(var(--hue) 10% 15%);
  --surface3: hsl(var(--hue) 5% 20%);
  --surface4: hsl(var(--hue) 5% 25%);
}

ダークモードではサーフェスが暗くなるため、テキストは非常に明るくなります。テキストの色で高い明度値(85% 以上)が使用されていた場合、サーフェスでは低い値(30% 以下)が使用されます。サーフェスとテキストの明度の範囲に適切な差を設けることで、ユーザーが読みやすいアクセシブルな色を確保できます。

  1. 色が、明度 10%、彩度 10% の最も暗いグレーから始まり、明るくなるにつれて彩度が下がっていることに注目してください。新しいサーフェスは、それぞれ前のサーフェスより 5% 軽くなっています。明るい面では彩度も少し低下しています。サーフェスの彩度をすべて 10% にしてみてください。気に入りましたか?

ライトモード

ダークモードを指定するテキストとサーフェスの健全な色のセットが用意できたら、prefers-color-scheme メディアクエリ内のカスタム プロパティの色を更新して、ライトモードの優先設定に対応します。

サーフェスとテキストの色との明度値の差を大きく保つという同じ手法を使用して、色のコントラストを保ちます。

ブランド

@media (prefers-color-scheme: light) {
  :root {
    --brand: hsl(
      var(--hue) 
      var(--saturation)
      var(--lightness) 
    );
  }
}

まず、ブランドカラーについて説明します。彩度を最大まで復元する必要があります。

テキスト

@media (prefers-color-scheme: light) {
  :root {
    --text1: hsl(
      var(--hue) 
      var(--saturation)
      10% 
    );

    --text2: hsl(
      var(--hue) 
      calc(var(--saturation) / 2)
      30%
    );
  }
}

ダークモードではテキストの色が非常に明るい青でしたが、ライトモードではテキストの色が非常に暗い青になっています。HSL カラーの明度値が 10% と 30% の場合、これらの色は暗いことを示しています。

Surface

@media (prefers-color-scheme: light) {
  :root {
    --surface1: hsl(var(--hue) 20% 90%);
    --surface2: hsl(var(--hue) 10% 99%);
    --surface3: hsl(var(--hue) 10% 96%);
    --surface4: hsl(var(--hue) 10% 85%);
  }
}

これらの表面の色は、最初にパターンを破ります。これまでかなり合理的で線形に見えていたものが、壊れてしまいました。HSL ライトモードの色の組み合わせをコード内で試して、明るさと彩度を調整し、クールすぎたり青すぎたりしない、素敵なライトカラーのカラーパターンを作成できるのがメリットです。

カラーシステムを使用する

色を定義したので、それらを使用します。ブランドのアクセント カラー、2 つのテキストカラー、4 つのサーフェス カラーが設定されています。

  • 次のコード セクションで、一致するセレクタを見つけて、既存のコードブロックに色の CSS を追加します。

<body>

body {
  background: var(--surface1);
  color: var(--text1);
}

ページのプライマリ カラーは、最初に作成したサーフェスとテキストの色です。これにより、デフォルトのコントラスト量が最大になります。ライトモードとダークモードの切り替えのテストを開始できます。

<fieldset>

fieldset {
  border: 1px solid var(--surface4);
  background: var(--surface4);
}

これは、デザインのカードのような要素です。1 ピクセルの枠線と 1 ピクセルのギャップは同じ色で、各 .fieldset-item の背後にあるサーフェスを表します。これにより、視覚的な調和が生まれ、メンテナンスも容易になります。

.fieldset-item

.fieldset-item {
  background: var(--surface3);
}

各フォーム入力は独自のサーフェスにあります。これらの要素がどのように組み合わされ、明度のバリエーションがどのように重ね合わされているか、ご理解いただけたでしょうか。

.fieldset-item > picture

.fieldset-item > picture {
  background: var(--surface4);
}

これは、アイコンを囲む円形を強調するためのスタイルの選択です。次のセクションでインタラクションを追加すると、その理由が明らかになります。

.fieldset-item svg

.fieldset-item svg {
  fill: var(--text2);
}

フォーム内のアイコンは、代替テキスト --text2 を使用するように設定されています。塗りつぶしアイコンがテキストよりもわずかに明るいデザインにすると、重すぎる印象を避けることができます。

.fieldset-item:focus-within svg

.fieldset-item:focus-within svg {
  fill: var(--brand);
}

このセレクタは、内部の入力のいずれかが操作されているときに入力コンテナ要素と一致し、SVG をターゲットにしてブランド アクセントでハイライト表示します。これにより、フォームの UX フィードバックが向上し、入力欄を操作すると関連するアイコンがハイライト表示されます。

<small>

small {
  color: var(--text2);
}

テキストが小さい。見出しや段落(メイン コンテンツ)と比較して、少し控えめにする必要があります。

ダーク フォーム コントロール

:root {
  color-scheme: dark light;
}

この最後の仕上げにより、このページがダークモードとライトモードの両方をサポートしていることをブラウザに伝えることができます。ブラウザは、ダークモードのフォーム コントロールで応答します。

6. アダプティブ アニメーション

Git ブランチ: animations

このセクションを終えると、設定ページは次のようになります。

  • ユーザーのモーション設定に適応する
  • ユーザー インタラクションに応答する

b23792cdf4cc20d2.gif

モーション抑制とモーションなし

オペレーティング システムで見つかったモーションのユーザー設定に、アニメーションなしの値がありません。モーションを減らすオプションです。クロスフェード アニメーションや色の遷移などは、モーションの低減を好むユーザーにとって依然として望ましいものです。

この設定ページでは、画面間の移動という点では動きはあまりありません。要素がユーザーに向かって移動しているかのように、スケール効果が適用されます。CSS コードを調整してモーションの縮小に対応するのは簡単なので、スケーリングのトランジションを減らします。

インタラクション スタイル

<fieldset>

fieldset {
  transition: box-shadow .3s ease;
}

fieldset:focus-within {
  box-shadow: 0 5px 20px -10px hsl(0 0% 0% / 50%);
}

ユーザーが <fieldset> カードのような要素の入力欄を操作しているときに、リフティング効果を追加します。インターフェースが要素を前に押し出し、コンテキスト フォーム グループがユーザーに向かってくるにつれて、ユーザーがフォーカスしやすくなるようにしています。

.fieldset-item

.fieldset-item {
  transition: background .2s ease;
}

.fieldset-item:focus-within {
  background: var(--surface2);
}

ユーザーが入力とやり取りしているとき、特定のアイテムレイヤの背景がハイライト表示されたサーフェス色に変化します。これは、ユーザーの注意を引き、入力が受信されていることを示すための、もう 1 つのサポート インターフェース機能です。ほとんどの場合、色の切り替えを減らす必要はありません。

.fieldset-item > picture

@media (prefers-reduced-motion: no-preference) {
  .fieldset-item > picture {
    clip-path: circle(40%);
    transition: clip-path .3s ease;
  }

  .fieldset-item:focus-within picture {
    clip-path: circle(50%);
  }
}

ユーザーがモーションの低減に関する設定を行っていない場合にのみ使用する clip-path アニメーションを次に示します。最初のセレクタとスタイルは、円形のクリップパスを 10% 縮小し、いくつかのトランジション パラメータを設定します。2 つ目のセレクタとスタイルは、ユーザーが入力とやり取りするのを待ってから、アイコンの円を拡大します。問題がない場合は、さりげなく効果を発揮します。

7. 完了

Git ブランチ: complete

お疲れさまでした。これで、ユーザー適応型インターフェースを構築できました。

ここでは、さまざまなユーザー シナリオや設定に対応するインターフェースを作成するために必要な主な手順について確認しました。