Stack Overflowの design system では、CSSカラー値をコンパイルするためにLessを使用しています。
ホバー状態、境界線スタイリングの構築、背景色などのために頻繁に変更される_@orange-500
_のようなグローバルLess変数があります。
Lessでは、これはdarken(@orange-500, 5%)
と書かれています。ネイティブCSS変数を使用して同様のことを達成しようとしています。 CSS変数に切り替えると、テーマに依存する機能(Stack Exchange Network、Dark Modeなど)をより速く、CSSの行数を減らしてwhileメディアクエリでスワッピング変数を有効にする(ハイコントラスト、ダークモードなど)。
hsl
の色の明度値をオーバーライドするこの例は、変数がCSSクラスにスコープされている場合に機能します。
_.card {
--orange: hsl(255, 72%, var(--lightness, 68%));
background: var(--orange);
}
.card:hover {
--lightness: 45%;
}
_
_<div class="card">
Hello world
</div>
_
ただし、グローバルテーマをサポートするには、色変数を単一のスワップ可能な場所でグローバルに指定する必要がありますが、これは期待どおりに機能しません。
_:root {
--orange: hsl(255, 72%, var(--lightness, 68%));
}
.card {
background: var(--orange);
}
.card:hover {
--lightness: 45%;
}
_
_<div class="card">
Hello world
</div>
_
私は、_:root
_からhtml
またはbody
への切り替えを試みましたが、うまくいきませんでした。これに対する回避策はありますか?
簡単な解決策は、CSS変数を別のCSSファイルに配置し、必要に応じてそれを交換することです。たとえば、ダークモードをサポートするメディアクエリでスワップを実行したり、JavaScriptやプリベークテーマなどを使用したりできます。
これの良い点は、CSSファイルを変数の定義と入れ替えることで、CSSのレンダリングがリアルタイムで変更されることです。
ライト/ダークモードのメディアクエリを使用していると仮定します。ブラウザが「ダークモード」を理解して要求すると、最初のファイルのみがロードされます。ただし、ブラウザがこれらのメディアクエリを理解しない場合、両方のCSSファイルが読み込まれるため、「デフォルト」はlight.cssですが、後続のルールが以前のルールをオーバーライドします。
<link rel="stylesheet" href="/dark.css" media="(prefers-color-scheme: dark)">
<link rel="stylesheet" href="/light.css" media="(prefers-color-scheme: no-preference), (prefers-color-scheme: light)">
<!-- The main stylesheet -->
<link rel="stylesheet" href="/style.css">
これらのスタイルシートでは、:root
疑似クラスは基本的にHTMLと同じですが、ほとんどのブラウザでより高い特異性を持っています。
light.css
:root {
--text-color: #333;
--background-color: #fff;
}
dark.css
:root {
--text-color: #dadada;
--background-color: #333;
}
また、Travisがその回答で言及しているように、変数を単純化し、要素内で完全なルールを構築することは良い考えです。
style.css(メインスタイリングドキュメント)
body {
color: var(--text-color);
background-color: var(--background-color);
}
ちなみに、CSSで read upすることをお勧めしますcolor-scheme
プロパティを使用して、ネイティブブラウザー要素でのサポートを改善します。