web design uiNovember 5, 20267 min read

CSSグラデーションの色:真ん中がグレーになる理由と3つの直し方

青から黄色へブレンドすると真ん中がグレーになります。原因は、16進カラーがRGBで混ざるから。中間ストップを足す、OKLCHでブレンドする、色相環で隣り合う色を選ぶ。すぐ使えるグラデーション5つ付き。

By Boone
XLinkedIn
CSS Gradient Colors: Why Gradients Turn Gray in the Middle and 3 Ways to Fix It

グラデーションの真ん中がグレーになるのは、ブラウザが16進カラーをRGBでブレンドするからです。正反対に位置する2色は、中間地点で打ち消し合います。直し方は、真ん中に意図して色を置くか、ブレンドの計算方法を変えるか。ここでは3つの直し方と、コピペで使えるグラデーション5つを紹介します。

真ん中がグレーになる理由

濁って見えるグラデーションを見てください。両端は無視します。両端は問題ありません。あなたが選んだ色だからです。誰も選んでいないのが真ん中です。

グラデーションはブレンドで、ブレンドには計算が必要です。16進カラーはRGBの値なので、ブラウザはデフォルトでチャンネルごとに混ぜます。

青と黄色の中間では、赤は0と255の中間、緑も0と255の中間、青は255と0の中間です。どのチャンネルも128付近に落ち着きます。赤・緑・青が等しい状態、それがグレーの定義です。

#0000FF から #FFFF00

青から黄色へのグラデーション。真ん中が平坦なグレーになっている

中間ストップ #0EBAAE を追加

同じ青から黄色のグラデーションに、ティールの中間色を入れたもの。端から端まで色鮮やかなまま
両端は同じです。左はブレンドが #808080 をまっすぐ通過します。右は真ん中がティールなので、グラデーションが最後まで生き生きしています。

これはモニターのせいでも、圧縮の問題でもありません。ただの算数で、2色が色相環で遠く離れているときはいつでも起こります。青と黄色はほぼ完全な反対色で、最悪のケースです。

直し方1:中間ストップを足す

最も直接的な方法は、真ん中を成り行きに任せるのをやめることです。50%の位置に、自分で選んだ色の3つ目のカラーストップを足します。

