Filipe Serrazina
Filipe Serrazina

Reputation: 11

Animation CSS with dynamic text

I need to add an animation to this links on hover, I have to deal with the "width" of the link word can change. Is there any way to change dynamically the value of the translate animation?

.link {
  text-decoration: none;
  padding-left: 15px;
  position: relative;
  transition: 1s;
  &:hover {
    padding-left: 0;
    .link--decoration {
      animation: in 1s ease both;
    }
  }
}

.link--decoration {
  animation: out 1s ease both;
  left: 0;
  position: absolute;
}

@keyframes in {
  to {
    transform: translate(calc(100% + 75px), 0);
  }
}

@keyframes out {
  from {
    transform: translate(calc(100% + 75px), 0);
  }
  to {
    transform: translate(0, 0);
  }
}
<p><a href="#" class="link"><span class="link--decoration">&dash;</span><span class="link--text">Read Article</span></a></p>

<p><a href="#" class="link"><span class="link--decoration">&dash;</span><span class="link--text">Open Hours</span></a></p>

<p><a href="#" class="link"><span class="link--decoration">&dash;</span><span class="link--text">Open Localization</span></a></p>

https://codepen.io/serrazina/pen/zzEaLE

Upvotes: 1

Views: 729

Answers (1)

Brett DeWoody
Brett DeWoody

Reputation: 62901

There are 2 approaches I see to solving this. The first uses left to animate the decoration. Like this:

.link {
  text-decoration: none;
  padding-left: 15px;
  position: relative;
  transition: 1s;
}

.link:hover {
  padding-left: 0;
}

.link:hover .link--decoration {
  animation: in 1s ease both;
}

.link--decoration {
  animation: out 1s ease both;
  left: 0;
  position: absolute;
}

@keyframes in {
  to {
    left: calc(100% + 5px);
  }
}

@keyframes out {
  from {
    left: calc(100% + 5px);
  }
  to {
    left: 0;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p><a href="#" class="link"><span class="link--decoration">&dash;</span><span class="link--text">Read Article</span></a></p>

<p><a href="#" class="link"><span class="link--decoration">&dash;</span><span class="link--text">Open Hours</span></a></p>

<p><a href="#" class="link"><span class="link--decoration">&dash;</span><span class="link--text">Open Localization</span></a></p>

The second method uses transform to take advantage of hardware acceleration. The difference between this method and yours was adding a width: 100% to the decoration as the translate is based on the width of the element. In your example that meant transform: translateX(100%) was 100% the width of the decoration element, which was about 20px in width. In the demo below I've made the element 100% the width of it's parent element, so transform: translateX(100%) moves it to the right of the parent element.

.link {
  text-decoration: none;
  padding-left: 15px;
  position: relative;
  transition: 1s;
}

.link:hover {
  padding-left: 0;
}

.link:hover .link--decoration {
  animation: in 1s ease both;
}

.link--decoration {
  animation: out 1s ease both;
  left: 0;
  width: 100%;
  position: absolute;
}

@keyframes in {
  to {
    transform: translateX(calc(100% + 5px));
  }
}

@keyframes out {
  from {
    transform: translateX(calc(100% + 5px));
  }
  to {
    transform: translateX(0);
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p><a href="#" class="link"><span class="link--decoration">&dash;</span><span class="link--text">Read Article</span></a></p>

<p><a href="#" class="link"><span class="link--decoration">&dash;</span><span class="link--text">Open Hours</span></a></p>

<p><a href="#" class="link"><span class="link--decoration">&dash;</span><span class="link--text">Open Localization</span></a></p>

Upvotes: 1

Related Questions