⭐️ 巧用 css3 实现一个带有输入状态表示的表单

247 阅读3分钟

开篇王炸,上效果图

效果图.gif

这个效果如果让你用纯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;
  }

Snipaste_2022-10-07_23-34-38.png

可能和原图略有偏差,问题不大

用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 {}

可以这么理解:

  1. 首先获取input标签
  2. 从步骤1中获取到的标签进行一次过滤,过滤规则是:placeholder没有在展示
  3. 将 placeholder没有在展示中的input元素
  4. 命中加号左边的筛选结果,去找同级的label元素
  • 因为input元素的placeholder设置成了一个空格,所以看上去好像没有placeholder一样,
  • 实际是有的,而这么设置的目的就是配合:placeholder-shown完成这么一个特殊的css条件选择器
  • 当没有聚焦也没有输入文字时那么input旁边的label就无法命中在input之上且文字缩小的样式
  • 如果有聚焦或者有输入文字,label才会命中样式,跑到input的上边同时变小

123.gif

接下来给登录按钮写一套禁用的样式和一套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;
  }

Snipaste_2022-10-08_00-28-17.png

拥有了这三种不同状态的按钮样式,重要的地方,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;
}

慢慢来,一步一步解析这个选择器表达式

  1. 从form出发,选择到整个form元素,
  2. 然后not进行一次取反操作,取反的规则是:后代有placeholder正在展示中的元素
  3. 如果form元素的后代有placeholder正在展示中的元素,那么就不应用后面的样式
  4. 如果没有placeholder正在展示中,也就是都已经填好内容,才可以应用后面的样式

123.gif

大功告成,没有写任何js代码就做出来了。