Espaço reservado Mixin SCSS / CSS

122

Estou tentando criar um mixin para espaços reservados no sass.

Este é o mixin que eu criei.

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

É assim que eu gostaria de incluir o mixin:

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

Obviamente, isso não vai funcionar por causa de todos os dois pontos e ponto-e-vírgulas que estão sendo passados ​​para o mixin, mas ... eu realmente gostaria de apenas inserir estático css e passá-lo exatamente como a função acima.

Isso é possível?

Shannon Hochkins
fonte

Respostas:

253

Você está procurando a @contentdiretiva:

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

A Referência do SASS tem mais informações, que podem ser encontradas aqui: http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#mixin-content


A partir do Sass 3.4, esse mixin pode ser escrito assim para trabalhar tanto aninhado quanto não aninhado:

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

Uso:

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

@include placeholder {
  color: red;
}

Resultado:

.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
fonte
1
Perfeito, exatamente o que eu precisava.
Shannon Hochkins
4
Não sei por que isso foi revertido, mas a resposta está incorreta. Você precisa de '@' no início de cada um dos prefixos de fornecedores individuais. Dê uma olhada em uma resposta mais detalhada de Dave Hein, ou melhor ainda - tente executar esse código e verá que ele não funcionará.
Sk446
1
@RickM Foi revertida porque as modificações feitas não são compiladas (erro: as regras no nível base não podem conter o caractere de referência do seletor pai '&'.). Isso cria a saída exata que o OP está procurando, a resposta que você afirma ser "correta" não.
Cimmanon
Interessante ... você está compilando via CLI? Parece que deve haver um conflito de versão, já que acontece exatamente o oposto para mim e, a julgar por outras respostas, outras também.
Sk446
4
Sim, CLI: Sass 3.3.0.rc.3 via Compass. Verificado duas vezes com CodePen e Sassmeister . A &é necessário se você quer ser capaz de obter um seletor como input::-webkit-input-placeholdercom o mixin, mas vai impedi-lo de usá-lo no nível de raiz. sassmeister.com/gist/9469073 . Agora, se você estiver usando o LibSass, essa é uma história diferente.
Cimmanon
168

Eu achei a abordagem dada por cimmanon e Kurt Mueller quase funcionou, mas eu precisava de uma referência principal (ou seja, eu preciso adicionar o prefixo '&' a cada prefixo do fornecedor); como isso:

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

Eu uso o mixin assim:

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

Com a referência pai no local, o CSS correto é gerado, por exemplo:

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

Sem a referência pai (&), um espaço é inserido antes do prefixo do fornecedor e o processador CSS ignora a declaração; que se parece com isso:

input::-webkit-input-placeholder {
    font-family: Constantia, "Lucida Bright", Lucidabright, "Lucida Serif", Lucida, "DejaVu Serif", "Liberation Serif", Georgia, serif;
    color: red;
}
Dave Hein
fonte
9
Muito obrigado. Você me salvou horas de tentativa e erro, a fim de tornar o trabalho aceite resposta / solução ...
tmuecksch
Vale a pena notar que seus seletores agora estão um pouco superqualificados (a menos que você realmente não queira que ele funcione na entrada ou selecione elementos). Adicionar o seletor pai impede que você use o mixin sem aninhar (que era o que o OP estava procurando).
Cimmanon 9/03/2014
1
O &é totalmente necessário. Editou a resposta popular para refletir isso.
AlexKempton
1
+1. Alguns navegadores suportam a ::placeholderpropriedade oficial agora, então eu recomendo adicioná-lo na parte superior:&::placeholder {@content}
Matt Browne
11

Isto é para sintaxe abreviada

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

use-o como

input
  +placeholder
    color: red
igrossiter
fonte
4
Eu honestamente acho que isso é mais difícil de ler e também não é tão puro como a sintaxe normal
Shannon Hochkins
Tentei colocar como comentário, mas é muito grande. Prefiro usar essa sintaxe e não consegui fazer a resposta escolhida funcionar com muita facilidade. Eu pensei que poderia ser útil para outra pessoa.
igrossiter
2
este é o melhor, fácil de entender e implementar.
arslion
3

Por que não algo assim?

Ele usa uma combinação de listas, iteração e interpolação.

@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 );
Kurt Mueller
fonte
1
É um pouco complicado, eu estava procurando pela diretiva de conteúdo, mas obrigado!
Shannon Hochkins
3

Para evitar que erros 'Unclosed block: CssSyntaxError' sejam lançados de compiladores sass, adicione um ';' até o final de @content.

@mixin placeholder {
   ::-webkit-input-placeholder { @content;}
   :-moz-placeholder           { @content;}
   ::-moz-placeholder          { @content;}
   :-ms-input-placeholder      { @content;}
}
Sem direção
fonte
0

Eu uso exatamente o mesmo espaço reservado sass mixin que a NoDirection escreveu. Eu o encontro na coleção sass mixins aqui e estou muito satisfeito com isso. Há um texto que explica mais uma opção de mixins.

Nesha Zoric
fonte