CSS 文本转换仅在 HTML 输入有 "required" 标签时有效

CSS text transition only works when HTML input has "required" tag

我在表单中设置了文本输入字段,我设置了样式以便标签从框中开始,然后在字段处于焦点时向上滑动。但是,这仅适用于“必填”字段,所有其他字段的标签都已经在框上方。我如何让这些人像其他人一样表现?

Picture of the form fields in question

HTML:

        <div class="tGroup">
            <input  id="email" maxlength="80" name="email" size="20" type="text" required>
            <span class="bar"></span>
            <label for="email">Email</label>
        </div>
        
        <div class="tGroup">
            <input  id="company" maxlength="40" name="company" size="20" type="text" required>
            <span class="bar"></span>
            <label for="company">Company</label>
        </div>

        <div class="tGroup">
            <input  id="url" maxlength="80" name="url" size="20" type="text">
            <span class="bar"></span>
            <label for="url">Website</label>
        </div>

        <div class="tGroup">
            <input  id="city" maxlength="40" name="city" size="20" type="text">
            <span class="bar"></span>
            <label for="city">City</label>
        </div>

CSS:

.tGroup { 
    position:relative; 
    margin-bottom:45px; 
    float:left;
    margin-right: 40px;
}

.tGroup input {
    font-size:.9em;
    padding:10px 0px;
    display:block;
    width:300px;
    border:none;
    color: #fff;
    background-color: transparent;
    border-bottom:1px solid #757575;
}

.tGroup input:focus { outline:none; }

.tGroup label {
    color:rgb(255, 255, 255); 
    font-size: .9em;
    font-weight:normal;
    position:absolute;
    pointer-events:none;
    top:10px;
    transition:0.2s ease all; 
    -moz-transition:0.2s ease all; 
    -webkit-transition:0.2s ease all;
}
  
/* active state */
.tGroup input:focus ~ label, input:valid ~ label {
    top:-20px;
}

问题出在 input:valid ~ label 上,因为您是说您希望有效的输入在标签上应用该特定样式,但由于最后 2 个没有必需的属性,因此它们没有不分类。你可以删除它。

body{
  background:black;
}
.tGroup { 
    position:relative; 
    margin-bottom:45px; 
    float:left;
    margin-right: 40px;
     margin-top: 30px;
}

.tGroup input {
    font-size:.9em;
    padding:10px 0px;
    display:block;
    width:300px;
    border:none;
    color: #fff;
    background-color: transparent;
    border-bottom:1px solid #757575;
}

.tGroup input:focus { outline:none; }

.tGroup label {
    color:rgb(255, 255, 255); 
    font-size: .9em;
    font-weight:normal;
    position:absolute;
    pointer-events:none;
    top:10px;
    transition:0.2s ease all; 
    -moz-transition:0.2s ease all; 
    -webkit-transition:0.2s ease all;
}
  
/* active state */
.tGroup input:focus ~ label  {
    top:-20px;
}
<div class="tGroup">
            <input  id="email" maxlength="80" name="email" size="20" type="text" required>
            <span class="bar"></span>
            <label for="email">Email</label>
        </div>
        
        <div class="tGroup">
            <input  id="company" maxlength="40" name="company" size="20" type="text" required>
            <span class="bar"></span>
            <label for="company">Company</label>
        </div>

        <div class="tGroup">
            <input  id="url" maxlength="40" name="url" size="20" type="text">
            <span class="bar"></span>
            <label for="url">Website</label>
        </div>

        <div class="tGroup">
            <input  id="city" maxlength="40" name="city" size="20" type="text">
            <span class="bar"></span>
            <label for="city">City</label>
        </div>

当 运行 代码片段时,我确实看到了一个小问题。在输入文本中输入信息并失去焦点后,文本标签返回并与输入的信息重叠。

这是一个替代解决方案,使用了一点 JavaScript。

我只是复制了您为标签的初始样式实现的 class,在副本中我只是将位置绝对更改为底部。

然后我使用 JS 遍历输入,使用事件(e)对象作为目标添加 focusin 事件侦听器,然后当每个输入被单击时,我只是修改了 class。

在 HTML 中,我为初始样式添加了 .startLabel class。此外,我将标签放在输入旁边(没有空格也没有回车 return),以便更好地定位 DOM 中的下一个兄弟姐妹。

const inputs = document.querySelectorAll('input');

for (let input of inputs) {
    input.addEventListener('focusin', function(e){
        addClass(e);
    }, false);
}





function getTarget(e){
    return e.target;
}

function addClass(e){
    let target; 
    let label;
    target = getTarget(e);
    label = target.nextSibling;
    label.className = 'lableup';
}
body    {
    background-color: black;
}

.tGroup { 
    position: relative; 
    margin-bottom: 45px; 
    float: left;
    margin-right: 40px;
}

.tGroup input {
    font-size:.9em;
    padding: 10px 0px;
    display: block;
    width: 300px;
    border: none;
    color: #fff;
    background-color: transparent;
    border-bottom: 1px solid #757575;
}

.tGroup input:focus { outline:none; }

.startLabel {
    color: rgb(255, 255, 255); 
    font-size: .9em;
    font-weight: normal;
    position: absolute; 
    top: 10px;
    pointer-events: none;
    transition: 0.2s ease all; 
    -moz-transition: 0.2s ease all; 
    -webkit-transition: 0.2s ease all;
}

.lableup {
    position: absolute; 
    bottom: 40px;
    color: rgb(255, 255, 255); 
    font-size: .9em;
    font-weight: normal;
    pointer-events: none;
    transition: 0.2s ease all; 
    -moz-transition: 0.2s ease all; 
    -webkit-transition: 0.2s ease all;
}

  

.tGroup input: focus ~ label, input:valid ~ label {
    top:-20px;
}

#wrapper {
    margin: 100px auto;
}
<div id='wrapper'>
        <div class="tGroup">
            <input  id="email" maxlength="80" name="email" size="20" type="text" required><label for="email" class="startLabel">Email</label><span class="bar"></span>

        </div>

        <div class="tGroup">
            <input  id="company" maxlength="40" name="company" size="20" type="text" required><label for="company" class="startLabel">Company</label>
            <span class="bar"></span>

        </div>

        <div class="tGroup">
            <input  id="url" maxlength="80" name="url" size="20" type="text"><label for="url" class="startLabel">Website</label>
            <span class="bar"></span>

        </div>

        <div class="tGroup">
            <input  id="city" maxlength="40" name="city" size="20" type="text"><label for="city" class="startLabel">City</label>
            <span class="bar"></span>

        </div>
    </div>