web-dev-qa-db-ja.com

Bootstrap SASS変数オーバーライドチャレンジ

編集:この質問は これ の重複としてマークされましたが、この回答の終わり近くにある補遺を参照してくださいその質問が何を尋ねないのか、そして答えが何を答えないのか。

Bootstrap 3.基本的な3層オーバーライドアーキテクチャを使用しているWebアプリに取り組んでいます。1)Bootstrapの_variables.scssにはコア変数が含まれています。2)_app-variablesです。 scssには、Bootstrapの_variables.scssをオーバーライドする基本アプリ変数が含まれています。3)_client-variables.scssには、_app-variables.scssをオーバーライドするクライアント固有のカスタマイズが含まれています。 #2または#3のいずれか(または両方)を空のファイルにすることができます。したがって、オーバーライドの順序は次のとおりです。

_variables.scss // Bootstrap's core
_app-variables.scss // App base
_client-variables.scss // Client-specific

理論的には十分に単純ですが、変数が他の変数として定義されている「変数の依存関係」と呼ぶものが原因で問題が発生します。例えば:

$brand: blue;
$text: $brand;

ここで、上記の変数が_variables.scssで定義されているとしましょう。次に、_app-variables.scssで、$ brand変数のみをオーバーライドして赤にします:$brand: red。 SASSはコードを1行ずつ順番に解釈するため、最初に$ brandを青に設定し、次に$ textを青に設定し(その時点で$ brandは青であるため)、最後に$ brandを赤に設定します。したがって、最終的な結果として、後で$ brandを変更しても、$ brandの古い値に基づいていた変数には影響しません。

_variables.scss
---------------------
$brand: blue;
$text: $brand; // $text = blue
.
.
.

_app-variables.scss
---------------------
$brand: red; // this does not affect $text, b/c $text was already set to blue above.

しかし、明らかにそれは私が望んでいることではありません-$ brandの変更がそれに依存するすべてに影響を与えることを望んでいます。変数を適切にオーバーライドするために、私は現在、_variables.scssの完全なコピーを_app-variables.scssに作成し、その時点から_app-variables内で変更を加えています。同様に、_app-variables.scssの完全なコピーを_client-variables.scssに作成し、その時点で_client-variables.scss内で変更を加えています。明らかに、これはメンテナンスの観点からは理想的(控えめな表現)ではありません-_variables.scss(Bootstrap upgrade)または_app-variables.scssの場合)に変更を加えるたびに、ファイルオーバーライドスタックに変更を手動で細流化する必要があります。さらに、オーバーライドすらできない可能性のある大量の変数を再宣言する必要があります。

