CSSのfilterを使って、背景色に合わせた文字色を自動的に設定する
背景色が動的に変わる状況で、文字色を良い感じに設定したい事があります。 ユーザーの入力によって色が決まるとか、外部のAPIが色を決めてるとか。
このサイトのworksページの各リポジトリについている、「Python」とか「TypeScript」とかの言語タグの色がそんな感じになっています。 この色はGitHubのAPIが決めているものなのですが、文字色の方は提供してくれないのでCSSで動的に計算するようにしています。
ここで使っているテクニックが地味に面白いのでご紹介します。
やり方
色設定のコードは以下のような感じ。
<div> <span>hello world!</span> </div> <style> div { background-color: red; } span { color: red; filter: invert(100%) grayscale(100%) contrast(100); } </style>
以上、これだけ。 背景色と同じ色を文字色にも設定しちゃって、CSSのfilterを使って見える色に変化させています。
実際色んな色でやってみると以下のような表示になります。
基本全部に上手いこと色を当ててくれている感じ。
ただ、中間付近の色(#8080FF
とか)だとちょっと微妙ですね。
あとはinvert()
が効かない完全な中間色である#808080
などはかなり見辛くなります。
とはいえ、この簡単さで基本上手くいっているので十分でしょう。
ブラウザの対応状況
基本的なブラウザで使用することが出来ますが、IEだけは対応しないのでご注意。
まあもうIEは良いでしょう。良いということにしましょう。
仕組み
まずは同じ色で描画する
最初はfilterを掛ける前の状態から。
背景と色を同じ色で描画します。 同じ色なので当然ですが、そのままでは全く見えません。
invertで色を反転させる
この状態から文字色だけにinvert(100%)
を当てることで色を反転させて、ちゃんと目に見えるようにします。
モノクロにして見やすくする
色を反転させただけだと反対色な上にコントラストが凄いことになるので、彩度が高いと目が痛い感じになります。
なので、grayscale(100%)
を設定してモノクロにしてあげます。
コントラストを上げて更に見やすくする
モノクロ化することで目が痛いことはなくなりましたが、今度はコントラストが低すぎて見えづらいです。
というわけで、contrast(100)
でコントラストをがっつり上げて白か黒かに固定します。
これで完成。結構シンプルです。