:not(:empty)CSS选择器不起作用?

时间:2011-12-26 21:39:05

标签: html css css3 css-selectors

我对这个特殊的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中测试。

13 个答案:

答案 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/

&#13;
&#13;
input:not([value=""]):not(:focus):invalid{
  background-color: tomato;
}
&#13;
<input 
  type="email" 
  value="" 
  placeholder="valid mail" 
  onkeyup="this.setAttribute('value', this.value);" />
&#13;
&#13;
&#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个事件are currently experimental,并且可能没有得到广泛支持。

答案 4 :(得分:7)

&#13;
&#13;
.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;
&#13;
&#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 并成功。