Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Css 引导SASS变量覆盖挑战_Css_Variables_Twitter Bootstrap 3_Sass_Overriding - Fatal编程技术网

Css 引导SASS变量覆盖挑战

Css 引导SASS变量覆盖挑战,css,variables,twitter-bootstrap-3,sass,overriding,Css,Variables,Twitter Bootstrap 3,Sass,Overriding,编辑:此问题被标记为的副本,但请参阅此答案末尾的附录,查看该问题没有问到什么,以及答案没有回答什么 我正在开发一个使用Bootstrap3的web应用程序。我有一个基本的三层覆盖架构,其中1)Bootstrap的_variables.scs包含核心变量,2)u app-variables.scs包含覆盖Bootstrap的_variables.scs的基本应用变量,3)u client-variables.scs包含覆盖_app-variables.scs的特定于客户端的定制。#2或#3(或两者

编辑:此问题被标记为的副本,但请参阅此答案末尾的附录,查看该问题没有问到什么,以及答案没有回答什么

我正在开发一个使用Bootstrap3的web应用程序。我有一个基本的三层覆盖架构,其中1)Bootstrap的_variables.scs包含核心变量,2)u app-variables.scs包含覆盖Bootstrap的_variables.scs的基本应用变量,3)u client-variables.scs包含覆盖_app-variables.scs的特定于客户端的定制。#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不会影响基于$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.scs的完整副本复制到_app-variables.scs中,然后从那时起在_app-variables中进行修改。类似地,我将_app-variables.scs的完整副本复制到_client-variables.scs中,然后在_client-variables.scs中进行修改。从维护的角度来看,这显然不太理想(轻描淡写)——每次我对_variables.scs(在引导升级的情况下)或_app-variables.scs进行修改时,我都必须手动将更改向下传递到文件覆盖堆栈。此外,我还必须重新声明大量的变量,这些变量我甚至可能都没有覆盖

我发现LESS有他们所谓的“惰性加载”(lazy-loading),其中变量的最后一个定义被到处使用,甚至在最后一个定义之前。我相信这会解决我的问题。但是有人知道使用SASS的合适的变量覆盖解决方案吗

附录:
我已经想到了一种技巧:使用
以相反的顺序包含文件!所有变量的默认值
(在对的回答中也建议使用此技术)。这就是结果:

_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.scs中定义的变量,如果我想使用其他引导变量定义我的变量覆盖(或我自己的其他自定义变量),我需要这些变量。例如,我可能想做:
$custom var:$grid-ground-width/2

已解决,但我不知道这从哪个版本起作用。我相信这个解决方案一直都是可行的。测试日期:

> sassc --version

sassc: 3.2.1
libsass: 3.2.5
sass2scss: 1.0.3
我们将使用一个简化的环境,因此文件名与引导不匹配


挑战 给定我们不控制的框架(例如,仅安装在持续集成环境中,在我们的机器中不可用),该框架以以下方式表示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;
}
挑战是:

在您自己的应用程序的SCS中包括框架,以便

  • 框架中变量的依赖关系被保留并获得荣誉
  • 您可以依赖于默认值,但仍然可以更改框架依赖项的结果
  • 更准确地说:

    将框架包括在应用程序的SCS中,无论其在框架中的值是多少,都应确保
    $brand color
    始终与
    $brand warning
    相反

    解决方案 主文件如下所示:

    // application.scss
    
    @import "variables";
    @import "bootstrap/variables";
    @import "bootstrap/main";
    
    // _variables.scss
    
    %scope {
      @import "bootstrap/variables";
    
      $brand-primary: invert($brand-warning) !global;
    }
    
    您的变量文件如下所示:

    // application.scss
    
    @import "variables";
    @import "bootstrap/variables";
    @import "bootstrap/main";
    
    // _variables.scss
    
    %scope {
      @import "bootstrap/variables";
    
      $brand-primary: invert($brand-warning) !global;
    }
    
    结果: 解释
    %scope
    部分并不是SCSS的神奇之处,它只是一个名为
    scope
    的隐藏类,仅适用于以后使用
    @extend
    进行扩展的情况。我们使用它只是为了创建一个变量范围(因此得名)

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

    但这里有一个噱头。变量不是全局变量,而是局部变量。我们可以访问它们,但它们不会污染全局范围,后者将用于在框架内派生变量

    事实上,当我们想要定义变量时,我们希望它们是全局的,实际上我们使用的是
    !全局
    关键字向SCS发送信号,以将其存储在全局范围内


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

    这意味着在这个文件中

    %scope {
      @import "bootstrap/variables";
    
      $brand-primary: black !global;
    
      @debug $brand-primary;
    }
    
    @debug
    语句将打印在bootstrap/_variables.scs中定义的默认值,而不是
    黑色

    解决方案 将变量分为两部分:

    %scope {
      @import "bootstrap/variables";
    
      $brand-primary: black !global;
    
      @debug $brand-primary;
    }
    
    @debug $brand-primary;
    

    第二个
    @debug
    将正确打印
    黑色

    ,使用Bootstrap 4或Bootstrap sass在_variables.scss中设置的所有变量,使用!默认标志

    因此,如果在包含引导程序的_variables.scs之前设置变量,则当包含该变量时,_variables.scs中的值将被忽略

    所以我的sass条目文件可能如下所示

    @import "bootstrap-overrides";
    @import "bootstrap/scss/bootstrap-flex";
    @import "mixins/module";
    
    @import "custom";
    @import "variables";
    @import "mixins";
    
    @import "client-variables";
    @import "app-variables";
    @import "boostrap";
    @import "app-mixins";
    @import "client-mixins";