: not (: empty) Le sélecteur CSS ne fonctionne pas?

J’ai un temps fou avec ce sélecteur CSS particulier qui ne veut pas fonctionner lorsque j’ajoute :not(:empty) à cela. Cela semble fonctionner correctement avec n’importe quelle combinaison des autres sélecteurs:

 input:not(:empty):not(:focus):invalid { border-color: #A22; box-shadow: none } 

Si je supprime la partie :not(:empty) , cela fonctionne très bien. Même si je change le sélecteur pour input:not(:empty) il ne sélectionnera toujours pas les champs de saisie contenant du texte. Est-ce que c’est cassé ou suis-je juste pas autorisé à utiliser :empty dans un :not() sélecteur?

La seule autre chose à laquelle je peux penser, c’est que les navigateurs disent toujours que l’élément est vide car il n’a pas d’enfant, juste une “valeur” par exemple. Le sélecteur :empty n’a-t-il pas une fonctionnalité distincte pour un élément d’entrée par rapport à un élément normal? Cela ne semble pas probable car utiliser :empty sur un champ et y taper quelque chose entraînera la disparition des effets alternatifs (car il n’est plus vide).

Testé dans Firefox 8 et Chrome.

En tant qu’élément vide , un élément est considéré comme vide par la définition HTML de “empty”, car le modèle de contenu de tous les éléments vides est toujours vide . Ils correspondent donc toujours à la pseudo-classe :empty , qu’ils aient ou non une valeur. C’est également pour cette raison que leur valeur est représentée par un atsortingbut dans la balise de début, plutôt que par le contenu textuel des balises de début et de fin.

De plus, à partir de la spécification des sélecteurs :

La pseudo-classe :empty représente un élément qui n’a aucun enfant. En termes d’arbre de document, seuls les nœuds d’élément et les nœuds de contenu (tels que les nœuds de texte DOM, les nœuds CDATA et les références d’entité) dont les données ont une longueur non nulle doivent être considérés comme affectant la vacuité;

Par conséquent, input:not(:empty) ne correspondra à rien dans un document HTML correct. (Cela fonctionnerait toujours dans un document XML hypothétique qui définit un élément pouvant accepter du texte ou des éléments enfants.)

Je ne pense pas que vous pouvez styler dynamicment les champs vides en utilisant uniquement des CSS (c’est-à-dire des règles qui s’appliquent chaque fois qu’un champ est vide et qu’aucune fois le texte n’est entré). Vous pouvez sélectionner des champs initialement vides s’ils ont un atsortingbut de value vide ( input[value=""] ) ou ne possèdent pas l’atsortingbut ( input:not([value]) ), mais c’est à peu près tout.

C’est possible avec javascript onkeyup="this.setAtsortingbute('value', this.value);" & input:not([value=""]):not(:focus):invalid

Démo: http://jsfiddle.net/mhsyfvv9/

 input:not([value=""]):not(:focus):invalid{ background-color: tomato; } 
  

Vous pouvez essayer d’utiliser:

 input { padding: 10px 15px; font-size: 16px; border-radius: 5px; border: 2px solid lightblue; outline: 0; font-weight:bold; transition: border-color 200ms; font-family: sans-serif; } .validation { opacity: 0; font-size: 12px; font-family: sans-serif; color: crimson; transition: opacity; } input:required:valid { border-color: forestgreen; } input:required:invalid:not(:placeholder-shown) { border-color: crimson; } input:required:invalid:not(:placeholder-shown) + .validation { opacity: 1; } 
  
Not valid

Vous pouvez aborder cela différemment; omettre l’utilisation de la pseudo-classe :empty et utiliser input événements d’ input pour détecter une valeur significative dans le champ et la personnaliser en conséquence:

 var inputs = document.getElementsByTagName('input'); for (var i = 0; i < inputs.length; i++) { var input = inputs[i]; input.addEventListener('input', function() { var bg = this.value ? 'green' : 'red'; this.style.backgroundColor = bg; }); } 
 body { padding: 40px; } #inputList li { list-style-type: none; padding-bottom: 1.5em; } #inputList li input, #inputList li label { float: left; width: 10em; } #inputList li input { color: white; background-color: red; } #inputList li label { text-align: right; padding-right: 1em; } 
 
 .floating-label-input { position: relative; height:60px; } .floating-label-input input { width: 100%; height: 100%; position: relative; background: transparent; border: 0 none; outline: none; vertical-align: middle; font-size: 20px; font-weight: bold; padding-top: 10px; } .floating-label-input label { position: absolute; top: calc(50% - 5px); font-size: 22px; left: 0; color: #000; transition: all 0.3s; } .floating-label-input input:focus ~ label, .floating-label-input input:focus ~ label, .floating-label-input input:valid ~ label { top: 0; font-size: 15px; color: #33bb55; } .floating-label-input .line { position: absolute; height: 1px; width: 100%; bottom: 0; background: #000; left: 0; } .floating-label-input .line:after { content: ""; display: block; width: 0; background: #33bb55; height: 1px; transition: all 0.5s; } .floating-label-input input:focus ~ .line:after, .floating-label-input input:focus ~ .line:after, .floating-label-input input:valid ~ .line:after { width: 100%; } 
 

Cela devrait fonctionner dans les navigateurs modernes:

 input[value]:not([value=""]) 

Il sélectionne toutes les entrées avec un atsortingbut de valeur, puis sélectionne les entrées avec une valeur non vide parmi celles-ci.

 input:not([value=""]) 

Cela fonctionne parce que nous sélectionnons l’entrée uniquement lorsqu’il n’y a pas de chaîne vide.