'How can I move a word by letter on hover in CSS?

I had asked a similar question about the same issue but the answers weren't the solution to my problem, since I want the letters of the word to move on hover, not once the page loads without being on hover, like this one: https://codepen.io/duncanlutz/pen/XWVaBQY , but if you're reading this, Duncan, thank you for taking the time to try to help. I'm trying to achieve that but when on hover.

I found another pen that gave me an idea on how to get the letters of the word to move no matter which letter is being hovered on. So, what I want is, for the all the letters to move together according to how I want them to move by only hovering over one letter. This is the pen that helped, if anyone's interested: https://codepen.io/younus-khan-abir/pen/KKWWGxd . It's the very first part. Here, the letters of the words don't move individually when being hovered but if you hover on one of the words, the word being hovered on and the other two words placed in different locations scale forward at the same time, with the help of the pseudo-elements ::before and ::after, and <a href=""...>.

Now, look at my pen so far: https://codepen.io/jenny0515/pen/LYeBOPJ

OR

HTML:

<body>
  <a href="" one="M" two="O" three="E">V</a>
</body>

CSS:

body{
  text-align: center;
  margin: 100px;
}

a::before{
  content: attr(one);
  left: 740px;
  position: absolute;
}

a::after{
  content: attr(three);
  position: absolute;
  left: 783px;
}

a:hover::before{
  content: attr(one);
  animation: move cubic-bezier(.32,.71,.28,.91) 3s     1 forwards;
}

a:hover::after{
  content: attr(three);
  animation: move cubic-bezier(.32,.71,.28,.91) 3s 1 forwards;
}

@keyframes move{
  from {
    opacity: 0;
    transform: translateX(-200px);
  }
  to {
    opacity: 1;
    transform: translateX(100px);
  }
}

Here, I haven't done anything to the "V" in "MOVE" yet. So, if you hover on "V", "M" and "E" will move as I want it to, but my issue is that, when I hover on "M" or "E", they don't move as it should... it just blinks.

My other issue is, I'm missing the "O" but I can't use another "::before". Is there a substitute for that or a loophole, so I can get the "O" to appear?

css


Solution 1:[1]

If you want to move the characters individually they have to each be in their own element.

While you can get a certain way using pseudo elements you are limited to just two and as you have pointed out it's not possible to do them all this way.

This snippet puts each character into a span element. It wraps the whole word in an element, word. It is this element that is centered within the center element.

Each direct child of word (i.e. each character) sets a CSS variable --n which is used to calculate the delay before it starts to move, just to make the CSS a little more compact and avoid repetition. It also makes it easier to add more characters if required.

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Word Test</title>
  <style>
    .center {
      width: 100vw;
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    .word {
      font-size 0;
      /* so there are no gaps between the spans */
    }
    
    .word>* {
      display: inline-block;
      font-family: 'Helvetica';
      font-weight: 900;
      font-size: 10vw;
    }
    
    .word:hover>* {
      animation: move 1s cubic-bezier(.32, .71, .28, .91) calc((4 - var(--n)) / 4 * 1s) 1 forwards;
    }
    
    .word>*:nth-child(1) {
      --n: 1;
    }
    
    .word>*:nth-child(2) {
      --n: 2;
    }
    
    .word>*:nth-child(3) {
      --n: 3;
    }
    
    .word>*:nth-child(4) {
      --n: 4;
    }
    
    @keyframes move {
      from {
        opacity: 0;
        transform: translateX(0);
      }
      to {
        opacity: 1;
        transform: translateX(100px);
      }
    }
  </style>
</head>

<body>
  <div class="center">
    <div class="word">
      <span>M</span>
      <span>o</span>
      <span>v</span>
      <span>e</span>
    </div>
  </div>
</body>

</html>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 A Haworth