CSS 根据选择器在 Sass 中设置变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18112238/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 23:52:15  来源:igfitidea点击:

Set a variable in Sass depending on the selector

cssvariablessass

提问by Jrn

I've got a website that's using a few different ‘main' colors. The general HTML layout stays the same, only the colors change depending on the content.

我有一个使用几种不同“主要”颜色的网站。一般的 HTML 布局保持不变,只是颜色根据内容而变化。

I was wondering if I could set a color variable depending on the CSS selector. This way I can theme my website with a few variables and let Sass fill in the colors.

我想知道是否可以根据 CSS 选择器设置颜色变量。这样我就可以用一些变量来主题我的网站,并让 Sass 填充颜色。

For example:

例如:

$color-1: #444;
$color-2: #555;
$color-3: #666;
$color-4: #777;

body.class-1 {
  color-default: $color-1;
  color-main: $color-2;
}
body.class-2 {
  color-default: $color-3;
  color-main: $color-4;
}

/* content CSS */
.content {
  background: $color-default;
  color: $color-main;
}

I was thinking of using a mixin for this, but I was wondering if there's a better way to do this—with a function maybe? I'm not that great with Sass, so any help would be appreciated.

我正在考虑为此使用 mixin,但我想知道是否有更好的方法来做到这一点——也许是一个函数?我对 Sass 不是很好,所以任何帮助将不胜感激。

采纳答案by Rory O'Kane

I think a mixinis the answer. (As I wrote, variables won't work.)

我认为mixin就是答案。(正如我所写,变量将不起作用。)

@mixin content($color-default, $color-main) {
  background: $color-default;
  color: $color-main;
}

body.class-1 {
  @include content(#444, #555);
}

body.class-2 {
  @include content(#666, #777);
}

That SCSS compiles tothis CSS:

SCSS编译成这个 CSS:

body.class-1 {
  background: #444444;
  color: #555555; }

body.class-2 {
  background: #666666;
  color: #777777; }

If you wanted to group the color values together in your SCSS file, you could use variables in conjunction with the mixin:

如果您想在 SCSS 文件中将颜色值组合在一起,可以将变量与 mixin 结合使用:

$color-1: #444;
$color-2: #555;
$color-3: #666;
$color-4: #777;

body.class-1 {
  @include content($color-1, $color-2);
}

body.class-2 {
  @include content($color-3, $color-4);
}

回答by Elise

If you really want to get hacky you could also define your different color schemes in a single variable like $scheme1: class1 #333 #444, where the first value is always the name, and that is followed by all the colors in that scheme.

如果你真的想变得 hacky,你也可以在一个变量中定义不同的配色方案,比如$scheme1: class1 #333 #444,其中第一个值始终是名称,然后是该方案中的所有颜色。

You can then use @each:

然后您可以使用@each

// Define your schemes with a name and colors
$scheme1: class1 #444 #555;
$scheme2: class2 #666 #777;
$scheme3: class4 #888 #999;

// Here are your color schemes
$schemes: $scheme1 $scheme2 $scheme3;

@each $scheme in $schemes {
  // Here are the rules specific to the colors in the theme
  body.#{nth($scheme, 1)} .content {
    background-color: nth($scheme, 2);
    color: nth($scheme, 3);
  }
}

This will compile to:

这将编译为:

body.class1 .content {
  background-color: #444444;
  color: #555555; }

body.class2 .content {
  background-color: #666666;
  color: #777777; }

body.class4 .content {
  background-color: #888888;
  color: #999999; }

Obviously if you don't want to combine body.class1and .contentin your selectors, you could just specify a mixin content($main, $default)and call it inside the @eachusing nthjust like in the above code, but the point is you don't haveto write out a rule for each of your classes.

显然,如果你不想在你的选择器中组合body.class1.content,你可以像上面的代码一样指定一个 mixincontent($main, $default)并在@eachusing 中调用它nth,但关键是你不必为每个写出规则你的课。

EDITThere are lots of interesting answers on Creating or referencing variables dynamically in Sassand Merge string and variable to a variable with SASS.

编辑在 SassMerge string and variable to a variable with Sass 中动态创建或引用变量有很多有趣的答案。

回答by Tim Hartmann

If you don't want to use a variable for each color, you can use one variable for all kinds of colors. In the mixin you can choose the right color with nth. For instance, if you write the index of the color as 1, then you get the first color in the color variable.

如果不想为每种颜色使用一个变量,则可以为所有种类的颜色使用一个变量。在 mixin 中,您可以使用 选择正确的颜色nth。例如,如果您将颜色的索引写为1,那么您将获得颜色变量中的第一个颜色。

$colors: #444, #555, #666, #777;

@mixin content($color-default-num, $color-main-num) {
  background: nth($colors, $color-default-num);
  color: nth($colors, $color-main-num);
}

body.class-1 {
  @include content(1, 2);
}

回答by Naveed

UPDATE: its 2017 and variables does works!

更新:它的 2017 和变量确实有效!

@mixin word_font($page) {
  @font-face {
    font-family: p#{$page};
    src: url('../../static/fonts/ttf/#{$page}.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
  }

  .p#{$page} {
   font-family: p#{$page};
  }
}

// Loop and define css classes 
@for $i from 1 through 604 {
 @include word_font($i);
}

回答by Juho Valtonen

You can also create a mixing that use the ampersand parent selector. http://codepen.io/juhov/pen/gbmbWJ

您还可以创建使用和号父选择器的混合。http://codepen.io/juhov/pen/gbmbWJ

@mixin color {
  body.blue & {
    background: blue;
  }
  body.yellow & {
    background: yellow;
  }
}

回答by Francesco Meli

For me the definite answer to my problem was creating a map of maps and loopig through them as follows:

对我来说,我的问题的明确答案是创建地图地图并按如下方式遍历它们:

$pallettes: (
  light-theme: (
    container-color: red,
    inner-color: blue,
  ),
  dark-theme: (
    container-color: black,
    inner-color: gray,
  ),
);

@each $pallette, $content in $pallettes {
  .main.#{$pallette} {
    background-color: map-get($content, container-color);
    .inner-div {
      background-color: map-get($content, inner-color);
    }
  }
}

回答by Don Townsend

You can simply override your scss variables inside of the class wrapper:

您可以简单地覆盖类包装器内的 scss 变量:

$color1: red;
$color2: yellow;

header { background: $color1; }

.override-class {
  $color1: green;
  header { background: $color1; }
}

Seems to work for me.

似乎对我有用。