likes
comments
collection
share

「原生练手」打造一个波浪动画登录表单

作者站长头像
站长
· 阅读数 16

本篇文章我们会实现一个酷炫的登录表单,主要体现在表单字段的标签的波浪特效上,就像下图中这样:

「原生练手」打造一个波浪动画登录表单

思路分析

整个表单的核心就在这个波浪特效的设计,这里我们需要用到transition-delay这个属性,表单字段标签中的每个字符我们都用一个span去包裹,然后通过transition-delay设置一个延迟,比如第一个字符延迟0ms后开始过渡动画,第二个字符延迟50ms后开始过渡动画,以此类推

然后在输入框focus的时候使用transform去改变每个字符的位置即可实现该效果

HTML

首先看看整体页面的结构

<div class="login-form">
  <h1>Login</h1>
  <form action="#">
    <div class="form-item">
      <input id="email" type="text" />
      <label for="email">
        <span style="transition-delay: 0;">E</span>
        <span style="transition-delay: 50ms;">m</span>
        <span style="transition-delay: 100ms;">a</span>
        <span style="transition-delay: 150ms;">i</span>
        <span style="transition-delay: 200ms;">l</span>
      </label>
    </div>

    <div class="form-item">
      <input id="password" type="password" />
      <label for="password">Password</label>
    </div>

    <button type="submit">Login</button>

    <p>Don't have an account?&nbsp;<a href="#">Register</a></p>
  </form>
</div>

根据前面的思路分析,这里我给email表单字段的标签设置成五个span标签,分别存放每个字符,然后通过内联样式添加上transition-delay过渡动画延迟,这样一来其实就可以纯css去实现波浪效果

但是感觉这样的话,html的可读性变低了,所以我会考虑采用第二种方案 -- 用js动态生成span标签

比如这里的password字段的label中就是一个Password字符串,那么可以通过js遍历这些字符,将每个字符包裹到一个span标签里面,动态插入到html中,这样一来,html的代码就会变得简洁不少,提高可读性

JavaScript

根据上面的分析,我们先来实现js的部分,js部分很简单,就是遍历label中的每个字符,用span去包裹后再放回label标签中

((doc) => {
  /** @type { HTMLLabelElement[] } */
  const oLabels = doc.querySelectorAll(".login-form .form-item label");

  const init = () => {
    oLabels.forEach((oLabel) => {
      oLabel.innerHTML = oLabel.innerText
        .split("")
        .map(
          (letter, idx) =>
            `<span style="transition-delay: ${idx * 50}ms;">${letter}</span>`
        )
        .join("");
    });
  };

  init();
})(document);

CSS

最后我们再来看看css的实现:

@import url("https://fonts.googleapis.com/css2?family=Fira+Code:wght@300;400;500;600;700&family=Fira+Mono:wght@400;500;700&display=swap");

:root {
  --primay-color: #4c3575;
  --form-bg-color: #371b58;
  --form-text-color: #ca82ff;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
}

body {
  display: grid;
  place-items: center;
  background-color: var(--primay-color);
  font-family: "Fira Mono", monospace;
}

.login-form {
  display: flex;
  flex-direction: column;
  align-items: center;
  color: var(--form-text-color);
  padding: 30px;
  background-color: var(--form-bg-color);
  border-radius: 12px;
}

.login-form form {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.login-form .form-item {
  position: relative;
  margin-bottom: 30px;
}

.login-form .form-item input {
  display: block;
  width: 100%;
  color: white;
  background-color: transparent;
  border: none;
  border-bottom: 2px solid white;
  padding: 15px 0;
  font-size: 24px;
}

.login-form .form-item input:focus {
  outline: none;
}

.login-form .form-item label {
  position: absolute;
  top: 20px;
  left: 0;
}

.login-form .form-item label span {
  display: inline-block;
  transition: all 0.3s ease;
}

.login-form .form-item input:focus + label span {
  color: var(--form-text-color);
  transform: translateY(-30px);
}

.login-form button {
  width: 100%;
  cursor: pointer;
  padding: 15px;
  border: none;
  border-radius: 12px;
  background-color: var(--form-text-color);
  transition: transform 0.5s ease;
}

.login-form button:active {
  transform: scale(0.95);
}

.login-form a {
  text-decoration: none;
  color: #a760ff;
}

整体都很常规,主要核心就在于当input出于focus状态的时候,要给label中的span进行一个Y轴方向上的偏移,再结合上内联样式中的transition-delay样式实现依次位移的效果,也就是波浪动画

配色的选择

整个表单看起来要顺眼的话,配色很重要,这里我的配色原则是,背景色要浅色,表单主体要深色,并且要是同一个色系的,最后文字的颜色要比背景色更浅更亮,这样整个表单看起来就会很自然顺眼不少

关于配色网站,这里推荐一个我平时经常用的,里面很多好看配色

colorhunt.co/