1. 始める前に

最近では、ユーザーはデバイスで多くの設定を指定しています。オペレーティング システムやアプリを自分好みにカスタマイズしたいと考えています。ユーザー適応型インターフェースとは、これらの設定を使用してユーザー エクスペリエンスを向上させ、ユーザーが自宅にいるかのように、自分のもののように感じられるようにするインターフェースです。正しく行われていれば、ユーザーはユーザー エクスペリエンスが適応していることや適応したことに気づかないかもしれません。
ユーザー設定
デバイスのハードウェアの選択は設定、オペレーティング システムは選択、アプリとオペレーティング システムの色は設定、アプリとオペレーティング システムのドキュメントの言語は設定です。ユーザーの好みは増える一方のようです。ウェブページはすべてにアクセスできるわけではありません。それにはもっともな理由があります。
CSS で使用できるユーザー設定の例をいくつかご紹介します。
- デバイスのビューポートのサイズ
- デバイスの向き(縦向き | 横向き)
- フォントサイズ
- オンライン / オフライン
- ネットワークの品質
- カラーパターン(ライト | ダーク)
- インターフェースのアニメーション(オン | 軽減)
- 入力の質(マウス | タッチ | タッチペン)
- ドキュメントの方向と書き込みモード(左から右、上から下など)
- 表示モード(全画面表示 | スタンドアロン | 最小限の UI | ブラウザ)
CSS に近日公開のユーザー設定の例をいくつかご紹介します。
メディアクエリ
CSS とウェブでは、メディアクエリ(条件が true の場合に一連のスタイルを含む宣言型の条件)を使用して、適応性とレスポンシブ性を実現できます。最も一般的なのは、デバイスのビューポート サイズに関する条件です。サイズが 800 ピクセル未満の場合、そのケースに適したスタイルが適用されます。
ユーザー適応型
適応性のないインターフェースとは、ユーザーがアクセスしても何も変化せず、基本的にすべてのユーザーに同じエクスペリエンスを提供し、調整できないものです。ユーザー適応型インターフェースでは、5 人の異なるユーザーに対して 5 つの異なる外観とスタイルを設定できます。機能は同じですが、UI を調整できるユーザーにとっては、見た目が良く、インターフェースのユーザビリティが向上します。
前提条件
- HTML と CSS の知識
- Google Chrome デベロッパー ツールなどのデベロッパー ツールに関する知識
作成するアプリの概要
この Codelab では、以下に適応するユーザー適応型フォームを作成します。
- フォーム コントロールと周囲の UI 要素にライト カラーパターンとダーク カラーパターンを提供することで、システムのカラーパターン設定
- 複数の種類のアニメーションを提供することで、システムのモーション設定をサポートする
- モバイルとデスクトップのエクスペリエンスを提供する、小型デバイスと大型デバイスのビューポート
- キーボード、スクリーン リーダー、タッチ、マウスなど、さまざまな入力タイプ
- 任意の言語と読み取り / 書き込みモード

学習内容
この Codelab では、ユーザーに適応するフォームの作成に役立つ最新のウェブ機能について学びます。次の方法について学びます。
- ライトモードとダークモードを作成する
- アニメーション付きのアクセスしやすいフォームを作成する
- レイアウト レスポンシブ フォーム
- 相対単位と論理プロパティを使用する

この Codelab では、ユーザー アダプティブ インターフェースに焦点を当てています。関連のない概念やコードブロックについては詳しく触れず、コードはコピーして貼るだけの状態で提供されています。
必要なもの
- Google Chrome 89 以降、またはお好みのブラウザ

