: tidak (: kosong) pemilih CSS tidak berfungsi?

93

Saya mengalami kesulitan dengan pemilih CSS khusus ini yang tidak ingin berfungsi ketika saya menambahkannya :not(:empty). Tampaknya berfungsi dengan baik dengan kombinasi apa pun dari penyeleksi lain:

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

Jika saya menghapus :not(:empty)bagian itu, itu berfungsi dengan baik. Bahkan jika saya mengubah pemilih input:not(:empty)tetap tidak akan memilih bidang masukan yang memiliki teks yang diketik di dalamnya. Apakah ini rusak atau saya hanya tidak diizinkan untuk digunakan :emptydalam :not()selektor?

Satu-satunya hal lain yang dapat saya pikirkan adalah bahwa browser masih mengatakan bahwa elemen tersebut kosong karena tidak memiliki turunan, hanya sebuah "nilai" per kata. Apakah :emptypemilih tidak memiliki fungsi terpisah untuk elemen masukan versus elemen biasa? Ini tampaknya tidak mungkin karena menggunakan :emptydi lapangan dan mengetik sesuatu ke dalamnya akan menyebabkan efek alternatif hilang (karena tidak lagi kosong).

Diuji di Firefox 8 dan Chrome.

animuson
sumber
Bisakah Anda memposting kode yang relevan?
Virendra
2
Dapatkah saya mengutip Anda bagian dari referensi API untuk :emptypemilih : "Beberapa elemen lainnya, di sisi lain, kosong (yaitu tidak memiliki anak) dengan definisi: <input>, <img>, <br>, dan <hr>, misalnya."
David mengatakan mengembalikan Monica
@Virendra: Itu adalah kode yang relevan, tetapi saya telah menambahkan aturan CSS yang sebenarnya ke dalamnya. Jika saya menghapus :not(:empty), batas merah berfungsi seperti yang diharapkan untuk input yang tidak fokus tetapi tidak valid.
animuson

Jawaban:

151

Sebagai elemen kosong , <input>elemen dianggap kosong menurut definisi HTML "kosong", karena model konten dari semua elemen kosong selalu kosong . Jadi mereka akan selalu cocok dengan :emptypseudo-class, apakah mereka memiliki nilai atau tidak. Ini juga mengapa nilainya diwakili oleh atribut di tag awal, bukan konten teks dalam tag awal dan akhir.

Juga, dari spesifikasi Selectors :

The :emptypseudo-class merupakan elemen yang tidak memiliki anak sama sekali. Dalam hal pohon dokumen, hanya node elemen dan node konten (seperti node teks DOM, node CDATA, dan referensi entitas) yang datanya memiliki panjang bukan-nol harus dianggap mempengaruhi kekosongan;

Akibatnya, input:not(:empty)tidak akan pernah cocok dengan apapun dalam dokumen HTML yang benar. (Ini masih akan berfungsi dalam dokumen XML hipotetis yang mendefinisikan <input>elemen yang dapat menerima teks atau elemen turunan.)

Saya tidak berpikir Anda dapat memberi gaya <input>bidang kosong secara dinamis hanya dengan menggunakan CSS (yaitu aturan yang berlaku setiap kali bidang kosong, dan jangan sekali teks dimasukkan). Anda dapat memilih bidang yang awalnya kosong jika mereka memiliki valueatribut kosong ( input[value=""]) atau tidak memiliki atribut sama sekali ( input:not([value])), tapi itu saja.

BoltClock
sumber
Hmm, saya tidak ingat apa yang saya lakukan untuk menghilangkan efek hanya dengan input:empty. Mungkin saya mengetik sesuatu yang salah, siapa tahu.
animuson
9
Untuk paragraf terakhir dalam jawaban, inputelemen dapat diberi gaya secara dinamis (di browser yang cukup modern) jika Anda dapat menggunakan requiredatribut dalam markup HTML. Kemudian Anda dapat menggunakan :validdan :invaliddi CSS untuk menguji nilai kontrol yang tidak kosong vs. kosong. Lihat stackoverflow.com/questions/16952526/…
Jukka K. Korpela
1
@ JukkaK.Korpela kecuali jika Anda juga menggunakan atribut pola.
WORMSS
2
input: not ([value = '']) akan memilih input dengan nilai;)
Chris Love
@Chris Love: Dimasukkan dengan nilai awal (saat memuat halaman).
BoltClock
43

Dimungkinkan dengan javascript sebaris 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" 
  onchange="this.setAttribute('value', this.value);" />

Mo.
sumber
Bukankah onchangeacara ini lebih baik dalam kasus ini? Karena Anda dapat mengedit nilai input dengan Right click > Cutjuga (misalnya). Mengujinya: berfungsi dengan baik.
Derk Jan Speelman
41

Anda dapat mencoba menggunakan: placeholder-ditampilkan ...

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>

tidak ada dukungan yang bagus ... caniuse

Gijs Erenstein
sumber
2
dukungan yang cukup bagus ... caniuse
Reggie Pinkham
Internet Explorer (Y) lama yang bagus
rorymorris89
@ rorymorris89 bahkan versi terbaru EDGE tidak mendukung :-(
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>

Amit
sumber
7

Anda mungkin melakukan pendekatan ini secara berbeda; hilangkan penggunaan :emptypseudo-class dan manfaatkan inputperistiwa untuk mendeteksi nilai yang signifikan di <input>bidang dan berikan gaya yang sesuai:

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>

Terkait


Penafian: perhatikan bahwa inputperistiwa saat ini bersifat eksperimental , dan mungkin tidak didukung secara luas.

Eliran Malka
sumber
3

Karena placeholder menghilang saat input, Anda dapat menggunakan:

input:placeholder-shown{
    //rules for not empty input
}
Luca C.
sumber
2

solusi css murni

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;
}
bintang
sumber
0

Solusi CSS murni lainnya

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

vacsati
sumber
-1

Ini harus berfungsi di browser modern:

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

Ini memilih semua input dengan atribut nilai dan kemudian memilih input dengan nilai yang tidak kosong di antara mereka.

Andrew Kondratev
sumber
10
Ini tidak akan dinamis. Ini hanya akan memilih elemen masukan yang memiliki atribut yang didefinisikan sebagai value="". Mengetik / menghapus sesuatu di kotak tidak akan menyebabkan perubahan apa pun.
animuson
-1
input:not([value=""])

Ini berfungsi karena kami memilih input hanya ketika tidak ada string kosong.

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

// or 

input:not(:focus):not(:invalid){
 border: 1px red solid;
}
SNEILΛ
sumber
1
Saat menambahkan jawaban untuk pertanyaan berusia sebelas tahun dengan sepuluh jawaban yang ada, sangat penting untuk menambahkan beberapa penjelasan tentang bagaimana dan mengapa jawaban Anda berhasil dan untuk menunjukkan aspek baru apa dari pertanyaan yang dijawab oleh jawaban Anda. Jika jawabannya tergantung pada sesuatu yang telah berubah sejak pertanyaan itu diajukan, tunjukkan juga.
Jason Aller