我对这个特殊的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中测试。
答案 0 :(得分:134)
作为void element,<input>
元素被HTML定义为“空”被视为empty,因为所有void元素的内容模型始终为空。因此,它们将始终匹配:empty
伪类,无论它们是否具有值。这也是为什么它们的值由开始标记中的属性表示的原因,而不是开始和结束标记中的文本内容。
另外,来自Selectors spec:
:empty
伪类表示根本没有子元素的元素。就文档树而言,只有数据具有非零长度的元素节点和内容节点(如DOM文本节点,CDATA节点和实体引用)必须被视为影响空虚;
因此,input:not(:empty)
永远不会匹配正确的HTML文档中的任何内容。 (它仍然可以在假定的XML文档中工作,该文档定义了一个可以接受文本或子元素的<input>
元素。)
我认为您不能仅使用CSS动态设置空<input>
字段(即只要字段为空时应用的规则,并且一旦输入文本就不应用)。您可以选择最初空字段,如果它们具有空value
属性(input[value=""]
)或完全缺少属性(input:not([value])
),那就是它。< / p>
答案 1 :(得分:36)
可以使用内联javascript onkeyup="this.setAttribute('value', this.value);"
&amp; input:not([value=""]):not(:focus):invalid
演示:http://jsfiddle.net/mhsyfvv9/
input:not([value=""]):not(:focus):invalid{
background-color: tomato;
}
&#13;
<input
type="email"
value=""
placeholder="valid mail"
onkeyup="this.setAttribute('value', this.value);" />
&#13;
答案 2 :(得分:27)
您可以尝试使用:占位符显示...
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>
虽然没有很大的支持...... caniuse
答案 3 :(得分:7)
你可以采用不同的方法;省略使用: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>
input
Events(DOM Mutation事件现已在DOM级别4中弃用,并已被DOM Mutation Observers取代。) 免责声明: 请注意input
个事件are currently experimental,并且可能没有得到广泛支持。
答案 4 :(得分:7)
.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%;
}
&#13;
<div class="floating-label-input">
<input type="text" id="id" required/>
<label for="id" >User ID</label>
<span class="line"></span>
</div>
&#13;
答案 5 :(得分:2)
我试图复制 Gmail 登录。当您单击“电子邮件或电话”并在其上键入内容时,标签会平移 (-38 像素) 和缩放 (0.75)。
我做了什么:-
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection(uid)
.doc('toDos')
.collection('toDos')
.where('dateTime', isNotEqualTo: DateTime.now())
.orderBy('dateTime', descending: false)
.snapshots(),
builder: (context, snapshots) {
if (snapshots.hasData) {
return ListView.builder(
shrinkWrap: true,
itemCount: snapshots.data.docs.length,
itemBuilder: (context, index) {
DocumentSnapshot documentSnapshots =
snapshots.data.docs[index];
return ListTile(
title: Text(documentSnapshots['dateTime']
.toDate()
.toString()),
subtitle: Container(
color: Colors.redAccent,
child: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection(uid)
.doc('toDos')
.collection('toDos')
.orderBy('dateTime',
descending: false)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
physics:
NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount:
snapshot.data.docs.length,
itemBuilder: (context, index) {
DocumentSnapshot
documentSnapshot =
snapshot.data.docs[index];
Timestamp timestamp =
documentSnapshot['dateTime'];
return Dismissible(
background: Container(
decoration: BoxDecoration(
color: Colors.redAccent,
borderRadius:
BorderRadius
.circular(
12.0)),
alignment:
Alignment.centerLeft,
child: Icon(Icons.delete),
),
onDismissed: (direction) =>
DatabaseService()
.deleteToDos(
documentSnapshot[
'todoTitle']),
key: Key(documentSnapshot[
'todoTitle']),
child:
documentSnapshot[
'dateTime'] ==
documentSnapshots[
'dateTime']
? Card(
elevation: 0.7,
shape:
RoundedRectangleBorder(
borderRadius:
BorderRadius
.circular(
12.0,
),
),
child: ListTile(
subtitle: Text(
ChooseLanguageState
.enLang
? '\n' +
dateEng
.format(DateTime.tryParse(timestamp
.toDate()
.toString()))
.toString()
: '\n' +
dateRu
.format(DateTime.tryParse(timestamp.toDate().toString()))
.toString(),
style:
TextStyle(
fontFamily:
'MontserratLight',
fontWeight:
FontWeight
.w200,
color: Colors
.grey,
fontSize:
sizeX.height /
70,
),
),
leading:
Padding(
padding: EdgeInsets
.only(
top:
10,
bottom:
10),
child:
IconButton(
onPressed:
() async {
setState(
() {
DatabaseService()
.completeTask(documentSnapshot['todoTitle']);
});
},
icon: documentSnapshot[
'isComplete']
? SvgPicture
.asset(
'assets/icons/icon_done.svg',
)
: SvgPicture
.asset(
'assets/icons/icon_circle.svg',
color:
Colors.black,
),
),
),
title: Text(
documentSnapshot[
'todoTitle'],
style: TextStyle(
fontFamily:
'MontserratLight',
fontWeight:
FontWeight
.w700,
color: Colors
.black),
),
trailing:
IconButton(
onPressed:
() {
setState(
() {
DatabaseService().deleteToDos(documentSnapshot['todoTitle']);
});
},
icon: SvgPicture
.asset(
'assets/icons/icon_trash.svg',
color:
Colors.redAccent,
)),
),
)
: null);
},
);
} else if (snapshots.hasError) {
const Text('No Data');
}
return Center(
child: CircularProgressIndicator());
}),
),
);
});
} else if (snapshots.hasError) {
const Text('No Data');
}
return Center(
child: Container(),
);
},
),
然后在我的 CSS 中
<input type='email' class='email' placeholder=' ' />
如果您尝试并发现任何问题。请分享。
答案 6 :(得分:0)
纯CSS解决方案
ListView
答案 7 :(得分:0)
由于占位符在输入中消失,因此可以使用:
input:placeholder-shown{
//rules for not empty input
}
答案 8 :(得分:0)
另一种纯CSS解决方案
.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>
答案 9 :(得分:-1)
这应该适用于现代浏览器:
input[value]:not([value=""])
选择具有value属性的所有输入,然后选择其中非空值的输入。
答案 10 :(得分:-1)
input:not([value=""])
这是有效的,因为我们只在没有空字符串时才选择输入。
答案 11 :(得分:-1)
input:not(:invalid){
border: 1px red solid;
}
// or
input:not(:focus):not(:invalid){
border: 1px red solid;
}
答案 12 :(得分:-1)
你可以在你的输入中使用 &:valid 并成功。