实现谷歌登录输入框交的互效果
分析
我们在登录谷歌输入账号的时候会发现有这么一个交互的效果,当input
聚焦时,占位符会有一个缩小的动画并且移动到左上角.
通过控制台可以看到,是用一个div
去充当占位符,并且在input聚焦的时候通过transform
属性缩小值,并且移动到输入框的上方,通过transition
给transform
加上动画.
参考实现
根据上面分析,以下为dom
结构:
<div class="warp">
<input type="text">
<div>电子邮件地址或电话号码</div>
</div>
在css
中对占位文字做了长度限制,取消了他的点击事件(为了能够触发input
的聚焦).
.warp {
width: 200px;
position: relative;
div {
bottom: 17px;
left: 15px;
background: #fff;
max-width: 100%;
position: absolute;
pointer-events: none;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1),
opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);
}
input {
width: 100%;
border-radius: 4px;
color: rgb(32, 33, 36);
font-size: 17px;
height: 28px;
padding: 13px 15px;
&:focus ~ div {
transform: scale(0.75) translateY(-39px);
color: rgb(26, 115, 232);
}
}
}
.move {
transform: scale(0.75) translateY(-39px);
}
这样在没有输入文字的时候就可以做到上图效果了,但是当用户输入了文字,失焦时占位文字应该保持在上方,而不是继续下来这样就会挡住文字,所以需要用js
判断下当input
有值时给他添加上对应的样式,这样就可以让他保持在上面,这里定义了一个.move
类来移动元素.
const input = document.querySelector(".warp input");
const div = document.querySelector(".warp div");
input.addEventListener("blur", ({ target: { value } }) => {
const { classList } = div;
value ? classList.add("move") : classList.remove("move");
});
优化
上面用到了js
来判断input
是否有值.那么不使用js也能做到这样的效果吗?我们利用valid伪类来实现判断功能.
<div class="warp">
<input type="email" id="email" required>
<label for="email">电子邮件地址或电话号码</label>
</div>
.warp {
margin: 50px auto;
width: 200px;
position: relative;
}
input {
width: 100%;
border-radius: 4px;
border: 1.5px solid black;
color: rgb(32, 33, 36);
font-size: 17px;
height: 28px;
padding: 13px 15px;
outline: none;
&:focus {
border-color: rgb(26, 115, 232);
}
}
label {
position: absolute;
bottom: 17px;
left: 15px;
background: #fff;
max-width: 100%;
pointer-events: none;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1),
opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);
transform-origin: left bottom;
}
input:focus + label {
color: rgb(26, 115, 232);
}
input:focus + label,
input:valid + label {
transform: scale(0.75) translateY(-39px);
}
:valid
伪类用来选择任何通过验证的 <input>,<form>,<fieldset>
等其他表单元素
这里设置了input type="email"
输入框会自动验证输入值是否是一个或多个合法的电子邮箱地址(非空值且符合电子邮箱地址格式,当然我们也可以自己编写约束验证 API CSS
伪标签 :valid
和 :invalid
能够在校验后自动应用,我们可以根据这两个伪类来编写对应状态下的样式.
总结
通过这一个简单的交互效果,首先分析了利用transform
和transition
来实现移动和过渡的效果,其次通过js
判断了输入框有值时将提示文字保持在左上角.最后通过:valid
伪类来进一步优化,来判断通过typd=email input
的校验,给他们编写对应的样式从而达到了不使用js
就能实现效果.