4

How can i rubber band each letter on hover? Currently i have it working for color on each letter but cant seem to get the rubber band effect going. What i'm doing wrong?

https://codepen.io/MariusZMM/pen/aPLJGo

.a {
  animation-duration: 1s;
  animation-fill-mode: both;
  animation-iteration-count: 1;
}

.a:hover {
  color: orange;
  /* animation: rubberBand 5s infinite; */
  animation-name: rubberBand;
}

@keyframes rubberBand {
  from {
    transform: scale3d(1, 1, 1);
  }

  30% {
    transform: scale3d(1.25, 0.75, 1);
  }

  40% {
    transform: scale3d(0.75, 1.25, 1);
  }

  50% {
    transform: scale3d(1.15, 0.85, 1);
  }

  65% {
    transform: scale3d(.95, 1.05, 1);
  }

  75% {
    transform: scale3d(1.05, .95, 1);
  }

  to {
    transform: scale3d(1, 1, 1);
  }
}
Marius
  • 1,664
  • 2
  • 16
  • 28
  • Can you explain what a "rubber band effect" is? Maybe provide a video or working codepen? Also, do you only want CSS or will JS and/or JQuery work? –  Dec 28 '18 at 16:55
  • 1
    https://codepen.io/yeskunall/pen/xVQrLw?js-preprocessor=babel i have JS in codepen so its selecting each text and putting them in span. When i don't use JS and only select H1 then the effect works but only for full text and not each letter – Marius Dec 28 '18 at 16:58

2 Answers2

2

Set position: absolute; and use manual spacing like so:

.a {
  animation-duration: 1s;
  animation-fill-mode: both;
  animation-iteration-count: 1;
  position: absolute;
}

.a:hover {
  color: orange;
  /* animation: rubberBand 5s infinite; */
  animation-name: rubberBand;
}

@keyframes rubberBand {
  from {
    transform: scale3d(1, 1, 1);
  }

  30% {
    transform: scale3d(1.25, 0.75, 1);
  }

  40% {
    transform: scale3d(0.75, 1.25, 1);
  }

  50% {
    transform: scale3d(1.15, 0.85, 1);
  }

  65% {
    transform: scale3d(.95, 1.05, 1);
  }

  75% {
    transform: scale3d(1.05, .95, 1);
  }

  to {
    transform: scale3d(1, 1, 1);
  }
} 
  <div class="title">
    <h1><div class="a" style="left: 4vw;">T</div>
    <h1><div class="a" style="left: 8vw;">E</div>
    <h1><div class="a" style="left: 12vw;">S</div>
    <h1><div class="a" style="left: 16vw;">T</div>
  </div>
  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

The manual spacing will be a little imprecise. It will work far better oriented vertically. but above is a rough snippet of what the effect would look like.

If you have a longer text, you can probably write a JQuery script to space out the text. You can find the width of a character as demonstrated in this SO post. I hope this helps you.

  • This is good but now i'm thinking what if i have a large text then this manual spacing business will take ages – Marius Dec 28 '18 at 17:18
  • 1
    @Marius Added clarification, thanks for bringing that up. –  Dec 28 '18 at 17:24
  • this is what i came up: https://codepen.io/MariusZMM/pen/oJGWMp but i feel that the space between is still too large. Looking at this webpage example he got it right https://jacekjeznach.com/ – Marius Dec 28 '18 at 17:58
  • @Marius switching to `px` and messing with the values worked for me at ~25px. To get the exact width of a character, take a look at the post I linked. –  Dec 28 '18 at 18:27
1

Modified version of another answer, using inline-block (which is not as compatible with some browsers, but allows less markup):

.a {
  animation-duration: 1s;
  animation-fill-mode: both;
  animation-iteration-count: 1;
  display: inline-block;
}

.a:hover {
  color: orange;
  /* animation: rubberBand 5s infinite; */
  animation-name: rubberBand;
}

@keyframes rubberBand {
  from {
    transform: scale3d(1, 1, 1);
  }

  30% {
    transform: scale3d(1.25, 0.75, 1);
  }

  40% {
    transform: scale3d(0.75, 1.25, 1);
  }

  50% {
    transform: scale3d(1.15, 0.85, 1);
  }

  65% {
    transform: scale3d(.95, 1.05, 1);
  }

  75% {
    transform: scale3d(1.05, .95, 1);
  }

  to {
    transform: scale3d(1, 1, 1);
  }
} 
  <div class="title">
    <h1>
    <span class="a" >T</span>
    <span class="a" >E</span>
    <span class="a" >S</span>
    <span class="a" >T</span>
  </h1>
  </div>
  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
anothermh
  • 9,815
  • 3
  • 33
  • 52
Garrett Motzner
  • 3,021
  • 1
  • 13
  • 30