【问题标题】:Creating or referencing variables dynamically in Sass在 Sass 中动态创建或引用变量
【发布时间】:2012-01-21 22:28:31
【问题描述】:

我正在尝试对我的变量使用字符串插值来引用另一个变量:

// Set up variable and mixin
$foo-baz: 20px;

@mixin do-this($bar) {
    width: $foo-#{$bar};
}

// Use mixin by passing 'baz' string as a param for use $foo-baz variable in the mixin
@include do-this('baz');

但是当我这样做时,我收到以下错误:

未定义变量:“$foo-”。

Sass 是否支持 PHP 风格的变量变量?

【问题讨论】:

    标签: variables sass


    【解决方案1】:

    这实际上可以使用 SASS 映射而不是变量来实现。这是一个简单的例子:

    动态引用:

    $colors: (
      blue: #007dc6,
      blue-hover: #3da1e0
    );
    
    @mixin colorSet($colorName) {
        color: map-get($colors, $colorName);
        &:hover {
            color: map-get($colors, #{$colorName}-hover);
        }
    }
    a {
        @include colorSet(blue);
    }
    

    输出为:

    a { color:#007dc6 }
    a:hover { color:#3da1e0 }
    

    动态创建:

    @function addColorSet($colorName, $colorValue, $colorHoverValue: null) {
      $colorHoverValue: if($colorHoverValue == null, darken( $colorValue, 10% ), $colorHoverValue);
    
      $colors: map-merge($colors, (
        $colorName: $colorValue,
        #{$colorName}-hover: $colorHoverValue
      ));
    
      @return $colors;
    }
    
    @each $color in blue, red {
      @if not map-has-key($colors, $color) {
        $colors: addColorSet($color, $color);
      }
      a {
        &.#{$color} { @include colorSet($color); }
      }
    }
    

    输出为:

    a.blue { color: #007dc6; }
    a.blue:hover { color: #3da1e0; }
    a.red { color: red; }
    a.red:hover { color: #cc0000; }
    

    【讨论】:

    • 请注意,这仍然不是“动态变量”。这只是使用我们一直在使用的列表列表的一种变体。
    • 这实际上扩展了列表,它只接受索引号作为指定变量。它允许使用动态生成的名称调用变量,该名称由传递的字符串连接创建,这是请求的功能。
    • 这应该是公认的答案。虽然不是完全动态的,但这最好地模仿了请求的功能。
    • 虽然有用,但这个示例根本没有创建任何变量
    • 是的。尽管操作的问题的标题,其文本并没有描述变量的创建,所以我没有解决这个问题。但是,只是添加了一个与此相关的部分(尽管仍然使用地图,而不是奇异变量)。
    【解决方案2】:

    Sass 不允许动态创建或访问变量。但是,您可以将列表用于类似行为。

    scss:

    $list: 20px 30px 40px;    
    @mixin get-from-list($index) {
      width: nth($list, $index);
    }
    
    $item-number: 2;
    #smth {
      @include get-from-list($item-number);
    }
    

    css 生成:

    #smth {
      width: 30px; 
    }
    

    【讨论】:

    • @castus 这如何解决您的问题?我遇到了一个非常相似的问题,我需要从列表中获取一个字符串值并向其中添加一个 $ 并将其用作变量。
    【解决方案3】:

    每当我需要使用条件值时,我都会依赖函数。这是一个简单的例子。

    $foo: 2em;
    $bar: 1.5em;
    
    @function foo-or-bar($value) {
      @if $value == "foo" {
        @return $foo;
      }
      @else {
        @return $bar;
      }
    }
    
    @mixin do-this($thing) {
      width: foo-or-bar($thing);
    }
    

    【讨论】:

    • 我认为这正是我正在寻找的。这实质上是将传入的值传递给 mixin 并通过函数运行它。然后,根据一系列 if 语句,返回与变量相同的字符串值。是否有可能用可能无限数量的值来做到这一点?假设我们有一个包含许多字符串的列表,而不仅仅是 foo 或 bar。
    • 这纯粹是不好的做法,你不想以无穷无尽的 if 条件链告终。使用带有键值对的 SASS 映射并从中提取值。
    • 在这个展示中主要是多余的——你为什么不直接打电话给@include do-this($foo);? ...但是,如果该函数确实做了某事,但它只是传递...,这将是有道理的
    • @jave.web - 当您只需要 value 和给定属性时,SCSS functions 优于 mixins。您将使用 mixin,其中 property 和 value 都将在多个地方使用,或者 mixin 正在输出多个属性。
    【解决方案4】:

    如果您正在使用rails,并且可能在其他情况下,这是另一种选择。

    如果您将 .erb 添加到文件扩展名的末尾,Rails 将在将文件发送到 SASS 解释器之前处理文件上的 erb。这让你有机会在 Ruby 中做你想做的事。

    例如:(文件:foo.css.scss.erb)

    // Set up variable and mixin
    $foo-baz: 20px; // variable
    
    <%
    def do_this(bar)
      "width: $foo-#{bar};"
    end
    %>
    
    #target {
      <%= do_this('baz') %>
    }
    

    结果如下scss:

    // Set up variable and mixin
    $foo-baz: 20px; // variable
    
    #target {
      width: $foo-baz;
    }
    

    其中,粗略的,导致以下 css:

    #target {
      width: 20px;
    }
    

    【讨论】:

      【解决方案5】:

      我最近发现需要动态引用颜色。

      我为每个项目都有一个 _colours.scss 文件,我在其中定义了所有颜色一次并将它们作为变量引用。

      在我的 _forms.scss 文件中,我想为每种可用颜色设置按钮样式。通常是一项乏味的任务。这有助于我避免为每种不同的颜色编写相同的代码。

      唯一的缺点是您必须在编写实际的 css 之前列出每种颜色的名称和值。

      // $red, $blue - variables defined in _colours.scss
      $colours: 
        'red' $red,
        'blue' $blue;
      
      @each $name, $colour in $colours {
        .button.has-#{$name}-background-color:hover {
          background-color: lighten($colour, 15%);
        }
      }
      

      【讨论】:

      • 这个答案没有回答问题。您正在生成 CSS,而不是 SCSS...
      【解决方案6】:

      我需要在 sass 变量中使用动态颜色值。 经过大量搜索,我应用了这个解决方案:

      在 application.html.erb 中:

      <style>
        :root {
          --primary-color: <%= current_client.header_color %>;
          --body-color: <%= current_client.footer_color %>;
         }
      </style>
      

      在 variables.sass 中:

      $primary: var(--primary-color);
      

      然后你就可以开始了!

      参考:https://medium.com/angular-in-depth/build-truly-dynamic-theme-with-css-variables-539516e95837

      【讨论】:

        【解决方案7】:

        到目前为止,在 SASS 中创建动态变量是不可能的,因为您将添加/连接另一个需要在运行 sass 命令时解析一次的变量。

        命令一运行,就会抛出 Invalid CSS 的错误,因为你声明的所有变量都会跟随提升。

        一旦运行,您就不能在运行中再次声明变量

        如果我理解了这一点,请说明以下是否正确:

        你想声明下一部分(单词)是动态的变量

        类似

        $list: 100 200 300;
        
        @each $n in $list {
            $font-$n: normal $n 12px/1 Arial;
        }
        
        // should result in something like
        
        $font-100: normal 100 12px/1 Arial;
        $font-200: normal 200 12px/1 Arial;
        $font-300: normal 300 12px/1 Arial;
        
        // So that we can use it as follows when needed
        
        .span {
            font: $font-200;
            p {
               font: $font-100
            }
        }
        

        如果这是你想要的,恐怕到目前为止,这是不允许

        【讨论】:

        • 不幸的是,这不起作用:错误 scss/components.scss(第 71 行:“$font-”之后的无效 CSS:预期的“:”,是“$n:正常 $n 1...” )
        • @castus,哎呀!抱歉不清楚 - 我没有给出解决方案,而是再次解释问题
        • 可能不应该发布不允许的解决方案!
        • i width 这可行,但似乎我们无法通过 sass 创建变量?
        猜你喜欢
        • 1970-01-01
        • 2018-03-28
        • 1970-01-01
        • 1970-01-01
        • 2012-04-04
        • 2013-01-11
        相关资源
        最近更新 更多