css
background: linear-gradient(90deg, #0000FF, #0EBAAE, #FFFF00);

#0EBAAE は、知覚上の色として青と黄色の間にあるティールです。ブレンドは青からティール、ティールから黄色へと進み、どちらの半分もグレーを横切りません。

これはすべてのブラウザで動き、新しい構文も要らないので、どこでも同じ見た目にしたいデザインには安全な選択です。中間色は目で選び、両端の隣に置いて確認しましょう。代償は、2色ではなく3色を管理することになる点です。

直し方2:OKLCHでブレンドする

もう一つは、色を足すのではなく計算を変える方法です。CSSではブレンドを行う色空間を選べて、OKLCHは色を明度、彩度、色相で表します。彩度は色の鮮やかさなので、彩度を保つブレンドは鮮やかなままです。

css
background: linear-gradient(in oklch, #0000FF, #FFFF00);

in oklch を付けると、ブラウザはグレーの中心をまっすぐ抜けず、緑やティールを通って色相環を回ります。色は2色のままで、コードも短く済みます。MDNはこれをグラデーション関数内のカラー補間方法として説明しており、レガシーな16進カラーは、指定しない場合に古いページとの互換性のためRGBだけを使います。

知っておくべきことが2つあります。旅の途中の色には画面で表示できない範囲に出るものがあり、その場合ブラウザは最も近い表示可能な値に切り詰めます。また、通るのは色相環の近道なので、選ばれた経路が好みかどうか確認してください。この色空間については、モダンCSSのOKLCHカラーのガイドで詳しく解説しています。

直し方3:隣り合う色を選ぶ

3つ目はコードに触れません。打ち消し合えない色を選ぶ方法です。

#0066FF から #FF8800

青からオレンジへのグラデーション。真ん中がくすんだ茶色がかったグレーになっている

#6440E0 から #E040A0

バイオレットからピンクへのグラデーション。端から端まで鮮やかなまま
青とオレンジは反対色なので、くすんだ #807780 で出会います。バイオレットとピンクは隣同士なので、豊かな #A240C0 で出会います。

反対色はグレーに混ざります。隣り合う色は、その間のちゃんと色のある色に混ざります。ブランドが反対色の2色を組み合わせているなら、それでもグラデーションに使えます。間に中間ストップを置くか、OKLCHでブレンドしましょう。

青からオレンジ、デフォルトのブレンド

茶色がかったグレーの真ん中を持つ、青からオレンジのグラデーション

青からオレンジ、oklchで

OKLCHでブレンドした同じ青からオレンジのグラデーション。グレーではなくバイオレットとピンクを通る
両端は先ほどと同じで、変えたのはブレンドだけです。グレーは消え、真ん中は鮮やかなピンクになりました。

自分のグラデーションを確認する方法

  1. 両端ではなく、真ん中を見る。
  2. そこに見える色の名前を言う。グレー、茶色、泥なら、#808080 や #807780 のように、それが問題です。
  3. 上の直し方から一つ選び、2つのバージョンを並べて比べる。

グラデーションは最悪の地点までの出来でしかなく、最悪の地点はほぼ必ず真ん中です。

盗んでいい5つのグラデーション

どれも、真ん中が色鮮やかなままか確認済みです。最初のものは中間ストップ入りで、残り4つは隣り合う色相を使っています。コードをタップするとコピーできます。

青からティールを経て黄色へのグラデーション
青、ティール、黄色。色をタップするとコードをコピーできます。
バイオレットからピンクへのグラデーション
バイオレットからピンク。色をタップするとコードをコピーできます。
青からティールへのグラデーション
青からティール。色をタップするとコードをコピーできます。
オレンジからホットピンクへのグラデーション
オレンジからホットピンク。色をタップするとコードをコピーできます。
グリーンからライムへのグラデーション
グリーンからライム。色をタップするとコードをコピーできます。
グラデーション開始中間終了効く理由
青、ティール、黄色#0000FF#0EBAAE#FFFF00両端は反対色だが、本物の中間ストップで救済
バイオレットからピンク#6440E0なし#E040A0色相環で隣同士
青からティール#2F5BEAなし#14B8A6色相環で隣同士
オレンジからホットピンク#FF7A00なし#FF2E93色相環で隣同士
グリーンからライム#00A86Bなし#C6F432色相環で隣同士

開発者に渡すコード

css
.gradient-sunrise { background: linear-gradient(90deg, #0000FF, #0EBAAE, #FFFF00); } .gradient-violet { background: linear-gradient(90deg, #6440E0, #E040A0); } .gradient-ocean { background: linear-gradient(90deg, #2F5BEA, #14B8A6); } .gradient-sunset { background: linear-gradient(90deg, #FF7A00, #FF2E93); } .gradient-meadow { background: linear-gradient(90deg, #00A86B, #C6F432); } /* Two opposite colors, no middle stop: choose the blend space instead. */ .gradient-opposites { background: linear-gradient(in oklch, #0066FF, #FF8800); }

ブラウザが in oklch を理解しない場合、宣言全体が無視されます。フォールバックとして、まず通常の linear-gradient(...) の行を書き、その後にOKLCHの行を置いてください。

FAQ

なぜグラデーションの真ん中がグレーになるの?

16進カラーはRGBでブレンドされ、色相環で遠く離れた2色は平均するとグレーになります。青 #0000FF と黄色 #FFFF00 は #808080 で出会います。

CSSグラデーションが濁って見えるのを防ぐには?

本物の色で中間のカラーストップを足す、linear-gradient(in oklch, ...) でOKLCHブレンドする、または色相環で隣り合う2色を選びましょう。

CSSグラデーションの「in oklch」は何をするの?

ブラウザに、RGBではなくOKLCH色空間で色をブレンドするよう指示します。これにより、真ん中がグレーに落ちず、色を保ちます。

相性のいいグラデーションの色は?

色相環で隣り合う色です。たとえばバイオレット #6440E0 からピンク #E040A0、グリーン #00A86B からライム #C6F432。ブレンドは端から端まで鮮やかなままです。

すべてのブラウザがOKLCHのグラデーションに対応している?

最新のブラウザは対応していますが、非対応のブラウザは宣言を捨てます。フォールバックとして、その前に通常のグラデーションの行を足してください。

なぜ青から黄色は緑ではなくグレーになるの?

ブレンドがRGBをまっすぐ通る経路を取り、2色の平均がグレーだからです。緑の中間は、ストップとして足すか、OKLCHでブレンドしたときだけ現れます。

出典

  • CSS Color Module Level 4, interpolation: 16進のようなレガシーsRGBカラーはデフォルトでsRGBで補間され、他の色空間はカラー補間方法で選びます。
  • MDN, linear-gradient(): <color-interpolation-method> 構文、in oklch。
  • MDN, OKLCH color: 明度、彩度、色相。
  • (0, 0, 255) と (255, 255, 0) の中間点は (127.5, 127.5, 127.5) で、これはOKLCH彩度0の #808080 です。#0066FF から #FF8800 の中間点 (#807780) と #6440E0 から #E040A0 の中間点 (#A240C0) は、当方がsRGBで計算しました。このページのバーはそれらの計算から描画しており、OKLCHのバーはブラウザと同様、画面の範囲外の色を切り詰めています。
  • 最初に UX Brainy でカルーセルとして公開されました。

Want gradients, color and every other detail designed as one system? Our team designs and builds product UI that holds up on every screen.

Get Started

More from Brainy Papers

Keep reading