はじめに
cssを書いていて、作成中のパーツがどんな色の背景に乗るのか決まらないので文字色が悩ましいなんてことありませんか?
緑の時もあれば
黄色の時もあるんかい……
といった場合に困ってしまいますよね。
輝度(luminance)というものがある
Photoshopを使っている人には馴染みがあると思いますが、明度ではなく人間の目が感じる色そのものが持っている輝きみたいなものみたいです。
上の例では黄色地に白抜きはデザインが全く機能していないので文字を黒くしたいところです。
JavaScriptで計算する
まずは背景色をゲットする
目的の要素を渡して親の背景色を再帰的に辿って取得すものです
function backgroundColor(el) {
var color = window.getComputedStyle(el)["background-color"];
var rgba = color
.replace(/^rgba?\(/, "")
.replace(/\)$/, "")
.split(", ")
.map(function(val) { return parseInt(val); });
if (rgba.length > 3 && rgba[rgba.length - 1] === 0) {
return backgroundColor(el.parentElement);
} else {
return rgba;
}
}
rgbから輝度を算出
こちらのページを参考にしました
osakana.factory - HSB 値と輝度の求め方
http://ofo.jp/osakana/cgtips/hsb.phtml
function luminance(rgba) {
var r = 0.298912;
var g = 0.586611;
var b = 0.114478;
return Math.floor(r * rgba[0] + g * rgba[1] + b * rgba[2]);
}
輝度120以下だと暗い感じがする
だいたい輝度120くらいがボーダーラインな気がします。HEXだと#777より暗いものは黒い文字が見難くなります。
以下のようにbodyに.is-dark
クラスを付与したりすると捗りますね。
var el = document.querySelector(".label");
var isDark = luminance(backgroundColor(el)) < 120;
if (isDark) {
document.querySelector("body").classList.add("is-dark");
}
.label {
color: #000;
}
.is-dark .label {
color: #fff;
}