2. セットアップする
コードを取得する
このプロジェクトに必要なすべてのコードは GitHub リポジトリにあります。まず、コードを取得して、お好みの開発環境で開く必要があります。または、この Codepen をフォークして、そこから作業することもできます。
推奨: Codepen を使用する
- 新しいブラウザタブを開きます。
- https://codepen.io/argyleink/pen/abBMeeq にアクセスします。
- アカウントをお持ちでない場合は、アカウントを作成して作業を保存してください。
- [Fork] をクリックします。
代替手段: ローカルで作業する
コードをダウンロードしてローカルで作業する場合は、Node.js バージョン 12 以降と、コードエディタをセットアップして準備しておく必要があります。
Git を使用する
- https://github.com/argyleink/Google-IO-2021-Workshop_User-Adaptive-Interfaces にアクセスします。
- リポジトリのクローンをフォルダに作成します。
- デフォルトのブランチは
beginningです。
ファイルを使用する
- ダウンロードした zip ファイルをフォルダに解凍します。
プロジェクトを実行する
上記の手順のいずれかで作成したプロジェクト ディレクトリを使用して、次の操作を行います。
npm installを実行して、サーバーの実行に必要な依存関係をインストールします。npm startを実行して、ポート 3000 でサーバーを起動します。- 新しいブラウザタブを開きます。
- http://localhost:3000 にアクセスします。
HTML について
このレッスンでは、ユーザー適応型のインタラクティビティをサポートするために使用される HTML の側面について説明します。このワークショップでは、CSS に焦点を当てています。提供されている HTML は、フォームやウェブサイトの作成に慣れていない場合に確認する価値があります。HTML 要素の選択は、ユーザー補助とレイアウトにとって重要です。
準備ができたら、このスケルトンを動的で適応性のあるユーザー エクスペリエンスに変換します。

3. アダプティブ インタラクション
Git ブランチ: beginning
このセクションの終わりには、設定フォームが次の状態に適応するようになります。
- ゲームパッド + キーボード
- マウス + タッチ
- スクリーン リーダーまたは同様の支援技術
HTML の属性
ソースコードで提供されている HTML は、フォーム入力のグループ化、順序付け、ラベル付けに役立つセマンティック要素がすでに選択されているため、出発点として最適です。
フォームはビジネスにとって重要なインタラクション ポイントとなることが多いため、ウェブで容易にできるさまざまな種類の入力に対応できることが重要です。たとえば、モバイルでタッチ操作で使用できるフォームを用意することが重要です。このセクションでは、レイアウトとスタイルを適用する前に、アダプティブ入力のユーザビリティを確保します。
入力のグループ化
HTML の <fieldset> 要素は、類似する入力とコントロールをグループ化するためのものです。フォームには、音量用と通知用の 2 つのグループがあります。これはユーザー エクスペリエンスにとって重要であり、セクション全体をスキップできます。
要素の順序付け
要素の順序は論理的な順序で指定します。これはユーザー エクスペリエンスにとって重要であり、ゲームパッド、キーボード、スクリーン リーダーのテクノロジーで視覚的なエクスペリエンスの順序が同じか、類似したものになります。
キーボード操作
ウェブユーザーは、Tab キーを使用してフォーム内を移動することに慣れています。幸いなことに、想定される HTML 要素を指定すれば、ブラウザがこの処理を行います。<button>、<input>、<h2>、<label> などの要素を使用すると、自動的にキーボードまたはスクリーン リーダーの移動先になります。

上の動画では、Tab キーと矢印キーを使用してインターフェースを移動し、変更を加える方法を説明しています。ただし、青いアウトラインは入力要素の周囲に非常に密接しているため、次のスタイルを追加して、このインタラクションに少し余裕を持たせます。
style.css
input {
outline-offset: 5px;
}
おすすめの方法
index.htmlで使用されている HTML 要素を確認します。- ブラウザでデモページをクリックします。
tabキーとshift+tabキーを押して、フォーム内の要素にフォーカスを移動します。- キーボードを使用して、スライダーとチェックボックスの値を変更します。
- Bluetooth ゲームパッド コントローラを接続し、フォーム内で要素のフォーカスを移動します。
マウス操作
ウェブユーザーは、マウスでフォームを操作することに慣れています。フォームでマウスを使用してみてください。スライダーとチェックボックスは機能しますが、さらに改善できます。これらのチェックボックスは、マウスでクリックするにはかなり小さいです。

