开篇王炸,上效果图
这个效果如果让你用纯HTML+css来做,你心中会有思路吗?
效果难点:
- 用css检查input框是否有内容
- 当两个输入框都不为空时登录按钮再允许点击
- css过渡动画的熟练使用
实现过程以及思路
先写出基础的HTML
<form>
<h1>登录</h1>
<div class="input-box">
<input type="text" id="logUsername" placeholder=" ">
<label for="logUsername">邮箱/用户名</label>
</div>
<div class="input-box">
<input type="text" id="logPassword" placeholder=" ">
<label for="logPassword">密码</label>
</div>
<button>登录</button>
</form>
- 注意:如果不使用label标签,我们就必须写js实现点击文本穿透到input的效果,但这就和标题相违了。
接下来要准备一些CSS,让整个表单有开篇那个动图的表单主题
form{
font-family:monospace;
width:300px;height: 300px;
background:#444;color:white;
box-sizing:border-box;
padding: 20px;
}
form > * {
margin-top:20px;
}
h1 {
text-align: center;
}
div.input-box > input {
height:2em;
background:transparent;color:white;
outline:none;border:none;
border-bottom:1px solid #fff;
}
button {
width: 100%;height:2em;
background:transparent;color:white;
outline:none;border:1px solid #fff;
}
可能和原图略有偏差,问题不大
用transform给label标签写两种位置状态,分别是在input元素之上 和 与input重叠
并分别设置于:input聚焦时和默认时两种状态
使用加号可以使选择器命中与input同级的label元素
div.input-box{ position:relative; }
div.input-box > input { width:100%; }
input + label{
position:absolute;
top:.5em;
cursor:text;
transition:all .5s;
transform-origin: left; /* 一定要设置旋转基准点 */
}
input:focus + label,
input:not(:placeholder-shown) + label{
position:absolute;
transform: translateY(-120%) scale(.778) ;
}
input :not( :placeholder-shown ) + label {}
可以这么理解:
- 首先获取input标签
- 从步骤1中获取到的标签进行一次过滤,过滤规则是:placeholder没有在展示
- 将 placeholder没有在展示中的input元素
- 命中加号左边的筛选结果,去找同级的label元素
- 因为input元素的placeholder设置成了一个空格,所以看上去好像没有placeholder一样,
- 实际是有的,而这么设置的目的就是配合:placeholder-shown完成这么一个特殊的css条件选择器
- 当没有聚焦也没有输入文字时那么input旁边的label就无法命中在input之上且文字缩小的样式
- 如果有聚焦或者有输入文字,label才会命中样式,跑到input的上边同时变小
接下来给登录按钮写一套禁用的样式和一套hover的样式
button {
width: 100%;height:2em;
background:transparent;color:white;
outline:none;border:1px solid #fff;
}
button[disabled] {
width: 100%;height:2em;
background:transparent;color:#fff3;
outline:none;border:1px solid #fff3;
}
button:hover{
background:#fff3;
}
拥有了这三种不同状态的按钮样式,重要的地方,css选择器部分:
- 当input任意一个未填写时,按钮都是禁用状态的
- 只有当按钮为可用(input填写完毕)按钮才支持hover态
- 禁用态时没有hover效果
button {
/* 默认禁用态 */
width: 100%;height:2em;
background:transparent;color:#fff3;
outline:none;border:1px solid #fff3;
}
form:not(:has(:placeholder-shown)) > button {
/* 可用 */
width: 100%;height:2em;
color:white;
border:1px solid #fff;
}
form:not(:has(:placeholder-shown)) > button:hover {
/* 可用且hover */
background-color: #fff4;
}
慢慢来,一步一步解析这个选择器表达式
- 从form出发,选择到整个form元素,
- 然后not进行一次取反操作,取反的规则是:后代有placeholder正在展示中的元素
- 如果form元素的后代有placeholder正在展示中的元素,那么就不应用后面的样式
- 如果没有placeholder正在展示中,也就是都已经填好内容,才可以应用后面的样式