カオス化したスタイルシートから卒業!CSSでカラーを管理する効率的な方法
Post on:2018年10月2日
テキスト、ボーダー、背景、アクセント、エラーなど、カラーをCSSでどのように定義すると効率的に管理できるのか、保守が簡単になるのか、そのテクニックを紹介します。
Create your design system, part 3: Colors
by CodyHouse
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
- はじめに
- カラーをCSSで効率的に管理するために
- セマンティックにするか、宣言型にするか
- 基本的なカラーパレットの作成
- セマンティックカラーの追加
- このアプローチを採用する理由
- テーマに使用するカラー
はじめに
元々は、近日公開予定の「Web Components」のために作成したものですが、グローバルのCSSとして利用できるので、一足先に公開します。
カラーをCSSで効率的に管理するために
カラーをCSSで効率的に管理するためには、セマンティックに重点をおきます。カラーを定義する_colors.scssファイルを作成し、以下の点に留意してください。
- カラーに使用する変数名は、覚えやすいものにします。カラーを使用する時、常にこのファイルを確認しなければならないのは面倒です。
- カラーを追加、削除、変更するのは、簡単に作業できるようにします。これらの作業が複雑ではないことを常に確認してください。
- このファイルには、カラーの設定のみが含まれる状態にします。他の定義は一切含んではいけません。
効果的なデザインシステムを作成するためには、必要ではないものをすべて取り除くことです。ここでは、カラーのみに限定します。
セマンティックにするか、宣言型にするか
カラーの変数を設定する際には、セマンティックにするか、宣言型にするかの2つのアプローチがあります。
まずは、セマンティックなアプローチから見てましょう。
1 2 3 4 5 6 7 8 9 10 11 |
:root { --color-primary: #4D84F4; --color-secondary: #f5414f; --color-text: #2e2e31; --color-border: #d1d0d2; --color-success: #88c459; --color-error: #f5414f; --color-warning: #ffd137; } |
宣言型になると、下記のようになります。
※それぞれのカラーコードは同じです。
1 2 3 4 5 6 7 8 9 10 11 |
:root { --blue: #4D84F4; --red-brand: #f5414f; --black: #2e2e31; --gray: #d1d0d2; --green: #88c459; --red: #f5414f; --yellow: #ffd137; } |
セマンティックでも宣言型でも、どちらもでもコード的には問題ありません。どちらを使用するかは、あなたのニーズによって異なります。例えば、プロジェクトの規模、ブランドカラーの有無など、いろいろな要因があります。
わたし達が作成したフレームワークでは、ユーザーがカラーを編集することを考慮に入れたため、セマンティックなアプローチを採用しました。宣言的なアプローチが使いやすいものであったとしても、メンテナンス性に優れた方を選択したことになります。
メンテナンス性とは、例えば「--color-primary」の「#4D84F4」ブルーをオレンジに変更しても「--color-primary」は問題ありません。しかし、宣言型の「--blue」がオレンジになるのは混乱します。この場合は変数名も変更するか、新たに変数を作成してHTMLをすべて修正することになります。そのため、宣言型はメンテナンス性に欠けます。
基本的なカラーパレットの作成
最初は、基本的なカラーを定義するために、必要最小限のカラーを設定します。
一般的に必要最小限のカラーは、下記の通りです。
-
- プライマリーカラー
- リンクやボタンや背景などに使用されるカラー。特に目立たせたい要素、アクションボタンに使用されます。
-
- アクセントカラー
- コンテンツの重要な要素を強調するために使用されるカラー。プライマリーカラーのバリエーションではなく、補色です。
-
- ニュートラルカラー
- テキスト要素やボーダーなどに使用されるグレースケールトーンのカラーです。
-
- フィードバックカラー
- 成功やエラーや警告など、フィードバックに使用されるカラー。
これらのカラーには、インタラクションを強調するために使用されるバリエーション(より暗い・より明るい)が必要なものもあります。
CSSでこれらのカラーを定義してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
:root { /* main colors */ --color-primary: #4D84F4; --color-primary-light: color-mod(var(--color-primary) tint(15%)); --color-primary-dark: color-mod(var(--color-primary) shade(15%)); --color-primary-bg: color-mod(var(--color-primary) alpha(20%)); --color-accent: #f5414f; --color-accent-light: color-mod(var(--color-accent) tint(15%)); --color-accent-dark: color-mod(var(--color-accent) shade(10%)); --color-accent-bg: color-mod(var(--color-accent) alpha(20%)); // shades - generated using chroma.js - 12 steps --black: #1d1d21; --gray-10: #2e2e31; --gray-6: #7b7a7d; --gray-4: #a5a5a6; --gray-3: #bbbbbc; --gray-2: #d1d0d2; --gray-1: #e8e7e8; --white: white; /* feedback */ --color-success: #88c459; --color-error: #f5414f; --color-warning: #ffd137; } |
※カラーの関数をすべてのブラウザと互換性のあるRGBAコードに変換するために、PostCSS color-mod() Functionを使用しています。
プライマリカラーとアクセントカラーのバリエーションは、color()を使用して生成されます。このcolor()を使用することで、定義したカラーを納得するまで関数の値を微調整できて便利です。
ニュートラルカラーはchroma.jsで生成されています。ニュートラルカラーの場合、関数を使用するのは理想的ではありません。一般的に、2つの反対色(白と黒)があり、この2つのカラーに基づいてカラーを生成する必要があるからです。
セマンティックカラーの追加
基本的なカラーパレットを準備できたら、セマンティックカラーを追加できます。セマンティックカラーを追加するのは、単にカラーの数を増やすのではなく、セマンティックのリファレンスを参照してカラーを決めることを意味します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
:root { /* main colors */ --color-primary: #4D84F4; --color-primary-light: color-mod(var(--color-primary) tint(15%)); --color-primary-dark: color-mod(var(--color-primary) shade(15%)); --color-primary-bg: color-mod(var(--color-primary) alpha(20%)); --color-accent: #f5414f; --color-accent-light: color-mod(var(--color-accent) tint(15%)); --color-accent-dark: color-mod(var(--color-accent) shade(10%)); --color-accent-bg: color-mod(var(--color-accent) alpha(20%)); // shades - generated using chroma.js - 12 steps --black: #1d1d21; --gray-10: #2e2e31; --gray-6: #7b7a7d; --gray-4: #a5a5a6; --gray-3: #bbbbbc; --gray-2: #d1d0d2; --gray-1: #e8e7e8; --white: white; /* feedback */ --color-success: #88c459; --color-error: #f5414f; --color-warning: #ffd137; /* typography */ --color-text: var(--gray-10); --color-text-heading: var(--black); --color-text-subtle: var(--gray-6); --color-link: var(--color-primary); --color-link-visited: var(--color-primary-dark); --color-mark: var(--color-accent-bg); --color-blockquote-border: var(--gray-2); /* border */ --color-border: var(--gray-2); /* body */ --color-body: var(--white); /* forms */ --form-element-border: var(--color-border); --form-element-border-focus: var(--color-primary); --form-element-border-error: var(--color-error); --form-element-bg: var(--white); --form-text-placeholder: var(--gray-4); /* buttons */ --btn-primary-bg: var(--color-primary); --btn-primary-hover: var(--color-primary-light); --btn-primary-active: var(--color-primary-dark); --btn-primary-label: var(--white); /* icons */ --color-icon-primary: var(--gray-4); --color-icon-secondary: inherit; } |
このアプローチを採用する理由
第一に、このシステムはプライマリカラーとアクセントカラーの2つの基本的なカラーに依存しています。つまり、カラーの変数を使用する場合、blueやredのような宣言的な名前を使用しなくても、変数が何をあらわしているのかを覚えておくことが難しくないということです。
あなたのシステムではより多くのカラー(セカンダリーカラーなど)を必要とするかもしれません。これはアプローチに関係なく、10以上のメインカラーに基づいてシステムを管理することは難しいことなので、シンプルにすることをお勧めします。
グレースケールのカラーは異なる命名規則を使用します。より暗いカラーになるほど、変数の最後にある数値が大きくなります。このアプローチは、どのニュートラルカラーを適用したいか分からない時に便利です。もしgray-2が微妙に感じたら、gray-3を試すことができます。
また、グレースケールの番号が欠けていることに気がついたと思います(gray-5など)。これらのカラーは必要ではない(Webコンポーネントを作成する際にそれらを使用したことはありません)ので、カラーパレットから削除しました。
セマンティックにする利点は、3つあります。
- _colors.scssファイルはカラーを変更する必要がある時は常に、元のソースになります。例えば、見出しのテキストをもっと暗くしたいと感じたら、_colors.scssをエディタで開いて変更するだけです。
- ボーダーにカラーを適用する時も、他のコンポーネントで使用したカラーを確認する必要はありません。同じコンセプトがボーダーだけでなく、多くの要素に適用されます。
- 異なるテーマを作成しても、一貫したカラーの使い方を維持することができます。
テーマに使用するカラー
プラグインやポリフィルに頼らずに、CSSの変数でテーマに使用するカラーを作成すると、非常に簡単です。逆に言うと、現在の状況だと作成できないということでしょうか? いいえ、違います。わたし達には2つのオプションがあります。
オプション1
とにかくCSSの変数をアップデートすることです。変数をサポートしていないブラウザは、デフォルトのテーマカラーを使用します。コンテンツがアクセシブルであれば、問題ありません。
例えば、デフォルトのテーマカラーが白背景で黒テキスト、.theme-darkが黒背景で白テキスト、があるとします。次にデフォルトと.theme-darkを使用する2つのコンポーネントを作成します。もしデフォルトのテーマで両方のコンポーネントを使用してもユーザーエクスペリエンスに問題がないのであれば、.dark-themeは拡張機能(オプション)として扱うことができます。こうすることで、ブラウザにサポートされていなくても、変数をアップデートしてさまざまなテーマを作成するのは理にかなっています。
これがCSSの変数を使用して、新しいテーマカラーを作成する方法です。
1 2 3 4 5 6 7 8 |
@supports(--css: variables) { .theme--dark { --component-background: var(--black); --color-border: var(--gray-6); --color-text: var(--gray-4); --color-text-heading: var(--white); } } |
この方法はカラー変更を抽象化し、1つのファイルにテーマカラーを保存できるので、私は好んで使用しています。こうすることで、CSSのclassを適用するだけで、さまざまなテーマの各コンポーネントの状態をアップデートすることができます。
オプション2
テーマによって外観に影響を受けるすべての要素を対象にします。この方法の利点は、すべてのブラウザでサポートされていることです。しかし、CSSの変数に基づいたものと比較して、管理するのは簡単ではありません。
コードを見てましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
.theme--dark { color: var(--gray-1); h1, h2, h3, h4 { color: var(--white); } .text--subtle { color: var(--gray-4); } a { color: var(--color-accent); } } |
sponsors