カラーパターンを作成する

動的で構成可能なカラーパターンを確立する方法の基本的な概要

この投稿では、CSS で複数のカラーパターンを管理する方法についてご説明します。デモをお試しください

デモ

動画をご覧になる場合は、この投稿の YouTube バージョンをご覧ください。

概要

カスタム プロパティと calc() を使用してアクセシビリティの高いカラーシステムを構築し、ユーザーの好みに合わせて調整できるウェブページを作成し、オーサリング エクスペリエンスを最小限に抑えます。ベースとなるブランドカラーから始め、それから 2 つのテキスト色、4 つのサーフェス色、対応するシャドウというバリエーションのシステムを構築します。

このガイドでは、まず各カラーパターンのすべての色を定義します。最後のまでは、ユーザーはページを変更するために使いません。

ブランド

多くの場合、ブランドカラーはすでに確立されており、16 進数または RGB として提供されます。この GUI チャレンジのベース ブランドカラーは #0af です。まず、このカラーシステムでは、16 進数値を hsl に変換する必要があります。

* {
  --brand: #0af;
  --brand: hsl(200 100% 50%);
}

ブランドカラーを(たとえば 20%)暗くまたは明るくするコンセプトを実現するには、次のように、HSL カラー値の 3 つのチャネルを独自のカスタム プロパティに抽出する必要があります。

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

CSS では、これらの色プロパティに対して計算を行うことができます。たとえば、calc(var(--brand-lightness) - 20%) で明度の値を 20% 減らすことができます。CSS は hsl の彩度と明度を調整することですべての色を同じ色相ファミリーに維持できるため、これがカラーパターンの作成の基礎となります。

ライトモード

色のバリエーションはそれぞれ対応するスキームでマークされます。この場合は、それぞれに -light が付加されます。

ライトモードの最終結果のプレビュー

ブランド

ブランドカラーから始めて、--brand-hue--brand-saturation--brand-lightness のカスタム プロパティを hsl の () 関数のかっこで囲み、計算を行わずに再ビルドします。

* {
  --brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
}

テキストの色

次に、カラーパターンの必須要素として、テキストの色が必要です。ライトモードでは テキストは非常に暗くなります以下の色の明度は低く、50% を大きく下回っています。

* {
  --text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
  --text2-light: hsl(var(--brand-hue) 30% 30%);
}

--text1-light: 10% の明度で非常に暗いため、強めの 100% の彩度を維持して、ブランドカラーがダークなダークネイビーまで透けて見えるようにします。

--text2-light は、1 番目の色ほど暗くありません。セカンダリ カラーとして優れているだけでなく、彩度もはるかに低くなります。

サーフェスの色

サーフェスの色は、テキストが上または中に配置される背景、境界、その他の装飾サーフェスです。ライトモードでは、これらは暗いテキスト色ではなく、明るい色になります。HSL で明るい色を作成するには、3 つ目の明度の値に高いパーセンテージ値を使用します。また、ライトグレーの色合いが悪くならないようにするため、彩度を低くします。

* {
  --surface1-light: hsl(var(--brand-hue) 25% 90%);
  --surface2-light: hsl(var(--brand-hue) 20% 99%);
  --surface3-light: hsl(var(--brand-hue) 20% 92%);
  --surface4-light: hsl(var(--brand-hue) 20% 85%);
}

:focus:hover などのインタラクティブな瞬間や紙レイヤの外観を作成するために、装飾色ではより多くのバリアントが必要になる傾向があるため、4 つのサーフェス色が作成されました。このようなシナリオでは、カーソルを合わせたときに --surface2-light--surface3-light に移行すると、コントラストが高くなります(明度 99% から明度 92%、暗くなります)。

カラーパターン内のシャドウはより大きくなりますが、効果にリアルな性質が加わり、非現実的な黒ベースのシャドウよりも目立ちます。そのために、シャドウの色はカスタム プロパティである hue を使用します。これは、色相でわずかに彩度があっても非常に暗くなります。非常に濃い青の影になります

* {
  --surface-shadow-light: var(--brand-hue) 10% 20%;
  --shadow-strength-light: .02;
}

