Передать список в mixin как один аргумент с SASS

Мне нравится делать mixins с SASS, которые помогают мне сделать хорошую совместимость между браузерами. Я хочу создать mixin, который выглядит так:

@mixin box-shadow($value) {
    box-shadow: $value;
    -webkit-box-shadow: $value; 
    -moz-box-shadow: $value; 
}

к которому я могу передать что-то вроде этого:

@include box-shadow(inset -2px -2px 2px rgba(0,0,0,0.5), inset 1px 1px 2px rgba(255,255,255,0.5), inset 0px 0px 0px 1px #ff800f);

в результате чего будет что-то вроде этого:

box-shadow: inset -2px -2px 2px rgba(0,0,0,0.5), inset 1px 1px 2px rgba(255,255,255,0.5),inset 0px 0px 0px 1px #ff800f;
-moz-box-shadow: inset -2px -2px 2px rgba(0,0,0,0.5), inset 1px 1px 2px rgba(255,255,255,0.5),inset 0px 0px 0px 1px #ff800f;
-webkit-box-shadow: inset -2px -2px 2px rgba(0,0,0,0.5), inset 1px 1px 2px rgba(255,255,255,0.5),inset 0px 0px 0px 1px #ff800f; 

Однако это не работает, потому что компилятор думает, что я пытаюсь передать mixin 3 аргумента. box-shadow принимает переменное количество разделенных запятыми битов, поэтому я не могу просто определить mixin как box-shadow($1,$2,$3).

Я пробовал пропустить

@include box-shadow("inset -2px -2px 2px rgba(0,0,0,0.5), inset 1px 1px 2px rgba(255,255,255,0.5), inset 0px 0px 0px 1px #ff800f");

и он скомпилирован, но на самом деле не отображал стили.

Любые советы о том, как разрешить это?

Ответ 1

Переменные аргументы

Иногда для mixin имеет смысл принимать неизвестное количество аргументов. Например, mixin для создания теней коробок может принимать любое количество теней в качестве аргументов. В этих ситуациях Sass поддерживает "переменные аргументы", которые являются аргументами в конце объявления mixin, которые принимают все оставшиеся аргументы и упаковывают их как список. Эти аргументы выглядят как обычные аргументы, но за ними следуют.... Например:

@mixin box-shadow($shadows...) {
  -moz-box-shadow: $shadows;
  -webkit-box-shadow: $shadows;
  box-shadow: $shadows;
}

.shadows {
  @include box-shadow(0px 4px 5px #666, 2px 6px 10px #999);
}

через: http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#variable_arguments

Ответ 2

SASS 3.1 или менее

Примечание. Если вы используете SASS 3.2+, используйте функцию Variable Arguments, как предлагает rzar.

Просто используйте интерполяцию строк в самой микшике, например:

@mixin box-shadow($value) {
  -webkit-box-shadow: #{$value};               // #{} removes the quotation marks that
  -moz-box-shadow: #{$value};                  // cause the CSS to render incorrectly.
  box-shadow: #{$value};
}

// ... calling it with quotations works great ...
@include box-shadow("inset -2px -2px 2px rgba(0,0,0,0.5), inset 1px 1px 2px rgba(255,255,255,0.5), inset 0px 0px 0px 1px #ff800f");

Спасибо за отзыв Райана.

Ответ 3

Использовать строчную интерполяцию

@include box-shadow(#{"inset -2px -2px 2px rgba(0,0,0,0.5), inset 1px 1px 2px rgba(255,255,255,0.5), inset 0px 0px 0px 1px #ff800f"});

Ответ 4

Есть много способов сделать это, лучший способ - использовать mixin так:

@mixin box-shadow($value...) {
  -webkit-box-shadow: $value;               
  -moz-box-shadow: $value;                  
  box-shadow: $value;
}

И включите его вот так:

@include box-shadow(inset 0 1px 0 #FFD265, 0 0 0 1px #912E01, 0 0 0 7px rgba(0, 0, 0, .1), 0 1px 4px rgba(0, 0, 0, .6));

или

@mixin box-shadow($value) {
      -webkit-box-shadow: #{$value};               
      -moz-box-shadow: #{$value};          
      box-shadow: #{$value};
}

И включите его вот так:

@include box-shadow("inset 0 1px 0 #FFD265, 0 0 0 1px #912E01, 0 0 0 7px rgba(0, 0, 0, .1), 0 1px 4px rgba(0, 0, 0, .6)");

или

@mixin box-shadow($value) {
      $value: unquote($value);
      -webkit-box-shadow: $value;               
      -moz-box-shadow: $value;          
      box-shadow: $value;
}

или

@mixin box-shadow($value) {
  -webkit-box-shadow: $value;               
  -moz-box-shadow: $value;                  
  box-shadow: $value;
}

И включите его вот так:

@include box-shadow((inset 0 1px 0 #FFD265, 0 0 0 1px #912E01, 0 0 0 7px rgba(0, 0, 0, .1), 0 1px 4px rgba(0, 0, 0, .6)));

Сасс очень мощный:)

Ответ 5

Я хочу указать, что вы также можете передать значение, используя имя аргумента, когда вы вызываете mixin:

@mixin shadow($shadow: 0 0 2px #000) {
    box-shadow: $shadow;
    -webkit-box-shadow: $shadow; 
    -moz-box-shadow: $shadow; 
}

.my-shadow {
  @include shadow($shadow: 0 0 5px #900, 0 2px 2px #000);
}

Обратите внимание, что scss имеет область действия, поэтому $shadow все равно сохранит значение mixin, если оно будет использовано позже. менее я считаю, страдает от переназначения в этом сценарии

Ответ 6

Это не скомпилируется:

+box-shadow(inset 0 1px 0 #FFD265, 0 0 0 1px #912E01, 0 0 0 7px rgba(0, 0, 0, .1), 0 1px 4px rgba(0, 0, 0, .6))

это компилируется:

+box-shadow((inset 0 1px 0 #FFD265, 0 0 0 1px #912E01, 0 0 0 7px rgba(0, 0, 0, .1), 0 1px 4px rgba(0, 0, 0, .6)))

То есть, добавьте скобки вокруг списка теней, разделенных запятыми, и он должен работать:

+box-shadow( (myshadow1, myshadow2, ...) )