ラベルとその入力を接続するための 2 つのユーザー エクスペリエンス機能が表示されます。
1 つ目の機能は、操作対象のオプションがあることです。ラベルは、小さな正方形よりもマウスでターゲットにしやすいです。
2 つ目の機能は、ラベルがどの入力に対応しているかを正確に把握することです。現時点では、CSS がないと、いくつかの属性を指定しない限り、どのラベルがどのチェックボックスに対応しているかを判断するのは非常に困難です。
この明示的な接続により、スクリーン リーダーの操作性も向上します。これについては次のセクションで説明します。
関連付けなし: 要素を接続する属性がない
<input type="checkbox">
<label>...</label>
関連付け: 要素を接続する属性
<input type="checkbox" id="voice-notifications" name="voice-notifications">
<label for="voice-notifications">...</label>
提供された HTML には、すべての入力とラベルがすでに属性として設定されています。このコンセプトを初めて知った方は、さらに詳しく調べることをおすすめします。
おすすめの方法
- ラベルにカーソルを合わせると、チェックボックスがハイライト表示されます。
- Chrome デベロッパー ツールでラベル要素を調査し、チェックボックスを選択できるクリック可能なサーフェス領域を可視化します。
スクリーン リーダーの操作
支援技術はこのフォームとやり取りでき、いくつかの HTML 属性を使用することで、ユーザー エクスペリエンスをよりスムーズにできます。

Chrome でスクリーン リーダーを使用して現在のフォームを操作しているユーザーは、<picture> 要素で不要な停止が発生します(Chrome 固有ではありません)。スクリーン リーダーを使用しているユーザーは、視覚障がいがあるためにスクリーン リーダーを使用している可能性が高いため、画像で停止しても役に立ちません。属性を使用して、スクリーン リーダーから要素を非表示にできます。
index.html
<picture aria-hidden="true">
これで、スクリーン リーダーは純粋に視覚的な要素を無視するようになります。

スライダー要素 input[type="range"] には、特別な ARIA 属性 aria-labelledby="media-volume" があります。これにより、スクリーン リーダーがユーザー エクスペリエンスを向上させるための特別な指示が提供されます。
おすすめの方法
- オペレーティング システムのスクリーン リーダー テクノロジーを使用して、フォーム内でフォーカスを移動します。
- スクリーン リーダー ソフトウェアをダウンロードして、フォームで試してみます。
4. アダプティブ レイアウト
Git ブランチ: layouts
このセクションを終えると、設定ページは次のようになります。
- カスタム プロパティとユーザーの相対単位を使用して間隔システムを作成する
- 柔軟でレスポンシブな配置と間隔を実現する CSS グリッドを作成する
- 国際的に適応可能なレイアウトには論理プロパティを使用する
- メディアクエリを記述して、コンパクトなレイアウトと広々としたレイアウトを切り替える

間隔
優れたレイアウトの鍵は、限られたパレットのスペース オプションです。これにより、コンテンツが自然に配置され、調和が生まれます。
カスタム プロパティ
このワークショップは、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 単位は、適応性があり、ユーザーの好みに配慮した、読みやすい全体的な単位サイズ設定にのみ使用します。
ページスタイル
次に、ドキュメント スタイルを設定し、要素からマージンを削除して、フォントを適切な Sans Serif に設定する必要があります。
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 が必要です。そうしないと、密集しすぎてしまいます。
論理プロパティ
body の padding は、論理プロパティ(block-start、block-end)を使用して側を指定しています。この Codelab の残りの部分では、論理プロパティを幅広く使用します。rem ユニットと同様に、ユーザーに適応します。このレイアウトは別の言語に翻訳でき、ユーザーが母国語で慣れ親しんでいる自然な書き方やドキュメントの方向に設定できます。論理プロパティを使用すると、スペース、方向、配置を 1 つ定義するだけで、このサポートを実現できます。