LESSには、変数の最後の定義が使用される「遅延読み込み」( http://lesscss.org/features/#variables-feature-lazy-loading )と呼ばれるものがあることがわかりました。最後の定義の前でさえ、どこでも。これで私の問題は解決すると思います。しかし、SASSを使用した適切な変数オーバーライドソリューションを知っている人はいますか?

補遺:
これは私がすでに考えた1つのテクニックです:すべての変数に!defaultを使用して、逆の順序でファイルを含めます(このテクニックは この質問 への回答でも提案されました)。したがって、これがどのように実行されるかを次に示します。

_app-variables.scss
---------------------
$brand: red !default; // $brand is set to red here, overriding _variables.scss's blue.
.
.
.


_variables.scss
---------------------
$brand: blue !default; // brand already set in _app-variables.scss, so not overridden here.
$text: $brand !default; // $text = red (desired behavior)

したがって、その解はほぼ完璧です。 ただし、オーバーライドファイルで、Bootstrapの_variablesで定義された変数にアクセスできません.scss。他のBootstrap変数を使用して、変数のオーバーライド(または独自の追加のカスタム変数)を定義する場合に必要です。たとえば、次のようにします。$custom-var: $grid-Gutter-width / 2;

14
jbyrd

解決しましたが、これがどのバージョンから機能するのかわかりません。私believeソリューションは常に利用可能であった可能性があります。テスト済み:

> sassc --version

sassc: 3.2.1
libsass: 3.2.5
sass2scss: 1.0.3

簡略化された環境を使用するため、ファイル名はBootstrapのファイル名と一致しません。


チャレンジ

SCSS変数を次のように表現するフレームワーク(たとえば、継続的インテグレーション環境にのみインストールされ、マシンでは使用できない)を考えると、次のようになります。

// bootstrap/_variables.scss

$brand-primary: #f00 !default;
$brand-warning: #f50 !default;

$link-color: $brand-primary !default;

そして、変数を使用する同じフレームワーク内のファイルを指定します。

// bootstrap/main.scss

a:link, a:visited {
  color: $link-color;
}

課題は次のとおりです。

次のような方法で、フレームワークを独自のアプリケーションのSCSSに含めます。

  1. 変数の依存関係フレームワーク内は保持され、尊重されます。
  2. デフォルト値に依存することはできますが、フレームワークの依存関係の結果を変更することはできます。

より正確に:

$brand-colorがフレームワーク内の値に関係なく常に$brand-warningの逆になるように、フレームワークをアプリケーションのSCSSに含めます。

解決

メインファイルは次のようになります。

// application.scss

@import "variables";
@import "bootstrap/variables";
@import "bootstrap/main";

そして、変数ファイルは次のようになります。

// _variables.scss

%scope {
  @import "bootstrap/variables";

  $brand-primary: invert($brand-warning) !global;
}

結果:

> sassc main.scss

a {
  color: blue; }

説明

%scopeの部分は、SCSSの魔法ではなく、scopeという名前の非表示のクラスであり、@extendを使用した後の拡張機能でのみ使用できます。可変スコープを作成するためだけに使用しています(そのため、名前が付けられています)。

スコープ内では、フレームワークの変数を@importします。現時点では、各変数に値がないため、すべての変数が作成され、その!default値が割り当てられます。

しかしここに仕掛けがあります。変数グローバルではなくローカル。それらにアクセスすることはできますが、後でフレームワーク内の変数を導出するために使用されるグローバルスコープを汚染することはありません。

実際、変数を定義するときは、変数をグローバルにする必要があります。実際、!globalキーワードを使用して、SCSSに変数をグローバルスコープに格納するように通知します。


警告

主な注意点が1つあります。定義中に独自の変数を使用することはできません

つまり、このファイルでは

%scope {
  @import "bootstrap/variables";

  $brand-primary: black !global;

  @debug $brand-primary;
}

@debugステートメントは、black

解決

変数を2つの部分に分割します。

%scope {
  @import "bootstrap/variables";

  $brand-primary: black !global;

  @debug $brand-primary;
}

@debug $brand-primary;

2番目の@debugは実際にblackを正しく出力します。

17

Bootstrap 4またはbootstrap-sassを使用して、_variables.scssに設定されているすべての変数に!defaultフラグを設定します。

したがって、ブートストラップの_variables.scssが含まれる前に変数を設定した場合、それが含まれると、_variables.scssの値は無視されます。

したがって、私のsassエントリファイルは次のようになります...

@import "bootstrap-overrides"; @import "bootstrap/scss/bootstrap-flex"; @import "mixins/module";

3
mryarbles

Bootstrap 4のアルファ6では、mryarblesが説明する方法で、_variables.scssのすべての変数を_custom.scssでオーバーライドできます。ただし、オーバーライドは他の要素にカスケードされません。包含順序は次のとおりです。

@import "variables";
@import "mixins";
@import "custom";

これをに変更すると

@import "custom";
@import "variables";
@import "mixins";

期待どおりに動作します。

0
rakensi

BS4 dev ブランチの_custom.scssファイルが削除されました。次の順序でインポートを並べ替えてみてください。

セットアップ

@import "client-variables";
@import "app-variables";
@import "boostrap";
@import "app-mixins";
@import "client-mixins";

必ずブーストラップ変数ファイル_variables.scssの内容をapp-variablesclient-variablesにコピーしてください。さらにオーバーライドできるように、各変数の横に!defaultを残します。

説明

すべてのbootstrap変数は!defaultで宣言されています。Sassから 参照

変数がまだ割り当てられていない場合は、値の最後に!defaultフラグを追加することで、変数に割り当てることができます。つまり、変数がすでに割り当てられている場合、再割り当てされることはありませんが、まだ値がない場合は、値が割り当てられます。

  • ブートストラップは、最上位ですでに定義されているすべての変数を尊重し、app_variablesの優先度を高くし、client_variablesの優先度を高くします。
  • すべての変数宣言をbootstrap _variablesからapp-variablesおよびclient-variablesにコピーして、必要に応じてカスタム変数を作成できるようにする必要があります(欠点はすべてのbootstrap update)で維持するのが難しいこと
  • すべての変数がapp-mixinsおよびclient-mixinsで使用できるようになりました
0
superhubo