css – Bootstrap SASS变量覆盖挑战

前端之家收集整理的这篇文章主要介绍了css – Bootstrap SASS变量覆盖挑战前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
编辑:此问题被标记this one的副本,但请参阅本答案末尾附近的附录,以查看该问题没有提出的问题,以及答案没有回答的问题.

我正在使用一个使用Bootstrap 3的Web应用程序.我有一个基本的3层覆盖架构,其中1)Bootstrap的_variables.scss包含核心变量,2)_app-variables.scss包含覆盖Bootstrap的基本app变量_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按顺序逐行解释代码,它首先将$brand设置为蓝色,然后将$text设置为蓝色(因为$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.

但显然这不是我想要的 – 我希望我的$品牌改变会影响所有依赖它的东西.为了正确地覆盖变量,我现在只是将_variables.scss的完整副本复制到_app-variables.scss中,然后在_app-variables中进行修改.同样地,我将_app-variables.scss的完整副本复制到_client-variables.scss中,然后在_client-variables.scss中进行修改.从维护的角度来看,这显然不太理想(轻描淡写) – 每当我对_variables.scss(在Bootstrap升级的情况下)或_app-variables.scss进行修改时,我都必须手动将更改下来文件覆盖堆栈.而且我必须重新宣布一些我甚至可能无法克服的变量.

我发现LESS有他们所谓的“延迟加载”(http://lesscss.org/features/#variables-feature-lazy-loading),其中变量的最后一个定义在任何地方使用,甚至在最后一个定义之前.我相信这可以解决我的问题.但有没有人知道使用SASS的适当的变量覆盖解决方案?

附录:
这是我已经考虑过的一种技术:以相反的顺序包含文件,使用所有变量的默认值(这种技术也在this question的答案中提出).所以这是如何发挥作用:

_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;

解决方法

解决了,但我不知道这个版本的工作原理.我相信解决方案始终可用.测试:
> sassc --version

sassc: 3.2.1
libsass: 3.2.5
sass2scss: 1.0.3

我们将使用简化的环境,因此文件名与Bootstrap不匹配.

挑战

给定一个我们无法控制的框架(例如,仅在Continuous Integration环境中安装,在我们的机器中不可用),它以下列方式表示SCSS变量:

// bootstrap/_variables.scss

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

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

并在同一框架中给出一个使用变量的文件

// boostrap/main.scss

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

挑战是:

Include the framework in your own application’s SCSS in such a way that

  1. variables’ dependencies in the framework are preserved and honores;
  2. you can depend in on the default values but still be able to change the results on the framework dependencies.

更确切地说:

Include the framework in your application’s SCSS in such a way that $brand-color will always be the inverse of $brand-warning,whatever its value is in the framework.

文件看起来像这样:

// application.scss

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

你的变量文件看起来像这样:

// _variables.scss

%scope {
  @import "boostrap/variables";

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

结果:

> sassc main.scss

a {
  color: blue; }

说明

%scope部分不是SCSS的神奇之处,它只是一个名为scope的隐藏类,专门用于以后使用@extend扩展.我们只是用它来创建一个变量范围(因此得名).

在范围内,我们@import框架的变量.因为此时每个变量都没有值,每个变量都被创建并分配其默认值.

但这是噱头.变量不是全局的,而是本地的.我们可以访问它们,但它们不会污染全局范围,后者将用于在框架内派生变量.

事实上,当我们想要定义变量时,我们希望它们是全局变量,实际上我们使用!global关键字来指示SCSS将它们存储在全局范围内.

注意事项

有一个主要的警告:在定义它们时不能使用自己的变量.

这意味着在这个文件

%scope {
  @import "boostrap/variables";

  $brand-primary: black !global;

  @debug $brand-primary;
}

@debug语句将打印在boostrap / _variables.scss中定义的默认值,而不是黑色.

拆分变量分为两部分:

%scope {
  @import "boostrap/variables";

  $brand-primary: black !global;

  @debug $brand-primary;
}

@debug $brand-primary;

第二个@debug确实会正确打印黑色.

原文链接:https://www.f2er.com/css/217677.html

猜你在找的CSS相关文章