web-dev-qa-db-de.com

: nicht (: leer) CSS Selector funktioniert nicht?

Ich habe eine verdammte Zeit mit diesem speziellen CSS-Selektor, der nicht arbeiten möchte, wenn ich :not(:empty) dazu füge. Es scheint gut zu funktionieren mit jeder Kombination der anderen Selektoren:

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

Wenn ich den :not(:empty)-Teil entferne, funktioniert es gut. Selbst wenn ich den Selektor auf input:not(:empty) ändere, werden Eingabefelder, in die Text eingegeben wurde, nicht ausgewählt. Ist das defekt oder darf ich :empty nicht innerhalb eines :not()-Selektors verwenden?

Das einzige andere, was mir einfällt, ist, dass Browser immer noch sagen, dass das Element leer ist, weil es keine untergeordneten Elemente hat, sondern lediglich einen "Wert". Verfügt der Selektor :empty nicht über eine separate Funktionalität für ein Eingabeelement gegenüber einem regulären Element? Dies scheint jedoch nicht wahrscheinlich zu sein, da bei Verwendung von :empty für ein Feld und Eingabe von etwas die alternativen Effekte verschwinden (weil sie nicht mehr leer sind).

Getestet in Firefox 8 und Chrome.

78
animuson

Als void-Element wird ein <input>-Element von der HTML-Definition von "leer" als empty betrachtet, da das Inhaltsmodell aller void-Elemente immer leer ist. Sie stimmen also immer mit der :empty-Pseudoklasse überein, unabhängig davon, ob sie einen Wert haben oder nicht. Aus diesem Grund wird ihr Wert auch durch ein Attribut im Starttag und nicht durch Textinhalt in Start- und Endtag dargestellt.

Auch aus der Selectors spec :

Die :empty-Pseudoklasse stellt ein Element dar, das überhaupt keine Kinder hat. In Bezug auf die Dokumentstruktur müssen nur Elementknoten und Inhaltsknoten (z. B. DOM-Textknoten, CDATA-Knoten und Entitätsreferenzen), deren Daten eine Länge ungleich Null haben, als Auswirkungen auf die Leere betrachtet werden.

Infolgedessen wird input:not(:empty) niemals mit einem korrekten HTML-Dokument übereinstimmen. (Es funktioniert immer noch in einem hypothetischen XML-Dokument, das ein <input>-Element definiert, das Text- oder untergeordnete Elemente akzeptieren kann.)

Ich glaube nicht, dass Sie leere <input>-Felder mit nur CSS dynamisch formatieren können (d. H. Regeln, die gelten, wenn ein Feld leer ist und kein Text mehr eingegeben wird). Sie können initial leere Felder auswählen, wenn sie ein leeres value-Attribut (input[value=""]) haben oder das Attribut ganz fehlt (input:not([value])), aber das wars.

130
BoltClock

Mit Inline-Javascript ist es möglich onkeyup="this.setAttribute('value', this.value);" & input: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" 
  onkeyup="this.setAttribute('value', this.value);" />

34
Mo.

Sie könnten versuchen, Folgendes zu verwenden: Platzhalter angezeigt ...

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>

keine großartige Unterstützung ... caniuse

25
Gijs Erenstein

.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
Amit

Sie können dies anders angehen; Lassen Sie die Verwendung der :empty-Pseudoklasse aus und verwenden Sie input -Ereignisse, um einen signifikanten Wert im <input>-Feld zu ermitteln, und gestalten Sie sie entsprechend:

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>

Verbunden


Disclaimer: Beachten Sie, dass input events derzeit experimentell sind und wahrscheinlich nicht allgemein unterstützt werden.

7
Eliran Malka

reine css lösung

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
star