在Sass中动态创建或引用变量


91

我试图在我的变量上使用字符串插值来引用另一个变量:

// 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样式的变量变量?

Answers:


49

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

9
@castus这是如何解决您的问题的?我遇到了一个非常类似的问题,我需要从列表中获取一个字符串值,并向其中添加$并将其用作变量。
cmegown 2013年

86

使用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; }

9
注意,这仍然不是“动态变量”。这只是从一开始就使用的列表列表的一种变体。
cimmanon

12
实际上,这会扩展到仅接受索引号作为指定变量的列表。它允许使用动态生成的名称来调用变量,该名称是通过传递的字符串的连接而创建的,这是请求的功能。
dibbledeedoo

3
这应该是公认的答案。尽管不是完全动态的,但它最好地模仿了所要求的功能。
thomaux '17

1
虽然有用,但此示例根本不创建任何变量
它的时间是

真正。尽管op的问题的标题是标题,但其文字并未描述变量的创建,因此我没有解决。但是,只是添加了一个与执行此操作相关的部分(尽管仍然使用map,而不是单个变量)。
dibbledeedoo

5

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

$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。
cmegown 2013年

3
这纯粹是一种不好的做法,您不希望最终遇到if条件的情况。将SASS映射与键值对结合使用,然后从中拉取值。
mystrdat

这个展示柜中主要是多余的-为什么您不打电话@include do-this($foo);呢?...但是,如果该函数确实执行了某项操作,但它只会通过...
这才有意义

2

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

如果在文件扩展名的末尾添加.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') %>
}

结果如下:

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

#target {
  width: $foo-baz;
}

粗略地讲,会导致以下css:

#target {
  width: 20px;
}

0

最近,我遇到了需要动态引用颜色的需求。

对于每个项目,我都有一个_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%);
  }
}

-2

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

该命令运行后,它将为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
    }
}

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


3
不幸的是,这不起作用:错误scss / components.scss(第71行:“ $ font-”之后的CSS无效:预期的“:”,是“ $ n:正常的$ n 1 ...”)
Krzysztof Romanowski

4
@castus,哎呀!抱歉,不清楚-我没有给出解决方案,而是再次解释了该问题
Om Shankar

15
可能不应该发布不允许的解决方案!
Rhyso 2015年

我宽度这将工作,但似乎我们不能通过sass创建变量?
v3nt
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.