グリッドと Flexbox はすでにフロー相対であるため、1 つの言語用に記述されたスタイルは、他の言語にもコンテキストに応じて適切に適用されます。適応型の方向性。コンテンツはドキュメントの方向性に応じて流れます。
論理プロパティを使用すると、記述するスタイルを減らしながら、より多くのユーザーにリーチできます。
CSS グリッド レイアウト
grid CSS プロパティは、複雑なタスクに取り組むための多くの機能を備えた強力なレイアウト ツールです。シンプルなグリッド レイアウトをいくつか作成し、複雑なレイアウトを 1 つ作成します。また、マクロ レイアウトからミクロ レイアウトまで、外側から内側に向かって作業します。間隔のカスタム プロパティは、パディングやマージンの値だけでなく、列サイズ、枠線の半径などにも重要になります。
以下は、Chrome DevTools で各 CSS グリッド レイアウトを一度にオーバーレイしたスクリーンショットです。

style.cssに以下の各スタイルを追加します。
<main>
main {
display: grid;
gap: var(--space-xl);
place-content: center;
padding: var(--space-sm);
}
Grid はデフォルトで、各子要素を独自の行に配置するため、要素を積み重ねるのに適しています。また、gap を使用するというメリットもあります。先ほど、* セレクタを使用してすべての要素に margin: 0 を設定しました。これは、gap を使用してスペースを調整する際に重要になります。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-itemsは、アイテムの高さを引き伸ばさないようにflex-startに設定されています。grid-template-columnsの構文は複雑ですが、目標は簡潔です。列の幅を35chに保ち、10ch未満にならないようにします。スペースがあれば列に配置し、スペースがなければ行に配置します。
- ブラウザのサイズを変更してみます。フォームが小さなビューポートでは行に折りたたまれますが、スペースがあれば新しい列にフローし、メディアクエリなしで適応します。このメディアクエリを使用しないレスポンシブ スタイルの戦略は、コンポーネントやコンテンツ中心のレイアウトに特に役立ちます。
<section>
section {
display: grid;
gap: var(--space-md);
}
各セクションは、子要素間に中程度のスペースがある行のグリッドにする必要があります。
<header>
header {
display: grid;
gap: var(--space-xxs);
}
各ヘッダーは、子要素間に非常に小さなスペースがある行のグリッドにする必要があります。
<fieldset>
fieldset {
padding: 0;
display: grid;
gap: 1px;
border-radius: var(--space-sm);
overflow: hidden;
}
このレイアウトは、カードのような外観を作成し、入力をグループ化します。overflow: hidden と gap: 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) は、アイコンよりも幅の広い列を作成するため、子要素を中央に配置する場所があります。
このレイアウトは、カスタム プロパティですでに多くの設計上の決定が行われていることを示しています。パディング、ギャップ、列はすべて、すでに定義した値を使用して、システムの調和を保ちながらサイズが設定されました。
<picture> の .fieldset-item
.fieldset-item > picture {
block-size: var(--space-xl);
inline-size: var(--space-xl);
clip-path: circle(50%);
display: inline-grid;
place-content: center;
}
このレイアウトは、設定、アイコンの円のサイズ、円形の作成、円形内での画像の中央揃えを担います。
画像>&[checkbox] 配置" id="picture-[checkbox]-alignment" is-upgraded="" tabindex="-1"><画像> と [チェックボックス] の配置
.fieldset-item > :is(picture, input[type="checkbox"]) {
place-self: center;
}
このレイアウトでは、:is 疑似セレクタを使用して、画像要素とチェックボックス要素を中央に配置しています。
- 次のように、セレクタ
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);
}
これらのスタイルは、間隔セットの値を使用してチェックボックスのサイズを大きくします。
おすすめの方法
- Chrome デベロッパー ツールを開き、[要素] パネルの HTML でグリッドバッジを見つけます。クリックすると、デバッグツールが有効になります。
- Chrome デベロッパー ツールを開き、[スタイル] ペインで gap にカーソルを合わせます。
- Chrome デベロッパー ツールを開き、[Styles] ペインに移動して、[Styles] から [Layouts] に切り替えます。設定を切り替えてレイアウトを有効にすることで、この領域を探索できます。
メディアクエリ
次の 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 ピクセル以上の場合、--repeat カスタム プロパティを auto-fit キーワードではなく数値に切り替えて、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;
}
}
このメディアクエリは、ビューポートのスペースがさらに利用可能な場合の、もう 1 つの間隔の拡張です。グリッド テンプレートは、テンプレート内のより大きなカスタム プロパティ(var(--space-xxl))を使用して最初の列を拡張します。パディングは、より大きなカスタム プロパティにも適用されます。
おすすめの方法
- ブラウザを拡大または縮小して、スペースがどのように調整されるかを確認します。
- モバイル デバイスでプレビューする
- モバイル デバイスで横向きにプレビューする
5. アダプティブ カラー
Git ブランチ: colors
このセクションを終えると、設定フォームは次のようになります。
- ダークモードとライトモードの好みに適応する
- ブランドの 16 進数コードから派生したカラーパターンを使用する
- アクセシブルな色を使用する

