skip to Main Content

I was trying to design a log in front end with some wave effect to make the letters of the label move in a wave shape but I can’t get the span tag to be added dynamically to the letters
I will put the HTML and jQuery code then the CSS code and finally the DOM code

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>login wave effect</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    <link rel="stylesheet" href="stylesheet.css">
    <script src="code.jquery.com_jquery-3.7.0.js"></script>
</head>
<body>
    <div class="container">
        <h1>Please Login</h1>
        <form>
            <div class="form-container">
                <input type="text" required >
                <label for="input">Email</label>
            </div>
            <div class="form-container">
                <input type="password" required>
                <label for="input">Password</label>
            </div>
            <button class="btn" type="submit">Login</button>
        </form>
        <p class="text">
            Don't have an account? <a href="#">Register</a>
        </p>
    </div>
    <script src="script.js"></script>
    <!--<script>
        $(".form-container label").each(function(){
            $(this).html = $(this)
            .text()
            .split("")
            .map(function(element,idx){
                `<span style="transition-delay:${idx*50}ms">${element}</span>`})
            .join('')
        });
    </script>-->
</body>
</html>

this is the DOM Code

var labels = document.querySelectorAll(".form-container label");
labels.forEach(function(label){
    label.innerHTML = innerText
    .split("")
    .map(function(element,idx){
        `<span style="transition-delay:${idx*50}ms">${element}</span>`})
    .join('');
 });

This is the CSS code

@import url('https://fonts.googleapis.com/css?family=Muli&display=swap');
*{
    box-sizing: border-box;
}
body{
    font-family:'Muli', sans-serif;
    margin: 0;
    display:flex;
    flex-direction: column;
    align-items: center;
    justify-content:center;
    height: 100vh;
    overflow: hidden;
    background-color: lightblue;
}
.container{
    position: relative;
    background-color: rgb(44, 88, 124);
    color: white;
    padding: 20px 50px;
    border: 0;
    border-radius: 10px;
    position: relative;
}
.btn{
    display: block;
    font-family: inherit;
    width: 100%;
    padding :10px;
    border: 0;
    border-radius: 5px;
    background-color: blueviolet;
    color: aliceblue;
    left: 0;
    margin-bottom: 60px;
}
.btn:active{
    outline: 0;
    transform: scale(0.95);
    background-color: rgb(83, 20, 142);
}
h1{
    text-align: center;
    font-size: 60px;
    margin: 10px 0 30px;
}
.form-container{
    margin:20px 0px 40px;
    padding: 10px;
    width: 300px;
}
.form-container input{
    background-color: transparent;
    border: 0;
    border-bottom: 2px white solid;
    width: 100%;
    height: 30px;
    font-size: 20px;
    color: bisque;
}
.form-container input:focus,
.form-container input:valid{
    outline: 0;
}
.text{
    margin-top: 50px;
}
.text a{
    text-decoration: none;
    color: rgb(30, 3, 8);
}
.form-container label{
    width: 100px;
    height: 50px;
}
.form-container label span{
    position: absolute;
    top: 15px;
    transition: transform 0.3s ease-in-out;
}
.form-container input:focus + label span,
.form-container input:valid + label span{
    transform: translateY(-40px);
}

2

Answers


  1. your map function is missing the return statement, also the innerText is not defined in the given script i don’t know if you just didn’t mention it in this code.

    the script should be:

    let innerText = "";//get the value from somewhere
    var labels = document.querySelectorAll(".form-container label");
    labels.forEach(function(label){
        label.innerHTML = innerText
        .split("")
        .map(function(element,idx){
            //here the return statement
            return `<span style="transition-delay:${idx*50}ms">${element}</span>`;})
        .join('');
     });
    
    Login or Signup to reply.
  2. That’s a perfect case for using CSS var() and CSS calc().
    Set the --idx CSS var to the element index and multiply it in CSS (animation-delay) by the desired time using calc() like: calc(var(--idx) * 0.2s)

    const labels = document.querySelectorAll(".form-container label");
    
    labels.forEach(function(label) {
      label.innerHTML = [...label.textContent].map((char, idx) => {
        return `<span style="--idx:${idx};">${char}</span>`;
      }).join("");
    });
    form label span {
      display: inline-block;
      animation: wave 1s linear calc(var(--idx) * 0.2s) alternate infinite;
      translate: 0 -30%;
    }
    
    @keyframes wave {
      to { translate: 0 30%; }
    }
    <div class="container">
      <h1>Please Login</h1>
      <form>
        <div class="form-container">
          <input type="text" required>
          <label for="input">Email</label>
        </div>
        <div class="form-container">
          <input type="password" required>
          <label for="input">Password</label>
        </div>
        <button class="btn" type="submit">Login</button>
      </form>
      <p class="text">
        Don't have an account? <a href="#">Register</a>
      </p>
    </div>

    also, notice that .map() should have an either direct or implicit return statement. Also, innerText is not defined and set. You meant to use Element.textContent instead (which BTW is preferred over Element.innerText).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search