web-dev-qa-db-ja.com

内部スコープからの:root CSS変数のオーバーライド

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への切り替えを試みましたが、うまくいきませんでした。これに対する回避策はありますか?

11
Aaron Shekey

簡単な解決策は、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プロパティを使用して、ネイティブブラウザー要素でのサポートを改善します。

0
Bryce Howitson