Установите переменную в 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;
}

Я думал об использовании микшинга для этого, но мне было интересно, может ли theres лучший способ сделать это - возможно, с функцией? Я не так хорош в Sass, поэтому любая помощь будет оценена.

Ответ 1

Я думаю, что миксин является ответом. (Как я уже писал, переменные не будут работать.)

@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 компилируется в этот 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);
}

Ответ 2

Если вы действительно хотите взломать, вы также можете определить свои разные цветовые схемы в одной переменной, например $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, используя nth, как в приведенном выше коде, но дело в том, что вам не нужно выписывать правило для каждого из ваших классов.

РЕДАКТИРОВАТЬ Есть много интересных ответов на Динамическое создание динамических ссылок в Sass или Объедините строку и переменную с переменной с помощью SASS.

Ответ 3

Если вы не хотите использовать переменную для каждого цвета, вы можете использовать одну переменную для всех видов цветов. В 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

Вы также можете создать микширование, использующее селектор ampersand parent. http://codepen.io/juhov/pen/gbmbWJ

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

Ответ 5

UPDATE: его 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

Вы можете просто переопределить переменные scss внутри оболочки класса:

$color1: red;
$color2: yellow;

header { background: $color1; }

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

Кажется, работает для меня.

Ответ 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);
    }
  }
}