【问题标题】:Set a variable in Sass depending on the selector根据选择器在 Sass 中设置变量
【发布时间】:2013-08-09 08:27:02
【问题描述】:

我的网站使用了几种不同的“主要”颜色。一般的 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 不是很好,因此我们将不胜感激。

【问题讨论】:

  • 无论如何,我知道变量不是答案。当 Sass 被转换成 CSS 时,变量是在编译时设置的。因此,如果您的所有 .content 有一个变量作为值,它们将具有相同的颜色。

标签: css variables sass


【解决方案1】:

我认为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);
}

那个SCSScompiles 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);
}

【讨论】:

  • 好吧,我担心我不得不这样做。感谢您的帮助,不胜感激。
  • 是否有机会按类更改“全局”变量? $颜色:#666; body.class-1 { $color : #fff; } p { $颜色; }
  • 2020:Sass 变量仍然不能单独工作,但您可以将一个 css 变量放在一个 sass 变量中,并根据 body 类对其进行更改,从而实现 OP 的需求。看我的回答:stackoverflow.com/a/62873203/1589851
【解决方案2】:

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

【讨论】:

  • 哪个开发人员会记住他们的颜色顺序?这是一个非常不切实际的解决方案。
  • @cimmanon 对。但是,如果您向前考虑,您现在可以使用 for 循环为每种颜色创建类 :) 我只想展示一种可能的方式
【解决方案3】:

如果您真的想搞怪,您还可以在单​​个变量中定义不同的配色方案,例如$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) 并使用 @each@each 中调用它,就像在上面的代码中一样,但关键是你没有必须为你的每个类写出规则。

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

【讨论】:

  • 感谢您的回答和链接,阅读都非常有趣。赞赏。
  • 非常感谢。我有一项艰巨的任务是在同一个页面上应用八种不同的配色方案,这为我节省了很多时间。哈克,但它的工作原理。干杯
【解决方案4】:

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

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

【讨论】:

    【解决方案5】:

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

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

    似乎对我有用。

    【讨论】:

    • 这只是从那时起无条件地覆盖$color1。如果它对你有用,我想这是巧合。
    【解决方案6】:

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

    【讨论】:

    • 这是关于颜色而不是关于字体的。所以与这个问题无关。
    • @Sato 问题是关于使用变量来设置 css 属性、颜色或字体等的值。
    • 有效,但欢迎提供有关您建议的答案的更多文档
    • 实际上问题在于使用范围之外的变量。我认为可以使用!global 标志(2014 年 3 月添加)。编辑:不,不是。
    【解决方案7】:

    对我来说,我的问题的明确答案是创建一个地图地图并通过它们循环如下:

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

    【讨论】:

      【解决方案8】:

      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 " class 否则它将是 $red-cosmo 默认颜色。

      【讨论】:

      • 这绝对是最好的答案。 Mixins 工作正常,但这正是 OP 想要的。
      • 太棒了!谢谢,+1
      • 优秀的答案 - 忽略其他所有内容并使用它!
      • 这种方法的唯一问题是你不能使用像 background-color:darken($primary-color, 10%) 这样的东西,因为技术上 $primary-color 不是一种颜色。
      • @AlexandreMartini 我猜你可以使用另一个 css 技巧来规避它,比如模拟变暗 => filter: brightness(0.x); 或者你可以在将颜色分配给 css 变量之前将其变暗
      猜你喜欢
      • 1970-01-01
      • 2013-08-08
      • 1970-01-01
      • 1970-01-01
      • 2015-05-29
      • 2017-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多