示例
某次冲浪时看到了提示文字能浮动的输入框,效果如下:
很酷的效果,于是我便开始着手实现。
使用HTML + CSS实现
这种效果可以直接使用HTML + CSS的方法实现,接下来,我们一步步地完成这个输入框。
首先,先写一个input,并添加一些基本样式
<input class="input">
.input {
width: 200px;
height: 40px;
font-size: 20px;
padding: 0 0 0 10px;
border: #cfcfcf 1px solid;
border-radius: 3px;
outline: none;
}
然后,我们需要给输入框加上提示文字,比如"Email"。这里,提示文字需要置于输入框中,首先想到的是input的placeholder属性,但是这样就无法实现提示文字的浮动效果。所以,只能单独使用一个div来承载,并且我们需要在外层使用一个div包裹住。
<div class="wrapper">
<input class="input">
<div class="hint">Email</div>
</div>
为wrapper和提示文字添加样式。其中,为了使提示文字能够置于输入框之中,我们采用绝对定位的方式。
.wrapper {
position: relative;
height: 50px;
display: flex;
justify-content: center;
align-items: flex-end;
}
.hint {
display: inline-block;
position: absolute;
color: #cfcfcf;
font-size: 20px;
height: 20px;
padding: 0 4px 0;
top: 16px;
left: 7px;
}
嗯,看着有模有样了。但是这时候,如果我们把鼠标放在"Email"点击,却发现输入框没有反应。这是为什么呢?
原来,"Email"所处的div位于input的上层,当我们点击"Email"时,鼠标的点击事件被div所捕获,input就不会认为你点击了它,于是就不会聚焦。那怎么解决呢?
CSS中有一个pointer-events属性,用于设置元素对于鼠标事件的反应。我们将.hint的pointer-events设置为none,就能使其忽略鼠标的事件。鼠标的点击就能直接传递到输入框。
.hint {
...
pointer-events: none;
}
现在,我们可以正常地与输入框交互了。接下来,我们来实现提示文字的浮动效果。
在这里,我们用到.input:focus伪类,当聚焦于输入框时,就提示文字移动到左上角并缩小,同时加上白色背景,遮住输入框的边框。
.input:focus {
border: #55A7FF 1px solid;
}
.input:focus + .hint {
font-size: 12px;
height: 12px;
top: 0px;
background-color: #ffffff;
}
同时,在.input和.hint类中加上transition动画效果。
.input {
...
transition: all ease-in-out 0.1s;
}
.hint {
...
transition: all ease-in-out 0.1s;
}
这样,当我们点击输入框时,提示文字就有浮动效果了。
好像大功告成了,是吗?我们试着输入文字,然后点击周围取消聚焦,发现出现这样的情况。
提示文字又返回到输入框里了,原因是我们没有判断输入框中是否有文字。怎么解决呢?我们可以使用js监听输入框的change事件来判断是否有文字,并手动修改样式,但这样未免太麻烦。
HTML的input元素有一个required属性,可以用来判断输入框中是否有内容。当输入框中有内容时,:valid伪类生效。借此思路,我们可以做如下的修改。
<input class="input" required>
.input:focus + .hint, .input:valid + .hint {
...
}
至此,我们的输入框和提示文字就能正常地工作了!
源码地址: codepen.io/moomoolo/pe…
总结
在这个带浮动提示的输入框的实现中,最主要的两个点是使用pointer-events: none来忽略鼠标点击事件以及使用required属性和:valid伪类来判断输入框内容。
希望这篇文章能给大家带来帮助,欢迎大家评论讨论。