由来
打开 CodePen 网站,首页推荐里看到一个有关 「表单 placeholder」 的设计,它的效果如下:
可以看到当鼠标点入输入框后,placeholder 文字飘到了输入框的上面且变了文字颜色。这种风格立马吸引了我,因为在学前端,我自然不会放过研究下它实现的原理这个机会。
源码
为了方便,我将原来的代码进行了缩减,不然因为太长会在文章里显得凌乱而分散注意力。
缩减后的表单展现是这样的:


HTML结构
这是缩减后的 HTML 片段:
<div class="form">
<div class="input-container">
<input id="firstname" class="input" type="text"
placeholder=" " />
<div class="cut"></div>
<label for="firstname" class="placeholder">First name</label>
</div>
</div>
没有多少可解释的,它的结构包含:
-
一个 form 容器 (div.form)。 -
一个 input 容器 (div.input-container),用来包裹 输入框 和 placeholder 。 -
输入框 (input.input) 和 placeholder (label.placeholder);div.cut 的作用在后面会谈到。
惟一要关注的,是它没有使用 input 标签原生的 placeholder 属性,而是用 label 作为替代,猜测是原生的属性不方便进行 CSS 修饰,而对 label 标签则可以「肆意妄为」。
CSS 代码
我们分成多块来说,以免一次性说太多,无法聚焦。
1. form 容器 (div.form) 的样式
.form {
background-color: #15172b;
border-radius: 20px;
box-sizing: border-box;
width: 320px;
height: 500px;
padding: 20px;
margin: 20px auto;
}
重点是它的宽高和背景色,就像前文图中所看到的。
2. input 容器 (div.input-container) 的样式
.input-container {
height: 50px;
position: relative;
width: 100%;
}
容器的 position 被设为了 relative,为什么?结合前文的效果图片可以知道,要把 label.placeholder 挪到 input 内,最常规的办法就是用定位了,让它相对于容器进行位移。
3. input 的样式
.input {
background-color: #303245;
border-radius: 12px;
border: 0;
box-sizing: border-box;
color: #eee;
font-size: 18px;
width: 100%;
height: 100%;
outline: 0;
padding: 4px 20px 0;
}
没什么可说的,就是设置常规的背景色、圆角、边框等。
4. div.cut 的样式
.cut {
background-color: #15172b;
border-radius: 10px;
height: 20px;
left: 20px;
position: absolute;
top: -20px;
transform: translateY(0);
transition: transform 200ms;
width: 76px;
}
该元素的背景色和 form容器 的背景色是一样的,我们在视觉上看不出它的作用。如果将背景色调成白色,结果就一目了然了:


即,div.cut 的作用是在鼠标点进输入框后装饰 placeholder 文字。
因为该元素需要位移到 input 的上方,所以使用了 position: absolute 进行定位。
left: 20px 是因为 input 的 padding-left 也是 20px,相当于和 input 输入起点对齐了。
top: -20px 是因为该元素的高度是 20px 且要位移到 input 的上方(也就是 input容器 的上方),即相对于 input容器 向上移动 20px;
transition: transform 200ms,这是为了后续的动画做准备,仔细观察 图 04 和 图 05,鼠标点进输入框后,div.cut 下移了几个像素。
5. label.placeholder 的样式
.placeholder {
color: #65657b;
font-family: sans-serif;
left: 20px;
line-height: 14px;
pointer-events: none;
position: absolute;
transform-origin: 0 50%;
transition: transform 200ms, color 200ms;
top: 20px;
}
left: 20px 和上面 div.cut 一样,为了保持和 input 输入起点一致。
整个 input容器 是50px的高度,top: 20px 刚好可以让 placeholder 落入 input 中间偏下的位置(从上面图片也能看出来)。
transition: transform 200ms, color 200ms 是为后面的动画过度效果做准备:当鼠标点进输入框后,placeholder 会上移到 div.cut 中,文字颜色也会改变。
*接下来是非常重要的动画部分:当鼠标点进输入框后,利用 :focus 伪类选择器,进行元素样式的动态调整。
6. input 获取焦点后,div.cut 的样式
.input:focus ~ .cut {
transform: translateY(8px);
}
transform: translateY(8px) 是让 div.cut 下移 8px,这在第4点 div.cut 的样式 中已有说明。
7. input 获取焦点后,label.placeholder 的样式
.input:focus ~ .placeholder {
transform: translateY(-30px) translateX(10px) scale(0.75);
color: #dc2f55;
}
transform: translateY(-30px) translateX(10px) scale(0.75) input 获取焦点后,我们需要把 input 内的 placeholder 上移到 div.cut 内,且上移后文字要变小,故这里同时使用了 位移(translate) 和 放大缩小(scale)。其中水平右移10px是为了让 placeholder 相对于 input输入起点 有 10px 的水平间隔,这个值可以按自己的喜好随意调。
以上是较为详尽的解释。
一个看似简单的效果竟然涉及如此多的 CSS 规则,真是让我捏把汗😓 。。
有用吗?分享一下吧!
原始的 CodePen 在这里[1]。
参考资料
CodePen: Form Placeholders: https://codepen.io/ainalem/pen/GRqPwoz
– END –
原文始发于微信公众号(背井):前端学习(2): 从一个实际案例介绍 input placeholder 的创意设计
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/246796.html