Marcador de posición Mixin SCSS / CSS

130

Estoy tratando de crear un mixin para marcadores de posición con descaro.

Este es el mixin que he creado.

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

Así es como me gustaría incluir el mixin:

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

Obviamente, esto no va a funcionar debido a todos los dos puntos y punto y coma que se pasan al mixin, pero ... realmente me gustaría ingresar CSS estático y pasarlo exactamente como la función anterior.

es posible?

265

Estás buscando la @contentdirectiva:

@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 Reference tiene más información, que se puede encontrar aquí: http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#mixin-content


A partir de Sass 3.4, este mixin se puede escribir así para que funcione tanto anidado como no anidado:

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

Producción:

.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;
}
7
  • 1
    Perfecto, exactamente lo que necesitaba. 19 de junio de 2013 a las 2:52
  • 4
    No estoy seguro de por qué se revirtió esto, pero la respuesta es incorrecta. Necesita '@' al comienzo de cada uno de los prefijos de proveedores individuales. Eche un vistazo a una respuesta más abajo de Dave Hein, o mejor aún: intente ejecutar este código y verá que no funcionará.
    Sk446
    10 mar 14 a las 10:06
  • 1
    @RickM Se revirtió porque las modificaciones que realizó no se compilan (error: las reglas de nivel base no pueden contener el carácter de referencia del selector principal '&'). Esto crea la salida exacta que el OP está buscando, la respuesta que usted afirma es "correcta" no. 10 de marzo de 2014 a las 12:27
  • Interesante ... ¿estás compilando a través de cli? Parece que debe haber un conflicto de versiones, ya que a mí me ocurre exactamente lo contrario y, a juzgar por otras respuestas, algunas otras también.
    Sk446
    10 mar 14 a las 16:47
  • 4
    Sí, CLI: Sass 3.3.0.rc.3 a través de Compass. Comprobado dos veces con CodePen y Sassmeister . El &es necesario si quieres poder conseguir un selector como input::-webkit-input-placeholdercon el mixin, pero te impedirá usarlo a nivel raíz. sassmeister.com/gist/9469073 . Ahora bien, si está utilizando LibSass, esa es una historia diferente. 10 mar 14 a las 16:58
171

Encontré que el enfoque dado por cimmanon y Kurt Mueller casi funcionó, pero necesitaba una referencia principal (es decir, necesito agregar el prefijo '&' a cada prefijo de proveedor); como esto:

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

Yo uso el mixin así:

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

Con la referencia principal en su lugar, se genera el CSS correcto, por ejemplo:

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

Sin la referencia principal (&), se inserta un espacio antes del prefijo del proveedor y el procesador CSS ignora la declaración; que se ve así:

input::-webkit-input-placeholder {
    font-family: Constantia, "Lucida Bright", Lucidabright, "Lucida Serif", Lucida, "DejaVu Serif", "Liberation Serif", Georgia, serif;
    color: red;
}
4
  • 9
    Muchísimas gracias. Me ahorraste horas de prueba y error para que la respuesta / solución aceptada funcione ... 23 feb 2014 a las 1:02
  • Vale la pena señalar que sus selectores ahora están ligeramente sobrecalificados (a menos que realmente no desee que funcione en la entrada o en los elementos seleccionados). Agregar el selector principal le impide usar el mixin sin anidar (que era lo que estaba buscando el OP). 9 de marzo de 2014 a las 14:34
  • 1
    El &es totalmente necesario. Editó la respuesta popular para reflejar esto. 30 de mayo de 2014 a las 11:41
  • 1
    +1. Algunos navegadores admiten la ::placeholderpropiedad oficial ahora, por lo que recomendaría agregar esto en la parte superior:&::placeholder {@content} 10 de agosto de 2017 a las 16:13
11

Esto es para la sintaxis abreviada

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

úsalo como

input
  +placeholder
    color: red
3
  • 4
    Honestamente, creo que esto es más difícil de leer y tampoco tan ordenado como la sintaxis normal. 23/02/15 a las 20:36
  • Traté de ponerlo como comentario, pero es demasiado grande. Prefiero usar esta sintaxis y no podría hacer que la respuesta elegida funcione con demasiada facilidad. Pensé que podría ser útil para otra persona. 23/02/15 a las 20:52
  • 2
    éste es el mejor, fácil de entender e implementar.
    arslion
    26/06/15 a las 23:05
3

¿Por qué no algo como esto?

Utiliza una combinación de listas, iteración e interpolación.

@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
  • 1
    Es un poco complicado, estaba buscando la directiva de contenido, ¡pero gracias! 19 de junio de 2013 a las 2:51
3

Para evitar errores de 'Bloque no cerrado: CssSyntaxError' que se generan desde los compiladores sass, agregue un ';' hasta el final de @content.

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

Utilizo exactamente el mismo marcador de posición de mezcla sass que escribió NoDirection. Lo encuentro en la colección sass mixins aquí y estoy muy satisfecho con él. Hay un texto que explica más una opción mixins.