--surface-shadow-light は hsl 関数でラップされていません。これは、--shadow-strength 値を組み合わせて不透明度を増すため、CSS で計算を行うために各要素が必要になるためです。詳細については、放射シャドウのセクションに進んでください。

さまざまな色の組み合わせ

光の色がどのように作られているかを調べる必要はありません。すべての色が CSS の 1 か所にまとめられています。

* {
  --brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
  --text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
  --text2-light: hsl(var(--brand-hue) 30% 30%);
  --surface1-light: hsl(var(--brand-hue) 25% 90%);
  --surface2-light: hsl(var(--brand-hue) 20% 99%);
  --surface3-light: hsl(var(--brand-hue) 20% 92%);
  --surface4-light: hsl(var(--brand-hue) 20% 85%);
  --surface-shadow-light: var(--brand-hue) 10% calc(var(--brand-lightness) / 5);
  --shadow-strength-light: .02;
}
ライトの色をすべて合わせた状態のスクリーンショット
CodePen のサンドボックス

ダークモード

ほとんどのブランドはダークモードから始めるのではなく、メインの(通常は明るい)テーマのバリエーションです。一方、ユーザーは夜間など、さまざまなコンテキストでダークモードを選択することがよくあります。こうした要因から、ダークモードでは次の 2 つの点を念頭に置くことにしました。

  1. 通常、このテーマを使用しているユーザーは暗い場所にいるため、暗い場所でテストしてください。
  2. 過度な強さが原因で画面が振動しないように、色の彩度を下げる必要があります。

ダークモードの最終結果のプレビュー

ブランド

ライトモードでは 3 つのブランドの HSL カラーチャネルの値をそのまま使用しましたが、ダークモードでは使用していません。彩度は半分に、明度は相対的に 50% 低減されます。

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

テキストの色

ダークモードでは、テキストの色は明るい色にする必要があります。以下の色は明度の値が高く、白に近い色です。

* {
  --text1-dark: hsl(var(--brand-hue) 15% 85%);
  --text2-dark: hsl(var(--brand-hue) 5% 65%);
}

サーフェスの色

ダークモードでは、サーフェスの色を暗くする必要があります。以下の色は明度と彩度が低く、最初のサーフェスは 10% で最も暗くなっています。

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

ダークモードでは、シャドウがとても見にくくなります。かなり暗いものを暗くするのは難しいので 理にかなっていますここで役立つのが --shadow-strength-dark です。変数を 1 つ変更するだけでシャドウを暗くできます。

* {
  --surface-shadow-dark: var(--brand-hue) 50% 3%;
  --shadow-strength-dark: .8;
}

また、その影の彩度を確認します。インターフェースを見たとき 色はわかりますか?DevTools から彩度を削除してみてください。どちらがよいですか?

ダークカラーがすべて揃う

* {
  --brand-dark: hsl(var(--brand-hue) calc(var(--brand-saturation) / 2) calc(var(--brand-lightness) / 1.5));
  --text1-dark: hsl(var(--brand-hue) 15% 85%);
  --text2-dark: hsl(var(--brand-hue) 5% 65%);
  --surface1-dark: hsl(var(--brand-hue) 10% 10%);
  --surface2-dark: hsl(var(--brand-hue) 10% 15%);
  --surface3-dark: hsl(var(--brand-hue) 5%  20%);
  --surface4-dark: hsl(var(--brand-hue) 5% 25%);
  --surface-shadow-dark: var(--brand-hue) 50% 3%;
  --shadow-strength-dark: .8;
}
暗い色をすべて合わせた状態のスクリーンショット
CodePen のサンドボックス

モードを暗くする

このカラーパターンでは、明度と彩度をオーケストレートしています。色相を表示するのに十分な彩度が必要ですが、いずれにせよ、暗めと低コントラストになることが目的であるため、コントラスト スコアをほとんど合格しません。

薄暗いテーマから得られた最終結果のプレビュー

ブランド

* {
  --brand-dim: hsl(
    var(--brand-hue)
    calc(var(--brand-saturation) / 1.25)
    calc(var(--brand-lightness) / 1.25)
  );
}

