Mixage d'espace réservé dans SCSS / CSS

122

J'essaye de créer un mixin pour les espaces réservés dans sass.

C'est le mixin que j'ai créé.

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

Voici comment j'aimerais inclure le mixin:

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

De toute évidence, cela ne fonctionnera pas à cause de tous les deux-points et points-virgules qui sont passés au mixin, mais ... j'aimerais vraiment entrer simplement du CSS statique et le passer exactement comme la fonction ci-dessus.

Est-ce possible?

Shannon Hochkins
la source

Réponses:

253

Vous recherchez la @contentdirective:

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

La référence SASS contient plus d'informations, qui peuvent être trouvées ici: http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#mixin-content


Depuis Sass 3.4, ce mixin peut être écrit comme ceci pour fonctionner à la fois imbriqué et non imbriqué:

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

Usage:

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

@include placeholder {
  color: red;
}

Production:

.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
la source
1
Parfait, exactement ce dont j'avais besoin.
Shannon Hochkins
4
Je ne sais pas pourquoi cela a été annulé, mais la réponse est incorrecte. Vous avez besoin de «@» au début de chacun des préfixes de fournisseur individuels. Jetez un œil à une réponse plus bas par Dave Hein, ou mieux encore - essayez d'exécuter ce code, et vous verrez que cela ne fonctionnera pas.
Sk446
1
@RickM Il a été annulé car les modifications que vous avez apportées ne se compilent pas (erreur: les règles de base ne peuvent pas contenir le caractère de référence du sélecteur parent '&'.). Cela crée la sortie exacte recherchée par l'OP, la réponse que vous prétendez être "correcte" ne l'est pas.
cimmanon
Intéressant ... compilez-vous via cli? On dirait qu'il doit y avoir un conflit de version car c'est exactement le contraire qui se produit pour moi, et à en juger par d'autres réponses, quelques autres aussi.
Sk446
4
Oui, CLI: Sass 3.3.0.rc.3 via Compass. Revérifié avec CodePen et Sassmeister . Le &est nécessaire si vous voulez pouvoir obtenir un sélecteur comme input::-webkit-input-placeholderavec le mixin, mais cela vous empêchera de l'utiliser au niveau racine. sassmeister.com/gist/9469073 . Maintenant, si vous utilisez LibSass, c'est une autre histoire.
cimmanon
168

J'ai trouvé que l'approche donnée par cimmanon et Kurt Mueller fonctionnait presque, mais que j'avais besoin d'une référence parent (c'est-à-dire que je dois ajouter le préfixe «&» à chaque préfixe de fournisseur); comme ça:

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

J'utilise le mixin comme ceci:

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

Avec la référence parent en place, le css correct est généré, par exemple:

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

Sans la référence parent (&), un espace est inséré avant le préfixe du fournisseur et le processeur CSS ignore la déclaration; qui ressemble à ceci:

input::-webkit-input-placeholder {
    font-family: Constantia, "Lucida Bright", Lucidabright, "Lucida Serif", Lucida, "DejaVu Serif", "Liberation Serif", Georgia, serif;
    color: red;
}
Dave Hein
la source
9
Merci beaucoup. Vous m'avez économisé des heures d'essais et d'erreurs afin de faire fonctionner la réponse / solution acceptée ...
tmuecksch
Il est à noter que vos sélecteurs sont maintenant légèrement surqualifiés (à moins que vous ne vouliez vraiment pas qu'ils fonctionnent sur des éléments d'entrée ou de sélection). L'ajout du sélecteur parent vous empêche d'utiliser le mixin sans imbrication (ce que recherchait l'OP).
cimmanon
1
Le &est totalement nécessaire. Modification de la réponse populaire pour refléter cela.
AlexKempton
1
+1. Certains navigateurs prennent en charge la ::placeholderpropriété officielle maintenant, je vous recommande donc d'ajouter ceci en haut:&::placeholder {@content}
Matt Browne
11

Ceci est pour la syntaxe abrégée

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

utilisez-le comme

input
  +placeholder
    color: red
igrossiter
la source
4
Je pense honnêtement que c'est plus difficile à lire et pas aussi net que la syntaxe régulière
Shannon Hochkins
J'ai essayé de le mettre en commentaire, mais c'est trop grand. J'utilise plutôt cette syntaxe et je ne pourrais pas faire fonctionner la réponse choisie trop facilement. J'ai pensé que cela pourrait être utile pour quelqu'un d'autre.
igrossiter
2
celui-ci est le meilleur, facile à comprendre et à mettre en œuvre.
arslion
3

Pourquoi pas quelque chose comme ça?

Il utilise une combinaison de listes, d'itérations et d'interpolation.

@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
la source
1
C'est juste un peu trop compliqué, je cherchais la directive de contenu mais merci!
Shannon Hochkins
3

Pour éviter les erreurs 'Unclosed block: CssSyntaxError' générées par les compilateurs sass, ajoutez un ';' à la fin de @content.

@mixin placeholder {
   ::-webkit-input-placeholder { @content;}
   :-moz-placeholder           { @content;}
   ::-moz-placeholder          { @content;}
   :-ms-input-placeholder      { @content;}
}
Pas de direction
la source
0

J'utilise exactement le même espace réservé sass mixin que NoDirection a écrit. Je le trouve dans la collection sass mixins ici et j'en suis très satisfait. Il y a un texte qui explique davantage une option mixins.

Nesha Zoric
la source