Creating or referencing variables dynamically in Sass

I'm trying to use string interpolation on my variable to reference another variable:

// 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');

But when I do this, I get the following error:

Undefined variable: "$foo-".

Does Sass support PHP-style variable variables?

107044 次浏览

Anytime I need to use a conditional value, I lean on functions. Here's a simple example.

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

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

返回文章页面

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

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

一旦命令运行,它将抛出一个无效的 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
}
}

如果这是你想要的,恐怕现在,这是 不允许

如果您正在使用 Rail,或者在其他情况下,这里还有另一个选择。

如果你加上。Erb 到文件扩展名的末尾,Rails 将在发送文件到 SASS 解释器之前处理 erb。这给了你一个在 Ruby 中做你想做的事情的机会。

例如: (File: 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') %>
}

Results in the following scss:

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


#target {
width: $foo-baz;
}

粗糙的结果是以下 css:

#target {
width: 20px;
}

这实际上是可以用 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; }

最近我偶然发现需要动态引用一种颜色。

I have a _colours.scss file for every project, where I define all my colours once and reference them as variables throughout.

在 my _ 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%);
}
}

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

在 application.html.erb 中:

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

在变量.sass:

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

然后你就可以走了!

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