: non (: vuoto) Il selettore CSS non funziona?


92

Mi sto divertendo moltissimo con questo particolare selettore CSS che non vuole funzionare quando aggiungo :not(:empty)ad esso. Sembra funzionare bene con qualsiasi combinazione degli altri selettori:

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

Se rimuovo la :not(:empty)parte, funziona perfettamente. Anche se cambio il selettore in input:not(:empty)esso, non selezionerò ancora i campi di input in cui è stato digitato del testo. È rotto o non sono autorizzato a usarlo :emptyall'interno di un :not()selettore?

L'unica altra cosa a cui riesco a pensare è che i browser continuano a dire che l'elemento è vuoto perché non ha figli, solo un "valore" per dire. Il :emptyselettore non ha funzionalità separate per un elemento di input rispetto a un elemento normale? Questo non sembra probabile però perché usare :emptysu un campo e digitare qualcosa al suo interno farà scomparire gli effetti alternativi (perché non è più vuoto).

Testato in Firefox 8 e Chrome.


Puoi pubblicare il codice pertinente?
Virendra

2
Posso citare una parte del riferimento API per il :emptyselettore di : "Alcuni altri elementi, d'altra parte, sono vuoto (cioè non hanno figli) per definizione: <input>, <img>, <br>, e <hr>, per esempio."
David dice di reintegrare Monica il

@Virendra: questo è il codice pertinente, ma ho aggiunto le regole CSS effettive. Se rimuovo il :not(:empty), il bordo rosso funziona come previsto per un input che non è a fuoco ma non è valido.
animuson

Risposte:


149

Essendo un elemento void , un <input>elemento è considerato vuoto dalla definizione HTML di "vuoto", poiché il modello di contenuto di tutti gli elementi void è sempre vuoto . Quindi corrisponderanno sempre alla :emptypseudo-classe, indipendentemente dal fatto che abbiano o meno un valore. Questo è anche il motivo per cui il loro valore è rappresentato da un attributo nel tag di inizio, piuttosto che dal contenuto di testo all'interno dei tag di inizio e fine.

Inoltre, dalle specifiche dei selettori :

La :emptypseudo-classe rappresenta un elemento che non ha affatto figli. In termini di struttura ad albero del documento, solo i nodi elemento e i nodi contenuto (come nodi testo DOM, nodi CDATA e riferimenti entità) i cui dati hanno una lunghezza diversa da zero devono essere considerati come influenzanti il ​​vuoto;

Di conseguenza, input:not(:empty)non corrisponderà mai a nulla in un documento HTML appropriato. (Funzionerebbe comunque in un ipotetico documento XML che definisce un <input>elemento che può accettare testo o elementi figlio.)

Non penso che tu possa modellare i <input>campi vuoti in modo dinamico usando solo CSS (cioè regole che si applicano ogni volta che un campo è vuoto, e non una volta inserito il testo). Puoi selezionare campi inizialmente vuoti se hanno un valueattributo vuoto ( input[value=""]) o se mancano del tutto dell'attributo ( input:not([value])), ma questo è tutto.


Hmm, non ricordo cosa ho fatto per far sparire gli effetti solo con il file input:empty. Forse ho digitato qualcosa di sbagliato, chi lo sa.
animuson

9
Per l'ultimo paragrafo della risposta, gli inputelementi possono essere stilizzati dinamicamente (in browser sufficientemente moderni) se puoi usare l' requiredattributo nel markup HTML. Quindi puoi usare :valide :invalidin CSS per testare il valore non vuoto rispetto a quello vuoto del controllo. Vedi stackoverflow.com/questions/16952526/…
Jukka K. Korpela

1
@ JukkaK.Korpela a meno che tu non stia utilizzando anche l'attributo pattern.
WORMSS

2
input: not ([value = '']) selezionerà un input con un valore;)
Chris Love

@ Chris Love: inserisce un valore iniziale (al caricamento della pagina).
BoltClock

43

È possibile con javascript in linea onkeyup="this.setAttribute('value', this.value);"einput:not([value=""]):not(:focus):invalid

Demo: http://jsfiddle.net/mhsyfvv9/

input:not([value=""]):not(:focus):invalid{
  background-color: tomato;
}
<input 
  type="email" 
  value="" 
  placeholder="valid mail" 
  onchange="this.setAttribute('value', this.value);" />


L' onchangeevento non è migliore in questo caso? Dal momento che puoi modificare i valori di input anche con Right click > Cut(ad esempio). Testato: funziona bene.
Derk Jan Speelman

