跳到主要内容

实现谷歌登录输入框交的互效果

分析

我们在登录谷歌输入账号的时候会发现有这么一个交互的效果,当input聚焦时,占位符会有一个缩小的动画并且移动到左上角. 谷歌登陆动图 通过控制台可以看到,是用一个div去充当占位符,并且在input聚焦的时候通过transform属性缩小值,并且移动到输入框的上方,通过transitiontransform加上动画. 控制台分析元素

参考实现

根据上面分析,以下为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 能够在校验后自动应用,我们可以根据这两个伪类来编写对应状态下的样式.

点击这里查看在线demo

总结

通过这一个简单的交互效果,首先分析了利用transformtransition来实现移动和过渡的效果,其次通过js判断了输入框有值时将提示文字保持在左上角.最后通过:valid伪类来进一步优化,来判断通过typd=email input 的校验,给他们编写对应的样式从而达到了不使用js就能实现效果.