web-dev-qa-db-ja.com

Twitterブートストラップ4の$ theme-colors配列でCSS変数を使用することは可能ですか?

bootstrap 4では、次の配列を使用してデフォルトの色を定義および/またはオーバーライドできます:( ここに記載されているとおり

_$theme-colors: (
    "primary": #001122, /*override*/
    "color-1": red, /*new color*/
    "color-2": black, /*new color*/
    "color-3": white /*new color*/
);
_

ユーザーごとにカスタムテーマの色を作成したい。ユーザーは、ボディのクラスに基づいて私が定義したさまざまなカラーパレットを選択できます。

BodyタグのCSS変数にテーマの色を定義して、独自のスタイルを作成する新しいファイルを作成しました。

_body {
  &.color-pallette-red {
    --theme-color-1: red;
    --theme-color-2: black;
    --theme-color-3: white;

    color: var(--theme-color-1); /*red*/
  }

  &.color-pallette-yellow {
    --theme-color-1: yellow;
    --theme-color-2: black;
    --theme-color-3: white;

    color: var(--theme-color-1); /*yellow*/
  }
}
_

しかし、このように、bootstrap色はもちろん上書きされません...

bootstrap前述の配列にCSS変数を貼り付けて、bootstrapが私の色を使用していることを確認しました:

_$theme-colors: (
    "color-1": var(--theme-color-1),
    "color-2": var(--theme-color-2),
    "color-3": var(--theme-color-3)
);
_

しかし、これはコンパイルスクリプトの実行後にError: $color2: var(--theme-color-1) is not a color. @return mix($color-base, $color, $level * $theme-color-interval);を返します。だからブートストラップ/コンパイラは私のCSS変数を色として認識しませんでした...

要約すると、次のようになります。変更bootstrapボディクラスに基づく色。これを達成する方法を誰かが知っていますか?

15
djl

SASSはプリプロセッサであるため、その変数はその時点でコンパイルされないため、マップ内のCSS変数を直接setすることはできません。さらにbootstrapは向きを変えて、これらのテーマKVPを:root変数に変換するので、基本的に同じことを2回実行します。これを回避する1つの方法は、一般的なSASSを介してマップ自体をタップすることです。メソッド:

  ...
  property: map-get(map-merge($theme-colors,($key : $color)),$key)
  ...

特定のKVPを設定すると、他の場所で使用できるようにグローバルに使用できるようになります。

この時点で、CSS var()を使用することは任意ですが、すべてのベースをカバーするために、theme-color("color-2")を再設定して呼び出すのではなく、テーマを設定して変数を変更できます。 。

この完全な例は次のとおりです。

@import "bootstrap";

$theme-colors: (
    "primary": #001122,
    "color-1": black, 
    "color-2": black, 
    "color-3": black 
);

@function set-theme-color($key, $color) {
  @return map-get(map-merge($theme-colors,($key : $color)),$key);
}

@mixin theme($color1, $color2, $color3) {
  background-color: set-theme-color("color-1", $color1);

  h1 {
    color: set-theme-color("color-2", $color2);
  }
  h2 {
    color: set-theme-color("color-3", $color3);
  }
}

main {
  &.theme-purple {
    @include theme(purple,cornflowerblue,white);
    /* example demonstrating color3 can change */
    --color-3: orange;
  }

  &.theme-red {
    @include theme(red,black,white);
  }
}

h2 { 
  color: theme-color("color-2"); 
}
h3 {
/* example demonstrating color3 changed */
  color: var(--color-3);
}
<script src="http://codeply.com/js/embed.js"></script><div data-codeply="o9n2ST6HW5" ></div>

この例は、1つのテーマが変数を設定し、他のテーマが設定しない場合も示しています。選択したテーマの色は無効であり、プロパティは継承に戻ります。

codeplyデモ

6
soulshined

SASSで色にCSS変数を使用できない理由

色にCSS変数を使用できない理由は、SASSのdarken()およびlighten()のような関数です。コンピュータが命令を受け取ったときに何をすべきかわからないと想像することができます:darken( var(--color), 20%);知らない値を変更することはできません。

色を変更する関数を使用しない場合はどうなりますか?

実際、それは実際に機能するはずです。 bootstrapライブラリには、これらの関数を使用するscssファイルが含まれています。すべてのbootstrapコードを確認し、色を変更する関数を削除できます。もちろん、 bootstrapを将来更新すると、サイトのスタイリングが不思議なほどクラッシュし、誰かがあなたを怒らせます。このオプションはお勧めできません。

しかし... CSSがそれを行うことができる場合、SASSを使用してできますか?

はい!これが答えです。そして、それはかなりの仕事になるでしょう。別の変数を使用して色を設定する場合は、それらの色に--colorのようなSASS変数を使用できます。例えば。:

  $color1: var(--color-1);

  /* It may seem completely redundant to  
     to define CSS variable here. But 
     it isn't. You can change the variables in 
     your browser now with JavaScript, which 
     may affect multiple elements.
  */
  :root{
    --color-1: purple;
  }
  /* An example on how to change the page
     styling with an id.        
  */
  :root#dark-mode{
    --color-1: black;
  }

  .alert-success{
    background-color: $color1;
  }
  .alert-danger{
    background-color: $color1;
  }

幸い、bootstrap 4人の開発者がセレクターをシンプルに保つのにかなり良い仕事をしているので、上書きするのはそれほど難しくありません。bootstrap css。bootstrap scssファイルで上書きするSASS変数を検索して、すべてのケースをカバーすることを確認できます。

幸運を!

2
RMo

私は他の答えが好きですが、プロジェクトのスコープのニーズに合わない場合は、別のソリューションも提供したいと思います。別のオプション、そして私はあなたのニーズにより直接的であると思いますが、スタイルシートをカスケードすることができます。プロジェクトツリーが次のようであると想定します。

`css\
  `--main.css
  `--themes.css <- compiled themes.sass
  `--themes.sass
`index.html

どこ index.html

  ...
  <head>
    <link rel="stylesheet" type="text/css" media="screen" href="css/main.css">
    <link rel="stylesheet" type="text/css" media="screen" href="css/themes.css">
  </head>

  <body>
    <main class="theme-purple">
      <h1>Hello World</h1>
      <h2>SASS is fun!</h2>
    </main>

    <main class="theme-red">
      <h1>Hello World</h1>
      <h2>SASS is fun!</h2>
    </main>
  </body>
  ...

どこ main.css

.theme-red {
  --theme-color-1: red;
  --theme-color-2: black;
  --theme-color-3: white;
}
.theme-purple {
  --theme-color-1: purple;
  --theme-color-2: cornflowerblue;
  --theme-color-3: white;
}

どこ themes.sass

@import "node_modules/bootstrap/scss/bootstrap";

$theme-colors: (
  "primary": #001122, 
  "color-1": var(--theme-color-1), 
  "color-2": var(--theme-color-2), 
  "color-3": var(--theme-color-3)
);

main { 
  background-color: theme-color("color-1");
}
h1 { 
  color: theme-color("color-2");
}
h2 { 
  color: theme-color("color-3")
}

これにより、CSS変数がコンパイルされる機会がありました。 node.jsサーバーでテストしたので、必要に応じてインポート文を変更する必要があります

1
soulshined