kanta's spike

デジタル庁が公開しているデザインシステムは、 ウェブデザインのポリシーや部品が記載されていて、大変勉強になります。

その中のカラーシステム2.0の説明を読んでいると、カラーパレットが登場します。 カラーパレットには、名前(例: Blue)と、番号(例: 50,100,…,1200)、16進数のRGB色(例: #E8F1FE) が登場します。

[新規スタイル] カラー2.0を追加しました # [バージョン1.4.0]スタイルやコンポーネントの追加・修正・更新を行いました|デジタル庁

このようなカラーパレットを自分でも作ってみたくなりました。

やること

基準となる色を選び、その色のカラーパレットを作成します。

今回は例として、最近見たアニメからこの色を選びました。 この色をもとにカラーパレットを作成したいと思います。

#405743
マントの色
16進数RGBの色

試行錯誤1

最初は、RGBをHSLに変換して輝度(HSLのL)だけ変化させれば良いと考えました。

デジ庁のカラーシステムでは、パレットに13段階(50,100,200,300,400,500,600,700,800,900,1000,1100,1200)の番号がついています。

13段階のルールがわからないので、今回は簡単にするため、輝度(L)をそのまま 色の番号 (プレフィックスにL、あとは輝度から%の除いた値)にしたいと思います。

#405743
マントの色(HSL)
No. L29.6
hsl(128 15.2% 29.6%)
HSLの色

80〜20までの輝度を10区切りで、100〜80、20〜0は5区切りで並べてみました。

なかなか良さそうです。

マントの色(HSL)
L100
#FFFFFF
hsl(128 15.2% 100%)
L95
#F0F4F1
hsl(128 15.2% 95%)
L90
#E2E9E3
hsl(128 15.2% 90%)
L85
#D3DFD4
hsl(128 15.2% 85%)
L80
#C4D4C6
hsl(128 15.2% 80%)
L70
#A7BEAA
hsl(128 15.2% 70%)
L60
#89A98E
hsl(128 15.2% 60%)
L50
#6C9371
hsl(128 15.2% 50%)
L40
#56765B
hsl(128 15.2% 40%)
L30
#415844
hsl(128 15.2% 30%)
L20
#2B3B2D
hsl(128 15.2% 20%)
L15
#202C22
hsl(128 15.2% 15%)
L10
#161D17
hsl(128 15.2% 10%)
L5
#0B0F0B
hsl(128 15.2% 5%)
L0
#000000
hsl(128 15.2% 0%)

しかし、以下の記事で知ったのですが、HSLによる色の表現は人間の感覚とは少し違うそうです。 同じ輝度を持つ色同士(例えば、青と黄)を並べた時に、それらの色を人間の目で見ると、同じ明さと感じれないそうです。

HSL / HSV より人間に寄り添った色表現 CIE L*C*h を使いたい #JavaScript - Qiita

比較用に黄色のパレットも作ってみました。

#FCEA2B
黄色(HSL)
No. L57.8
hsl(55 97.2% 57.8%)
HSLの色
黄色(HSL)
L100
#FFFFFF
hsl(55 97.2% 100%)
L95
#FFFDE6
hsl(55 97.2% 95%)
L90
#FEFACD
hsl(55 97.2% 90%)
L85
#FEF8B4
hsl(55 97.2% 85%)
L80
#FEF59A
hsl(55 97.2% 80%)
L70
#FDF068
hsl(55 97.2% 70%)
L60
#FCEB36
hsl(55 97.2% 60%)
L50
#FBE604
hsl(55 97.2% 50%)
L40
#C9B803
hsl(55 97.2% 40%)
L30
#978A02
hsl(55 97.2% 30%)
L20
#655C01
hsl(55 97.2% 20%)
L15
#4B4501
hsl(55 97.2% 15%)
L10
#322E01
hsl(55 97.2% 10%)
L5
#191700
hsl(55 97.2% 5%)
L0
#000000
hsl(55 97.2% 0%)

マントの緑と黄色を輝度(L)の順に並べてみましょう。

HSL色の比較
マントの色
L70
#A7BEAA
hsl(128 15.2% 70%)
L60
#89A98E
hsl(128 15.2% 60%)
L50
#6C9371
hsl(128 15.2% 50%)
L40
#56765B
hsl(128 15.2% 40%)
L30
#415844
hsl(128 15.2% 30%)
L20
#2B3B2D
hsl(128 15.2% 20%)
黄色
L70
#FDF068
hsl(55 97.2% 70%)
L60
#FCEB36
hsl(55 97.2% 60%)
L50
#FBE604
hsl(55 97.2% 50%)
L40
#C9B803
hsl(55 97.2% 40%)
L30
#978A02
hsl(55 97.2% 30%)
L20
#655C01
hsl(55 97.2% 20%)

例えばL50番など同じ輝度の緑と黄色を比べても、同じ輝度とは感じられませんね。 また、個人の感想ですが黄色のL60番とL50番の色の差がわかりにくいですね。

試行錯誤2

先ほどの記事(リンクを再掲)では、CIE L*C*h カラーモデルという色の表現方法を紹介してくれています。

HSL / HSV より人間に寄り添った色表現 CIE L*C*h を使いたい #JavaScript - Qiita

このカラーモデルは、人間の知覚に合せて設計されているそうです。Lが明度で、Cが彩度、H色相になります。

さきほどの緑と黄色をCIE L*C*h カラーモデルで表現してみましょう。

#405743
マントの色(LCH)
No. L34.6
lch(34.6% 16 146.5)
LCHの色
#FCEA2B
黄色(LCH)
No. L91.6
lch(91.6% 85.4 98.1)
LCHの色

LCHの明度(L)の部分だけ変化させてカラーパレットを作ります。 80〜20までの輝度を10区切りで、100〜80、20〜0は5区切りで並べてみました。

マントの色(LCH)
L100
#EBFFED
lch(100% 16 146.5)
L95
#DCF8DF
lch(95% 16 146.5)
L90
#CEE9D1
lch(90% 16 146.5)
L85
#C1DBC3
lch(85% 16 146.5)
L80
#B3CDB5
lch(80% 16 146.5)
L70
#98B29B
lch(70% 16 146.5)
L60
#7E9781
lch(60% 16 146.5)
L50
#657D68
lch(50% 16 146.5)
L40
#4D644F
lch(40% 16 146.5)
L30
#354C39
lch(30% 16 146.5)
L20
#203523
lch(20% 16 146.5)
L15
#152A19
lch(15% 16 146.5)
L10
#0B200E
lch(10% 16 146.5)
L5
#001700
lch(5% 16 146.5)
L0
#000A00
lch(0% 16 146.5)
黄色(LCH)
L100
#FFFF49
lch(100% 85.4 98.1)
L95
#FFF438
lch(95% 85.4 98.1)
L90
#F7E624
lch(90% 85.4 98.1)
L85
#E8D803
lch(85% 85.4 98.1)
L80
#D8CA00
lch(80% 85.4 98.1)
L70
#BAAF00
lch(70% 85.4 98.1)
L60
#9D9400
lch(60% 85.4 98.1)
L50
#807B00
lch(50% 85.4 98.1)
L40
#656200
lch(40% 85.4 98.1)
L30
#4D4A00
lch(30% 85.4 98.1)
L20
#3B3300
lch(20% 85.4 98.1)
L15
#352800
lch(15% 85.4 98.1)
L10
#311C00
lch(10% 85.4 98.1)
L5
#2C1200
lch(5% 85.4 98.1)
L0
#270100
lch(0% 85.4 98.1)

緑と黄色を並べてみましょう。

HSLと比べると、LCHの同一輝度の色を比較すると、輝度に統一感がありますね。 個人の感想ですが、同じ番号のマントの色と黄色は、だいたい同じ明るさに思えますね。

LCH色の比較
マントの色
L90
#CEE9D1
lch(90% 16 146.5)
L85
#C1DBC3
lch(85% 16 146.5)
L80
#B3CDB5
lch(80% 16 146.5)
L70
#98B29B
lch(70% 16 146.5)
L60
#7E9781
lch(60% 16 146.5)
L50
#657D68
lch(50% 16 146.5)
黄色
L90
#F7E624
lch(90% 85.4 98.1)
L85
#E8D803
lch(85% 85.4 98.1)
L80
#D8CA00
lch(80% 85.4 98.1)
L70
#BAAF00
lch(70% 85.4 98.1)
L60
#9D9400
lch(60% 85.4 98.1)
L50
#807B00
lch(50% 85.4 98.1)

一応、HSL版を再掲しておきます。

HSL色の比較
マントの色
L70
#A7BEAA
hsl(128 15.2% 70%)
L60
#89A98E
hsl(128 15.2% 60%)
L50
#6C9371
hsl(128 15.2% 50%)
L40
#56765B
hsl(128 15.2% 40%)
L30
#415844
hsl(128 15.2% 30%)
L20
#2B3B2D
hsl(128 15.2% 20%)
黄色
L70
#FDF068
hsl(55 97.2% 70%)
L60
#FCEB36
hsl(55 97.2% 60%)
L50
#FBE604
hsl(55 97.2% 50%)
L40
#C9B803
hsl(55 97.2% 40%)
L30
#978A02
hsl(55 97.2% 30%)
L20
#655C01
hsl(55 97.2% 20%)

試行錯誤3

このカラーパレットですが、LCH色の端の色が怪しいですね。L100は、もっと白くなって欲しい。

マントの色(LCH)
L100
#EBFFED
lch(100% 16 146.5)
L95
#DCF8DF
lch(95% 16 146.5)
L90
#CEE9D1
lch(90% 16 146.5)
L85
#C1DBC3
lch(85% 16 146.5)
L80
#B3CDB5
lch(80% 16 146.5)
L70
#98B29B
lch(70% 16 146.5)
L60
#7E9781
lch(60% 16 146.5)
L50
#657D68
lch(50% 16 146.5)
L40
#4D644F
lch(40% 16 146.5)
L30
#354C39
lch(30% 16 146.5)
L20
#203523
lch(20% 16 146.5)
L15
#152A19
lch(15% 16 146.5)
L10
#0B200E
lch(10% 16 146.5)
L5
#001700
lch(5% 16 146.5)
L0
#000A00
lch(0% 16 146.5)
黄色(LCH)
L100
#FFFF49
lch(100% 85.4 98.1)
L95
#FFF438
lch(95% 85.4 98.1)
L90
#F7E624
lch(90% 85.4 98.1)
L85
#E8D803
lch(85% 85.4 98.1)
L80
#D8CA00
lch(80% 85.4 98.1)
L70
#BAAF00
lch(70% 85.4 98.1)
L60
#9D9400
lch(60% 85.4 98.1)
L50
#807B00
lch(50% 85.4 98.1)
L40
#656200
lch(40% 85.4 98.1)
L30
#4D4A00
lch(30% 85.4 98.1)
L20
#3B3300
lch(20% 85.4 98.1)
L15
#352800
lch(15% 85.4 98.1)
L10
#311C00
lch(10% 85.4 98.1)
L5
#2C1200
lch(5% 85.4 98.1)
L0
#270100
lch(0% 85.4 98.1)

このカラーパレットは、LCH色をRGB色に変換し、そのRGB色をHTML上に表示しています。

しかし、LCH色は、RGB色よりも広い範囲の色を表現できるそうです。 LCH色がRGB色の範囲を超えた場合どうなるのでしょうか?

色の怪しかったマントの色の左端(L100)は、以下のように変換されています。

変換前LCH色 変換後16進RGB
lch(100% 16 146.5) #EBFFED

しかし、LCH色をRGB色に変換した生のRGB値(丸める前の値)は以下のようになります。

変換前LCH色 変換後の’生’RGB 16進RGBに強制変換
lch(100% 16 146.5) rgb(235 262 237) #EBFF0ED

RGB値の各色は0〜255までなので、緑成分(G)が262となり範囲を超えています。

その場合、16進RGBに変換時に、範囲を超えた値を強制的に上限or下限の値に置き換えられます。 今回は緑成分の262255に置き換えられてしまいます。

そのため、怪しい色になったのだと考えられます。

では、どうすれば良いのでしょうか?

luncheon/lch-color-wheelでは、丸める前の生のRGB値を取得し1、0〜255を超える成分がある場合は、 もう一度LCH色に戻り、LCH色の 彩度(C) の値を調整してRGB値が0〜255に収まるように補正しています。2

これにより、RGBの各成分が均等に丸められます。(RGBの特定成分だけが255や0に丸められるのを避けることができます。)

この方法を採用してカラーパレットを表示してみましょう(赤字部分は補正のあった色になります。)。3 より自然なカラーパレットになった気がします。

マントの色(LCH)
L100
#FEFFFE
lch(100% 16 146.5)
補正あり
rawRGB
[235 262 237]
L95
#DDF8DF
lch(95% 16 146.5)
L90
#CEE9D1
lch(90% 16 146.5)
L85
#C1DBC3
lch(85% 16 146.5)
L80
#B3CDB6
lch(80% 16 146.5)
L70
#98B29B
lch(70% 16 146.5)
L60
#7E9781
lch(60% 16 146.5)
L50
#657D68
lch(50% 16 146.5)
L40
#4D644F
lch(40% 16 146.5)
L30
#354C39
lch(30% 16 146.5)
L20
#203523
lch(20% 16 146.5)
L15
#152A19
lch(15% 16 146.5)
L10
#0B200F
lch(10% 16 146.5)
L5
#051407
lch(5% 16 146.5)
L0
#13000A
lch(0% 16 146.5)
補正あり
rawRGB
[12 -4 3]
黄色(LCH)
L100
#FFFFFD
lch(100% 85.4 98.1)
補正あり
rawRGB
[278 258 73]
L95
#FFF1B0
lch(95% 85.4 98.1)
補正あり
rawRGB
[263 244 56]
L90
#F7E624
lch(90% 85.4 98.1)
L85
#E8D803
lch(85% 85.4 98.1)
L80
#D9C900
lch(80% 85.4 98.1)
補正あり
rawRGB
[217 202 -39]
L70
#BBAE00
lch(70% 85.4 98.1)
補正あり
rawRGB
[186 174 -87]
L60
#9E9300
lch(60% 85.4 98.1)
補正あり
rawRGB
[157 148 -98]
L50
#827900
lch(50% 85.4 98.1)
補正あり
rawRGB
[127 123 -84]
L40
#686000
lch(40% 85.4 98.1)
補正あり
rawRGB
[99 98 -58]
L30
#4E4800
lch(30% 85.4 98.1)
補正あり
rawRGB
[71 74 -33]
L20
#363100
lch(20% 85.4 98.1)
補正あり
rawRGB
[46 52 -21]
L15
#2A2600
lch(15% 85.4 98.1)
補正あり
rawRGB
[35 41 -25]
L10
#1F1C00
lch(10% 85.4 98.1)
補正あり
rawRGB
[28 31 -36]
L5
#161100
lch(5% 85.4 98.1)
補正あり
rawRGB
[27 18 -57]
L0
#13000A
lch(0% 85.4 98.1)
補正あり
rawRGB
[35 -8 -87]

マントの色と黄色のパレットを突き合わせて確認しましょう。

個人の感想ですが、対応する各色は同じ明るさに見えますね。(L90は少し怪しいですが…)

LCHのパレットの比較(1/3)
マントの色(LCH)
L100
#FEFFFE
lch(100% 16 146.5)
L95
#DDF8DF
lch(95% 16 146.5)
L90
#CEE9D1
lch(90% 16 146.5)
L85
#C1DBC3
lch(85% 16 146.5)
L80
#B3CDB6
lch(80% 16 146.5)
L70
#98B29B
lch(70% 16 146.5)
黄色(LCH)
L100
#FFFFFD
lch(100% 85.4 98.1)
L95
#FFF1B0
lch(95% 85.4 98.1)
L90
#F7E624
lch(90% 85.4 98.1)
L85
#E8D803
lch(85% 85.4 98.1)
L80
#D9C900
lch(80% 85.4 98.1)
L70
#BBAE00
lch(70% 85.4 98.1)
LCHのパレットの比較(2/3)
マントの色(LCH)
L60
#7E9781
lch(60% 16 146.5)
L50
#657D68
lch(50% 16 146.5)
L40
#4D644F
lch(40% 16 146.5)
L30
#354C39
lch(30% 16 146.5)
L20
#203523
lch(20% 16 146.5)
黄色(LCH)
L60
#9E9300
lch(60% 85.4 98.1)
L50
#827900
lch(50% 85.4 98.1)
L40
#686000
lch(40% 85.4 98.1)
L30
#4E4800
lch(30% 85.4 98.1)
L20
#363100
lch(20% 85.4 98.1)
LCHのパレットの比較(3/3)
マントの色(LCH)
L15
#152A19
lch(15% 16 146.5)
L10
#0B200F
lch(10% 16 146.5)
L5
#051407
lch(5% 16 146.5)
L0
#13000A
lch(0% 16 146.5)
黄色(LCH)
L15
#2A2600
lch(15% 85.4 98.1)
L10
#1F1C00
lch(10% 85.4 98.1)
L5
#161100
lch(5% 85.4 98.1)
L0
#13000A
lch(0% 85.4 98.1)

まとめ

最終的なマントの色のカラーパレットは以下になります。(L100とL0は、ほぼ白と黒になるので削っています。)

カラーパレットを作成するには、HSLではなく、CIE L*C*h カラーモデルを利用したほうが良さそうですね。

マントの色 カラーパレット
L95
#DDF8DF
lch(95% 16 146.5)
L90
#CEE9D1
lch(90% 16 146.5)
L85
#C1DBC3
lch(85% 16 146.5)
L80
#B3CDB6
lch(80% 16 146.5)
L70
#98B29B
lch(70% 16 146.5)
L60
#7E9781
lch(60% 16 146.5)
L50
#657D68
lch(50% 16 146.5)
L40
#4D644F
lch(40% 16 146.5)
L30
#354C39
lch(30% 16 146.5)
L20
#203523
lch(20% 16 146.5)
L15
#152A19
lch(15% 16 146.5)
L10
#0B200F
lch(10% 16 146.5)
L5
#051407
lch(5% 16 146.5)

ただ、以下の記事に紹介されているように、実際のカラーパレットは、単純に輝度を変化させるだけではなく、目的に応じて個別に彩度と色相に調整を入れるようです。(L95は調整が必要かも…)

UIデザインにおけるカラーパレットの作り方|小池 政幸 / TSUMIKI INC.

また、デジ庁のカラーパレットは色番号に50〜1200までを採番しています。 でも、この採番ルールがわからないので、自分専用のカラーパレットであれば、今回のように色番号に輝度(L)をそのまま使えば良いと思いました。

文字や背景色とした場合のコントラストについての考慮など、いろいろ勉強も必要そうです。

引き続き勉強したいと思います。

参考


  1. WickyNilliams/pure-colorpure-color/convert/xyz2rgb.jsを使うと、RGB値が0〜255の範囲に丸められるため、luncheon/lch-color-wheelさんは、生のRGB値を返せるように、xyz2rgb関数を修正されています。 ↩︎

  2. lch-color-wheel/src/index.ts at main · luncheon/lch-color-wheel ↩︎

  3. 生のRGB(rawRGB)の値が0〜255を超える場合は、パレットの下に赤字で表示し、16進RGB値は補正したものを表示しています。 ↩︎

作成日: 2023/11/17