Puis-je utiliser un pseudo-élément: before ou: after sur un champ de saisie?
J'essaie d'utiliser le pseudo-élément :after
css sur un champ input
, mais cela ne fonctionne pas. Si je l'utilise avec un span
, cela fonctionne bien.
<style type="text/css">
.mystyle:after {content:url(smiley.gif);}
.mystyle {color:red;}
</style>
Cela fonctionne (met le smiley après "buu!"et avant "un peu plus")
<span class="mystyle">buuu!</span>a some more
Cela ne fonctionne pas - il ne colore que someValue en rouge, mais il n'y a pas de smiley.
<input class="mystyle" type="text" value="someValue">
Ce que je fais mal? dois-je utiliser un autre pseudo-sélecteur?
Note: Je ne peux pas ajouter un span
autour de mon input
, car il est généré par un tiers contrôle.
19 réponses
:after
et :before
ne sont pas pris en charge dans Internet Explorer 7 et Sous, sur tous les éléments.
Il n'est pas non plus destiné à être utilisé sur des éléments remplacés tels que form elements (inputs) et image elements.
En d'autres termes, c'est impossible avec du CSS pur.
Cependant, si vous utilisez jquery Vous pouvez utiliser
$(".mystyle").after("add your smiley here");
Pour ajouter votre contenu avec javascript. Cela fonctionne sur tous les navigateurs.
:before
et :after
rendent dans un conteneur
Et ne peut pas contenir d'autres éléments.
Les Pseudo-éléments ne peuvent être définis (ou mieux, ne sont pris en charge) que sur des éléments de conteneur. Parce que la façon dont ils sont rendus est dans le conteneur lui-même en tant qu'élément enfant. input
ne peut pas contenir d'autres éléments, donc ils ne sont pas pris en charge. Un button
d'autre part c'est aussi un élément de formulaire soutient, car c'est un contenant d'autres sous-éléments.
Si vous me demandez, si un navigateur affiche ces deux pseudo-éléments sur des éléments non-conteneurs, c'est un bug et une conformité non standard. La spécification parle directement du contenu de l'élément...
Spécifications W3C
Si nous lisez attentivement la spécification, il dit qu'ils sont insérés dans un élément contenant:
Les auteurs spécifient le style et l'emplacement du contenu généré avec :before et :après les pseudo-éléments. Comme leurs noms l'indiquent, les pseudo-éléments :before Et: after spécifient l'emplacement du contenu avant et après le contenu de l'arborescence de documents d'un élément. La propriété' content', en conjonction avec ces pseudo-éléments, spécifie ce qui est inséré.
Tu vois? arbre de document d'un élément contenu. Si je comprends bien, cela signifie dans un conteneur.
Curieusement, cela fonctionne avec certains types d'entrée. Au moins en Chrome,
<input type="checkbox" />
Fonctionne bien, comme
<input type="radio" />
C'est juste type=text
et d'autres qui ne fonctionnent pas.
Voici une autre approche (en supposant que vous avez le contrôle du code HTML): ajoutez un <span></span>
vide juste après l'entrée, et ciblez-le en CSS en utilisant input.mystyle + span:after
.field_with_errors {
display: inline;
color: red;
}
.field_with_errors input+span:after {
content: "*"
}
<div class="field_with_errors">Label:</div>
<div class="field_with_errors">
<input type="text" /><span></span>
</div>
J'utilise cette approche dans AngularJS car elle ajoutera automatiquement des classes .ng-invalid
aux éléments de formulaire <input>
, et au formulaire, mais pas au <label>
.
:before
et :after
sont appliqués à l'intérieur d'un conteneur, ce qui signifie que vous pouvez l'utiliser pour les éléments avec une balise de fin.
Il ne s'applique pas aux éléments à fermeture automatique.
Sur une note de côté, les éléments à fermeture automatique (tels que img/hr/input) sont également appelés "éléments remplacés", car ils sont remplacés par leur contenu respectif. "Objets externes" pour l'absence d'un meilleur terme. Une meilleure lecture ici
J'ai utilisé le background-image
pour créer le point rouge pour les champs requis.
input[type="text"][required] {
background-image: radial-gradient(red 15%, transparent 16%);
background-size: 1em 1em;
background-position: top right;
background-repeat: no-repeat
}
Vous ne pouvez pas mettre un pseudo-élément dans un élément d'entrée, mais vous pouvez mettre un élément d'ombre, comme un espace réservé!
input[type="text"] {
&::-webkit-input-placeholder {
&:before {
// your code
}
}
}
Pour le faire fonctionner dans d'autres navigateurs, l'utilisation :-moz-placeholder
, ::-moz-placeholder
et :-ms-input-placeholder
dans les différents sélecteurs. Impossible de regrouper les sélecteurs, car si un navigateur ne reconnaît pas le sélecteur invalide l'instruction entière.
UPDATE : le code ci-dessus ne fonctionne qu'avec le pré-processeur CSS (SASS, LESS...), sans pré-processeurs utiliser:
input[type="text"]::-webkit-input-placeholder:before { // your code }
J'ai trouvé ce post car j'avais le même problème, c'était la solution qui a fonctionné pour moi. Au lieu de remplacer la valeur de l'entrée, supprimez-la et positionnez absolument une span derrière elle de la même taille, la span peut avoir une pseudo-classe :before
appliquée avec la police d'icône de votre choix.
<style type="text/css">
form {position: relative; }
.mystyle:before {content:url(smiley.gif); width: 30px; height: 30px; position: absolute; }
.mystyle {color:red; width: 30px; height: 30px; z-index: 1; position: absolute; }
</style>
<form>
<input class="mystyle" type="text" value=""><span class="mystyle"></span>
</form>
Une solution de travail en CSS pur:
L'astuce est de supposer qu'il y a un élément dom après le champ de texte.
/*
* The trick is here:
* this selector says "take the first dom element after
* the input text (+) and set its before content to the
* value (:before).
*/
input#myTextField + *:before {
content: "";
}
<input id="myTextField" class="mystyle" type="text" value="someValue" />
<!--
There's maybe something after a input-text
Does'nt matter what it is (*), I use it.
-->
<span></span>
( * ) solution limitée, cependant:
- Vous devez espérer qu'il y a un élément dom suivant,
- Vous devez espérer qu'aucun autre champ de saisie ne suit votre champ de saisie.
Mais dans la plupart des cas, nous connaissons notre code donc cette solution semble efficace et 100% CSS et 0% jQuery.
Pseudo éléments comme :after
, :before
sont uniquement pour les éléments de conteneur. Éléments commençant et se fermant dans un seul endroit comme <input/>
, <img>
etc ne sont pas des éléments de conteneur et donc les pseudo-éléments ne sont pas pris en charge. Une fois que vous appliquez un pseudo-élément à l'élément conteneur comme <div>
et si vous inspectez le code (voir l'image), vous pouvez comprendre ce que je veux dire. En fait le pseudo-élément est créé à l'intérieur de l'élément conteneur. Ceci n'est pas possible dans le cas de <input>
ou <img>
Selon une note dans la spécification CSS 2.1, la spécification " ne définit pas complètement l'interaction de: before et: after avec des éléments remplacés (tels que IMG en HTML). Cela sera défini plus en détail dans une spécification future."Bien que input
ne soit plus vraiment un élément remplacé, la situation de base n'a pas changé: l'effet de :before
et :after
sur lui dans unspecified et n'a généralement aucun effet.
, La solution est de trouver une approche différente du problème que vous essayons d'aborder de cette façon. Mettre le contenu généré dans un contrôle de saisie de texte serait très trompeur: pour l'utilisateur, il semblerait faire partie de la valeur initiale du contrôle, mais il ne peut pas être modifié – il semblerait donc être quelque chose de forcé au début du contrôle, mais il ne serait pas soumis dans le cadre des données de formulaire.
Comme d'autres l'ont expliqué, input
s sont des éléments vides un peu remplacés, donc la plupart des navigateurs ne vous permettront pas de générer ::before
Ni ::after
pseudo-éléments en eux.
Cependant, le groupe de travail CSS envisage d'autoriser explicitement ::before
et ::after
dans le cas où le input
a appearance: none
.
À Partir de https://lists.w3.org/Archives/Public/www-style/2016Mar/0190.html,
Safari et Chrome autorisent tous deux des pseudo-éléments sur leurs entrées de formulaire. Les autres navigateurs ne le font pas. Nous nous sommes penchés sur la suppression de ce, mais les utilisation-compteur d'enregistrement ~.07% des pages qui l'utilisent, ce qui est 20x notre max seuil de suppression.
Spécifier réellement des pseudo-éléments sur les entrées nécessiterait de spécifier la structure interne des entrées au moins un peu, ce que nous n'avons pas réussi à le faire encore (et je ne suis pas confiant que nous * pouvons * faire). Mais Boris suggéré, dans l'un des bugthreads, permettant à l'apparence:aucun entrées-fondamentalement juste les transformer en S, plutôt que "kinda-remplacé" élément.
Vous devez avoir une sorte de wrapper autour de l'entrée pour utiliser un pseudo-élément avant ou après. Voici un violon qui a un before sur le wrapper div d'une entrée, puis place le before à l'intérieur de l'entrée - ou du moins il ressemble à cela. Évidemment, c'est un travail autour mais efficace dans un pincement et se prête à être réactif. Vous pouvez facilement en faire un après si vous avez besoin de mettre un autre contenu.
Violon De Travail
Signe Dollar dans une entrée en tant que le pseudo-élément: http://jsfiddle.net/kapunahele/ose4r8uj/1/
Le code HTML:
<div class="test">
<input type="text"></input>
</div>
Le CSS:
input {
margin: 3em;
padding-left: 2em;
padding-top: 1em;
padding-bottom: 1em;
width:20%;
}
.test {
position: relative;
background-color: #dedede;
display: inline;
}
.test:before {
content: '$';
position: absolute;
top: 0;
left: 40px;
z-index: 1;
}
Essayez suivant:
label[for="userName"] {
position: relative;
}
label[for="userName"]::after {
content: '[after]';
width: 22px;
height: 22px;
display: inline-block;
position: absolute;
right: -30px;
}
<label for="userName">
Name:
<input type="text" name="userName" id="userName">
</label>
Si vous essayez de styliser un élément d'entrée avec :before Et: after, il est probable que vous essayez de imiter les effets d'autres éléments span, div ou même a dans votre pile CSS.
Comme le souligne la réponse de Robert Koritnik,: before Et: after ne peuvent être appliqués qu'aux éléments de conteneur et les éléments d'entrée ne sont pas des conteneurs.
Cependant, HTML 5 a introduit l'élémentbutton qui est un conteneur et se comporte comme une entrée [type= " submit / reset"] élément.
<style>
.happy:after { content:url(smiley.gif); }
</style>
<form>
<!-- won't work -->
<input class="happy" type="submit" value="Submit" />
<!-- works -->
<button class="happy">Submit</button>
</form>
Résumé
, Il ne fonctionne pas avec <input type="button">
, mais il fonctionne très bien avec <input type="checkbox">
.
Violon: http://jsfiddle.net/gb2wY/50/
HTML:
<p class="submit">
<input id="submit-button" type="submit" value="Post">
<br><br>
<input id="submit-cb" type="checkbox" checked>
</p>
CSS:
#submit-button::before,
#submit-cb::before {
content: ' ';
background: transparent;
border: 3px solid crimson;
display: inline-block;
width: 100%;
height: 100%;
padding: 0;
margin: -3px -3px;
}
:before
et :after
ne fonctionne que pour les nœuds qui peuvent avoir des nœuds enfants puisqu'ils insèrent un nouveau nœud en tant que Premier ou dernier nœud.
J'ai trouvé que vous pouvez le faire comme ceci:
.submit .btn input
{
padding:11px 28px 12px 14px;
background:#004990;
border:none;
color:#fff;
}
.submit .btn
{
border:none;
color:#fff;
font-family: 'Open Sans', sans-serif;
font-size:1em;
min-width:96px;
display:inline-block;
position:relative;
}
.submit .btn:after
{
content:">";
width:6px;
height:17px;
position:absolute;
right:36px;
color:#fff;
top:7px;
}
<div class="submit">
<div class="btn">
<input value="Send" type="submit" />
</div>
</div>
Vous devez avoir un parent div qui prend le remplissage et le: after. Le premier parent doit être relatif et le second div doit être absolu afin que vous puissiez définir la position de l'après.
Vous pouvez utiliser l'élément after ou before dans votre bloc parent avec jQuery. comme ceci:
$(yourInput).parent().addClass("error-form-field");