38

Potresti provare a usare: segnaposto mostrato ...

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

  
<input type="email" placeholder="e-mail" required>
<div class="validation">Not valid</span>

nessun grande supporto però ... caniuse


1
supporto abbastanza buono però ... caniuse
Reggie Pinkham

Buon vecchio Internet Explorer (Y)
rorymorris89

@ rorymorris89 anche l'ultima versione di EDGE non supporta :-(
Mo.

12

.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%;
}
<div class="floating-label-input">
      <input type="text" id="id" required/>
      <label for="id" >User ID</label>
      <span class="line"></span>
</div>


7

Puoi avvicinarti a questo in modo diverso; omettere l'uso della :emptypseudo-classe e utilizzare gli inputeventi per rilevare un valore significativo nel <input>campo e modellarlo di conseguenza:

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;
}
<ul id="inputList">
  <li>
    <label for="username">Enter User Name:</label>
    <input type="text" id="username" />
  </li>
  <li>
    <label for="password">Enter Password:</label>
    <input type="password" id="password" />
  </li>
</ul>

Relazionato


Dichiarazione di non responsabilità: tieni presente che gli inputeventi sono attualmente sperimentali e probabilmente non ampiamente supportati.


3

Poiché il segnaposto scompare durante l'input, puoi utilizzare:

input:placeholder-shown{
    //rules for not empty input
}

2

pura soluzione CSS

input::-webkit-input-placeholder {
    opacity: 1;
    -webkit-transition: opacity 0s;
    transition: opacity 0s;
    text-align: right;
}
/* Chrome <=56, Safari < 10 */
input:-moz-placeholder {
    opacity: 1;
    -moz-transition: opacity 0s;
    transition: opacity 0s;
    text-align: right;
}
/* FF 4-18 */
input::-moz-placeholder {
    opacity: 1;
    -moz-transition: opacity 0s;
    transition: opacity 0s;
    text-align: right;
}
/* FF 19-51 */
input:-ms-input-placeholder {
    opacity: 1;
    -ms-transition: opacity 0s;
    transition: opacity 0s;
    text-align: right;
}
/* IE 10+ */
input::placeholder {
    opacity: 1;
    transition: opacity 0s;
    text-align: right;
}
/* Modern Browsers */

*:focus::-webkit-input-placeholder {
   opacity: 0;
   text-align: left;
}
/* Chrome <=56, Safari < 10 */
*:focus:-moz-placeholder {
    opacity: 0;
    text-align: left;
}
/* FF 4-18 */
*:focus::-moz-placeholder {
    opacity: 0;
    text-align: left;
}
/* FF 19-50 */
*:focus:-ms-input-placeholder {
    opacity: 0;
    text-align: left;
}
/* IE 10+ */
*:focus::placeholder {
    opacity: 0;
    text-align: left;
}
/* Modern Browsers */

input:focus {
    text-align: left;
}

0

Un'altra soluzione CSS pura

.form{
  position:relative;
  display:inline-block;
}
.form input{
  margin-top:10px;
}
.form label{
    position:absolute;
    left:0;
    top:0;
    opacity:0;
    transition:all 1s ease;
}
input:not(:placeholder-shown) + label{
    top:-10px;
    opacity:1;
}
<div class="form">
    <input type="text" id="inputFName" placeholder="Firstname">
    <label class="label" for="inputFName">Firstname</label>
</div>
<div class="form">
    <input type="text" id="inputLName" placeholder="Lastname">
    <label class="label" for="inputLName">Lastname</label>
</div>


-1

Questo dovrebbe funzionare nei browser moderni:

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

Seleziona tutti gli input con l'attributo value e quindi seleziona gli input con un valore non vuoto tra di loro.


10
Questo non sarebbe dinamico, però. Seleziona solo gli elementi di input che hanno l' attributo definito come value="". Digitare / rimuovere qualcosa nella casella non comporterebbe alcuna modifica.
animuson

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

Funziona perché stiamo selezionando l'input solo quando non c'è una stringa vuota.


-1
input:not(:invalid){
 border: 1px red solid;
}

// or 

input:not(:focus):not(:invalid){
 border: 1px red solid;
}

1
Quando si aggiunge una risposta a una domanda di undici anni con dieci risposte esistenti, è molto importante aggiungere qualche spiegazione su come e perché la risposta funziona e sottolineare quale nuovo aspetto della domanda risponde. Se la risposta dipende da qualcosa che è cambiato da quando è stata posta la domanda, segnalalo pure.
Jason Aller
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.