Заполнитель Mixin SCSS / CSS

122

Я пытаюсь создать миксин для заполнителей в sass.

Это миксин, который я создал.

@mixin placeholder ($css) {
  ::-webkit-input-placeholder {$css}
  :-moz-placeholder           {$css}
  ::-moz-placeholder          {$css}
  :-ms-input-placeholder      {$css}  
}

Вот как я хотел бы включить миксин:

@include placeholder(font-style:italic; color: white; font-weight:100;);

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

Это возможно?

Шеннон Хочкинс
источник

Ответы:

254

Вы ищете @contentдирективу:

@mixin placeholder {
  ::-webkit-input-placeholder {@content}
  :-moz-placeholder           {@content}
  ::-moz-placeholder          {@content}
  :-ms-input-placeholder      {@content}  
}

@include placeholder {
    font-style:italic;
    color: white;
    font-weight:100;
}

Справочник SASS содержит дополнительную информацию, которую можно найти здесь: http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#mixin-content


Начиная с Sass 3.4, этот миксин может быть написан так, чтобы он работал как вложенным, так и невложенным:

@mixin optional-at-root($sel) {
  @at-root #{if(not &, $sel, selector-append(&, $sel))} {
    @content;
  }
}

@mixin placeholder {
  @include optional-at-root('::-webkit-input-placeholder') {
    @content;
  }

  @include optional-at-root(':-moz-placeholder') {
    @content;
  }

  @include optional-at-root('::-moz-placeholder') {
    @content;
  }

  @include optional-at-root(':-ms-input-placeholder') {
    @content;
  }
}

Использование:

.foo {
  @include placeholder {
    color: green;
  }
}

@include placeholder {
  color: red;
}

Вывод:

.foo::-webkit-input-placeholder {
  color: green;
}
.foo:-moz-placeholder {
  color: green;
}
.foo::-moz-placeholder {
  color: green;
}
.foo:-ms-input-placeholder {
  color: green;
}

::-webkit-input-placeholder {
  color: red;
}
:-moz-placeholder {
  color: red;
}
::-moz-placeholder {
  color: red;
}
:-ms-input-placeholder {
  color: red;
}
cimmanon
источник
1
Идеально, именно то, что мне нужно.
Шеннон Хочкинс
4
Не уверен, почему это было отменено, но ответ неверен. В начале каждого отдельного префикса поставщика необходимо указать «@». Взгляните на ответ Дэйва Хайна ниже, а еще лучше - попробуйте запустить этот код, и вы увидите, что он не работает.
Sk446
1
@RickM Он был отменен, потому что внесенные вами изменения не компилируются (ошибка: правила базового уровня не могут содержать символ, указывающий на родительский селектор '&'.). Это создает точный результат, который ищет OP, ответ, который вы утверждаете, «правильный» - нет.
cimmanon
Интересно ... через cli компилируете? Похоже, должен быть конфликт версий, поскольку у меня происходит прямо противоположное, и, судя по другим ответам, несколько других тоже.
Sk446
4
Да, CLI: Sass 3.3.0.rc.3 через Compass. Дважды проверено с помощью CodePen и Sassmeister . Это &необходимо, если вы хотите иметь селектор, как в случае input::-webkit-input-placeholderс миксином, но он не позволит вам использовать его на корневом уровне. sassmeister.com/gist/9469073 . Теперь, если вы используете LibSass, это другая история.
cimmanon
168

Я обнаружил, что подход, предложенный cimmanon и Куртом Мюллером, почти работает, но мне нужна родительская ссылка (т.е. мне нужно добавить префикс '&' к каждому префиксу поставщика); как это:

@mixin placeholder {
    &::-webkit-input-placeholder {@content}
    &:-moz-placeholder           {@content}
    &::-moz-placeholder          {@content}
    &:-ms-input-placeholder      {@content}  
}

Я использую миксин так:

input {
    @include placeholder {
        font-family: $base-font-family;
        color: red;
    }
}

При наличии родительской ссылки создается правильный css, например:

input::-webkit-input-placeholder {
    font-family: Constantia, "Lucida Bright", Lucidabright, "Lucida Serif", Lucida, "DejaVu Serif", "Liberation Serif", Georgia, serif;
    color: red;
}

Без родительской ссылки (&) перед префиксом поставщика вставляется пробел, и обработчик CSS игнорирует объявление; это выглядит так:

input::-webkit-input-placeholder {
    font-family: Constantia, "Lucida Bright", Lucidabright, "Lucida Serif", Lucida, "DejaVu Serif", "Liberation Serif", Georgia, serif;
    color: red;
}
Дэйв Хайн
источник
9
Большое спасибо. Вы сэкономили мне часы проб и ошибок, чтобы принятый ответ / решение сработали ...
tmuecksch
Стоит отметить, что ваши селекторы теперь немного переоценены (если вы действительно не хотите, чтобы он работал с вводом или элементами выбора). Добавление родительского селектора не позволяет вам использовать миксин без вложенности (что и искал OP).
cimmanon
1
Это &совершенно необходимо. Отредактировал популярный ответ, чтобы отразить это.
AlexKempton
1
+1. Некоторые браузеры ::placeholderтеперь поддерживают официальное свойство, поэтому я бы рекомендовал добавить его вверху:&::placeholder {@content}
Мэтт Браун,
11

Это для сокращенного синтаксиса

=placeholder
  &::-webkit-input-placeholder
    @content
  &:-moz-placeholder
    @content
  &::-moz-placeholder
    @content
  &:-ms-input-placeholder
    @content

используйте это как

input
  +placeholder
    color: red
igrossiter
источник
4
Я честно думаю, что это труднее читать, и к тому же он не такой аккуратный, как обычный синтаксис
Шеннон Хочкинс
Пытался поставить как комментарий, но он слишком большой. Я предпочитаю использовать этот синтаксис и не могу заставить выбранный ответ работать слишком легко. Я подумал, что это может быть полезно для кого-то другого.
igrossiter
2
это лучший, простой для понимания и внедрения.
arslion
3

Почему не что-то подобное?

Он использует комбинацию списков, итераций и интерполяции.

@mixin placeholder ($rules) {

  @each $rule in $rules {
    ::-webkit-input-placeholder,
    :-moz-placeholder,
    ::-moz-placeholder,
    :-ms-input-placeholder {
      #{nth($rule, 1)}: #{nth($rule, 2)};
    }  
  }
}

$rules: (('border', '1px solid red'),
         ('color', 'green'));

@include placeholder( $rules );
Курт Мюллер
источник
1
Это слишком сложно, я искал директиву по содержанию, но спасибо!
Шеннон Хочкинс
3

Чтобы избежать ошибок типа «Незакрытый блок: CssSyntaxError» компиляторами sass добавьте «;» до конца @content.

@mixin placeholder {
   ::-webkit-input-placeholder { @content;}
   :-moz-placeholder           { @content;}
   ::-moz-placeholder          { @content;}
   :-ms-input-placeholder      { @content;}
}
NoDirection
источник
0

Я использую точно такой же заполнитель sass mixin, как написал NoDirection. Я нахожу его в коллекции Sass Примеси здесь , и я очень доволен этим. Есть текст, который больше объясняет опции миксинов.

Неша Зорич
источник