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

时间:2013-08-07 19:34:25

标签: css variables sass

我的网站使用了一些不同的“主要”颜色。一般的HTML布局保持不变,只有颜色会根据内容而改变。

我想知道是否可以根据CSS选择器设置颜色变量。通过这种方式,我可以使用一些变量为我的网站添加主题,让Sass填充颜色。

例如:

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

我正在考虑使用mixin,但我想知道是否有更好的方法来做这个 - 可能还有一个功能?我对Sass并不是那么好,所以任何帮助都会受到赞赏。

8 个答案:

答案 0 :(得分:22)

我认为mixin就是答案。 (As I wrote,变量不起作用。)

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

SCSS compiles to这个CSS:

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

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

如果您想在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);
}

答案 1 :(得分:9)

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

然后您可以使用@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);
  }
}

这将编译为:

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

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

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

显然,如果您不想在选择器中合并body.class1.content,则可以指定mixin content($main, $default)并使用{@eachnth内调用它{1}}就像上面的代码一样,但重点是你 没有为每个类写出规则。

编辑 Creating or referencing variables dynamically in SassMerge string and variable to a variable with SASS上有很多有趣的答案。

答案 2 :(得分:2)

sass文档的解释很好(https://sass-lang.com/documentation/variables):

  • Sass变量全部由Sass编译。 CSS变量包含在CSS输出中。

  • CSS变量对于不同的元素可以具有不同的值,但是Sass变量一次只能具有一个值。

  • Sass变量是必须的,这意味着如果您使用变量然后更改其值,则较早的使用将保持不变。 CSS变量是声明性的,这意味着如果更改该值,它将影响早期使用和以后使用。

我们可以利用sass和css变量的组合来实现所需的功能:

//theme colors
$red-cosmo: #e01019;
$green-cosmo: #00c398;
$primary-color: var(--primary-color);
body{
  --primary-color: #{$red-cosmo};
}
body.univers-ride{
  --primary-color: #{$green-cosmo};
}

因此,当我将我的sass变量称为$ primary-color时,它将打印为css变量“ var(-primary-color)”,仅当我的身体具有“ univers-ride”时,该变量才会扩展为$ green-cosmo ”类,否则将使用$ red-cosmo作为默认颜色。

答案 3 :(得分:1)

如果您不想为每种颜色使用变量,则可以将一个变量用于各种颜色。在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);
}

答案 4 :(得分:1)

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

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

答案 5 :(得分:1)

更新: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);
}

答案 6 :(得分:0)

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

$color1: red;
$color2: yellow;

header { background: $color1; }

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

似乎适合我。

答案 7 :(得分:0)

对我来说,对我的问题的肯定答案是创建地图并通过它们循环搜索,如下所示:

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