: not (: empty) Селектор CSS не работает?
У меня чертовски время с этим конкретным селектором CSS, который не хочет работать, когда я добавляю к нему :not(:empty)
. Кажется, что он отлично работает с любой комбинацией других селекторов:
input:not(:empty):not(:focus):invalid { border-color: #A22; box-shadow: none }
Если я удалю часть :not(:empty)
, она работает нормально. Даже если я переключу селектор на input:not(:empty)
, он все равно не будет выбирать поля ввода, в которые в них будет напечатан текст. Является ли это сломанным или мне просто не разрешено использовать :empty
в селекторе :not()
?
Единственное, что я могу придумать, это то, что браузеры все еще говорят, что элемент пуст, потому что у него нет детей, просто "значение" для каждого. Селектор :empty
не имеет отдельной функциональности для элемента ввода в сравнении с регулярным элементом? Это не кажется вероятным, хотя, поскольку использование :empty
в поле и ввод чего-то в него приведет к тому, что альтернативные эффекты исчезнут (потому что он больше не пуст).
Протестировано в Firefox 8 и Chrome.
Ответы
Ответ 1
Будучи void element, элемент <input>
считается пустым по определению HTML "empty", поскольку модель содержимого всех элементов void всегда пуста. Поэтому они всегда будут соответствовать псевдоклассу :empty
, независимо от того, имеет ли оно значение. Вот почему их значение представлено атрибутом в начальном теге, а не текстовым контентом в начале и конце тегов.
Кроме того, из Specors spec:
Псевдокласс класса :empty
представляет собой элемент, у которого вообще нет детей. Что касается дерева документов, следует рассматривать только узлы элементов и узлы контента (такие как текстовые узлы DOM, узлы CDATA и ссылки на сущности), данные которых имеют ненулевую длину, как влияющие на пустоту;
Следовательно, input:not(:empty)
никогда не будет соответствовать чему-либо в надлежащем HTML-документе. (Он все равно будет работать в гипотетическом XML-документе, который определяет элемент <input>
, который может принимать текстовые или дочерние элементы.)
Я не думаю, что вы можете динамически создавать пустые поля <input>
, используя только CSS (т.е. правила, которые применяются всякий раз, когда поле пусто, и не раз ввод текста). Вы можете выбрать изначально пустые поля, если у них есть пустой атрибут value
(input[value=""]
) или вообще нет атрибута (input:not([value])
), но это о нем.
Ответ 2
Возможно с встроенным javascript onkeyup="this.setAttribute('value', this.value);"
и input:not([value=""]):not(:focus):invalid
Демо: 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);" />
Ответ 3
Вы можете попробовать использовать: placeholder-shown...
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>
Ответ 4
Вы можете подойти к этому по-другому; опустить использование псевдокласса :empty
и использовать события input
для определения значимого значения в поле <input>
и соответственно его стиля:
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>
Ответ 5
.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>
Ответ 6
Это должно работать в современных браузерах:
input[value]:not([value=""])
Он выбирает все входы с атрибутом value и затем выбирает входы с непустым значением среди них.
Ответ 7
input:not([value=""])
Это работает, потому что мы выбираем вход только тогда, когда нет пустой строки.