テキストの色

* {
  --text1-dim: hsl(var(--brand-hue) 15% 75%);
  --text2-dim: hsl(var(--brand-hue) 10% 61%);
}

サーフェスの色

* {
  --surface1-dim: hsl(var(--brand-hue) 10% 20%);
  --surface2-dim: hsl(var(--brand-hue) 10% 25%);
  --surface3-dim: hsl(var(--brand-hue) 5%  30%);
  --surface4-dim: hsl(var(--brand-hue) 5% 35%);
}

* {
  --surface-shadow-dim: var(--brand-hue) 30% 13%;
  --shadow-strength-dim: .2;
}

すべての色を暗くする

* {
  --brand-dim: hsl(var(--brand-hue) calc(var(--brand-saturation) / 1.25) calc(var(--brand-lightness) / 1.25));
  --text1-dim: hsl(var(--brand-hue) 15% 75%);
  --text2-dim: hsl(var(--brand-hue) 10% 61%);
  --surface1-dim: hsl(var(--brand-hue) 10% 20%);
  --surface2-dim: hsl(var(--brand-hue) 10% 25%);
  --surface3-dim: hsl(var(--brand-hue) 5%  30%);
  --surface4-dim: hsl(var(--brand-hue) 5% 35%);
  --surface-shadow-dim: var(--brand-hue) 30% 13%;
  --shadow-strength-dim: .2;
}
薄暗い色をすべて撮影したスクリーンショット
CodePen のサンドボックス

アクセシブルな色

暗いテキスト カラーセットの最小値は 65%、暗いサーフェスの最大値は 25% です。両者の間には 40% の明るさがありますライトモードのライトモードには 55% の余白があります。テキストの色とサーフェスの色の明度の違いを 40 ~ 50% 程度にすることで、色のコントラスト比を高く保つことができます。また、スコアが低い場合に調整の手段にもなります。

私はこれを「Bump boost til ya pass」と呼んでいますが、これは、ツールが合格を示すまで明度の値をバンプする相互作用です。

Shift+下矢印キーを押すと、合格するまで明度を下げてコントラストを上げます

このチャレンジで作成した各テーマは、コントラスト スコアに合格します。暗めのカラーパターンはコントラストが最も低くなりますが、最小要件を満たしています。チームの他のメンバーが適切なコントラストの色を使用できるよう、サーフェスの色とアクセスしやすいテキストの色をペアにするクラス名を作成することをおすすめします。

.surface1 {
  background-color: var(--surface1);
  color: var(--text2);
}

.surface2 {
  background-color: var(--surface2);
  color: var(--text2);
}

.surface3 {
  background-color: var(--surface3);
  color: var(--text1);
}

.surface4 {
  background-color: var(--surface4);
  color: var(--text1);
}
薄暗い場所とテキストのペア設定のスクリーンショット
VisBug と薄暗いサーフェスとテキストのペアのスクリーンショット

ラッドシャドウ

テーマでは、.rad-shadow というユーティリティ クラスを使用します。このシャドウは、この [Smooth Shadow] ツールで生成したもので、とても気に入っています。生成されたスニペットを使用して、独自の色と不透明度の計算でカスタマイズしました。これは、各カラーパターン内で調整できるシャドウを作成するためです。

それぞれの影が横に並べられている

そのために、調整するカラーパターンごとにシャドウの色とシャドウの強さの 2 つの変数を作成しました。色は彩度と暗さの調整に使用し、濃度は暗いカラーパターンのシャドウの強さを簡単に上げるためのものです。最終的な結果は次のようになります。

:root {
  --surface-shadow-light: var(--brand-hue) 10% 20%;
  --shadow-strength-light: .02;
}

.rad-shadow {
  box-shadow:
    0 2.8px 2.2px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
    0 6.7px 5.3px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .01)),
    0 12.5px 10px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
    0 22.3px 17.9px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
    0 41.8px 33.4px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
    0 100px 80px hsl(var(--surface-shadow) / var(--shadow-strength))
  ;
}

カラーパターンでシャドウをさらに使用する場合は、シャドウの角度もデザイン トークンを一定にします。これは、デザインのすべてのシャドウ間で光の方向を同じにするためです。