HSL
次のセクションでは、HSL を使用してカラーシステムを作成し、ライトモードとダークモードを作成できるようにします。これは、CSS のコアコンセプトである calc() に基づいています。
HSL は、色相(Hue)、彩度(Saturation)、輝度(Lightness)の略です。色相は時計の針のような角度で、彩度と明度はパーセンテージで表されます。calc() は、パーセンテージと角度の計算を行うことができます。CSS で、これらの割合に対して明度と彩度の計算を行うことができます。カラー チャンネルの計算をカスタム プロパティと組み合わせると、ベースカラーからバリエーションが計算される、モダンでダイナミックなカラーパターンが実現します。これにより、コードで多数の色を管理する必要がなくなります。

カスタム プロパティ
このセクションでは、残りのスタイルで使用する一連のカスタム プロパティを作成します。先ほど :root タグで作成した間隔セットと同様に、色を追加します。
アプリのブランドカラーが #0af であるとします。最初のタスクは、この 16 進数色コード hsl(200 100% 50%) を HSL 色コードに変換することです。この変換により、ブランドのカラー チャンネルが HSL で表示されます。これに calc() を使用して、さまざまなサポート ブランドカラーを計算できます。
このセクションの次の各コードブロックは、同じ :root セレクタに追加する必要があります。
ブランド チャンネル
:root {
--hue: 200;
--saturation: 100%;
--lightness: 50%;
}
3 つの HSL チャンネルが抽出され、独自のカスタム プロパティに配置されています。
- 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% の白で、どちらも彩度が非常に低くなっています。
- プロジェクトにコードを追加したら、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% 以下)を使用します。サーフェスとテキストの明度範囲の間に適切な幅を設けることで、ユーザーが読みやすい色を確保できます。
- 色は、明度 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
このセクションを終えると、設定ページは次のようになります。
- ユーザーのモーション設定に適応する
- ユーザー インタラクションに応答する

モーションの抑制とモーションなしの比較
オペレーティング システムで見つかったモーションに関するユーザー設定に、アニメーションなしの値がありません。このオプションは、動きを軽減するためのものです。クロスフェード アニメーションや色の遷移などは、動きを抑えたいユーザーにとっても望ましいものです。
この設定ページでは、画面全体にわたる動きはあまりありません。このモーションは、要素がユーザーに向かって移動しているかのような、スケール効果に近いものです。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);
}
ユーザーが入力項目を操作しているとき、特定のアイテムレイヤの背景がハイライト表示されたサーフェス色に変わります。これは、ユーザーの注意を引き、入力が受け付けられていることを示すための、もう一つの補助的なインターフェース機能です。ほとんどの場合、色の遷移を減らす必要はありません。
.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
これで、ユーザー適応型インターフェースを構築できました。
さまざまなユーザー シナリオや設定に適応するインターフェースを作成するために必要な主な手順について確認しました。