カラーパターンの使用

色の事前定義が完了したら、次は色をスキームに依存しないプロパティに変換します。つまり、このカラーパターン プロジェクト内の CSS 作成者は、特定のカラーパターンの値にアクセスする必要はほとんどありません。テーマから逸脱しないように気をつけましょう。

これを実現するには、カラーパターンは汎用のカスタム プロパティのみを使用して行う必要があります。これについては後で定義します。これにより、デザイン変数を使用するユーザーは、現在設定されているカラーパターンを気にする必要がなくなります。サーフェスとテキストの色を使用するだけで済みます。color: var(--text1-light) の代わりに color: var(--text1) を使用します。色の適応と調整はすべて、CSS の上位レベルで行われます。

次のコードブロックでライトモードのコネクティブ スタイルを見ていきましょう。ライトモード固有の色を使用して汎用のカスタム プロパティを接続します。これで、var(--brand) のすべての使用で、ライトのブランドカラーが使用されます。

ライトモード(自動)

:root {
  color-scheme: light;
  --brand: var(--brand-light);
  --text1: var(--text1-light);
  --text2: var(--text2-light);
  --surface1: var(--surface1-light);
  --surface2: var(--surface2-light);
  --surface3: var(--surface3-light);
  --surface4: var(--surface4-light);
  --surface-shadow: var(--surface-shadow-light);
  --shadow-strength: var(--shadow-strength-light);
}

現在、サイトでライトモードが使用されています。これは非常に楽しい成功の瞬間です。 他のカラーパターンのコンテキストで事前定義済みの色を使用するので、もう少し詳しく見てみましょう。

ダークモード(自動)

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;

    --brand: var(--brand-dark);
    --text1: var(--text1-dark);
    --text2: var(--text2-dark);
    --surface1: var(--surface1-dark);
    --surface2: var(--surface2-dark);
    --surface3: var(--surface3-dark);
    --surface4: var(--surface4-dark);
    --surface-shadow: var(--surface-shadow-dark);
    --shadow-strength: var(--shadow-strength-dark);
  }
}

ライトモード

[color-scheme="light"] {
  color-scheme: light;

  --brand: var(--brand-light);
  --text1: var(--text1-light);
  --text2: var(--text2-light);
  --surface1: var(--surface1-light);
  --surface2: var(--surface2-light);
  --surface3: var(--surface3-light);
  --surface4: var(--surface4-light);
  --surface-shadow: var(--surface-shadow-light);
  --shadow-strength: var(--shadow-strength-light);
}

ダークモード

[color-scheme="dark"] {
  color-scheme: dark;

  --brand: var(--brand-dark);
  --text1: var(--text1-dark);
  --text2: var(--text2-dark);
  --surface1: var(--surface1-dark);
  --surface2: var(--surface2-dark);
  --surface3: var(--surface3-dark);
  --surface4: var(--surface4-dark);
  --surface-shadow: var(--surface-shadow-dark);
  --shadow-strength: var(--shadow-strength-dark);
}

モードを暗くする

[color-scheme="dim"] {
  color-scheme: dark;

  --brand: var(--brand-dim);
  --text1: var(--text1-dim);
  --text2: var(--text2-dim);
  --surface1: var(--surface1-dim);
  --surface2: var(--surface2-dim);
  --surface3: var(--surface3-dim);
  --surface4: var(--surface4-dim);
  --surface-shadow: var(--surface-shadow-dim);
  --shadow-strength: var(--shadow-strength-dim);
}

この時点では、作成者は必要に応じて提供されたカラーパターンのジェネリックを自由に使用でき、テーマについて心配する必要はもうありません。

おわりに

さて、やったらどうやってやったの?🙂

多様なアプローチと、ウェブでの構築方法を学んでいきましょう。 Codepen を作成するか、独自のデモをホストして、それをツイートしてください。以下のコミュニティ リミックス セクションに追加します。

ソース

コミュニティ リミックス - @chris-kruiningno-preferencemoreless の色相スライダー、ステータス カラー、コントラスト モードを追加しました(デモ)。