1

Looking for ideas on how to emulate this pure CSS link underline loading animation...

loading animation gif

... but without the extra markup and wraps with the link text like this pen.

Can animated background-clip be used to "poke holes" through the link underline rather than multiple 6x1 background-image: linear-gradient shapes animated over it?

Thank you!

HTML:

<a href="#">Animated link underline</a>

CSS:

body {background-color: #222;}
a {
  color: white;
  font-size: 20px;
  text-decoration: none;
  position: relative;
  animation: underline 1s infinite;
  background: linear-gradient(currentColor, currentColor) bottom / 0 1px no-repeat;
  -webkit-background-clip: content-box;
}
@keyframes underline {
  from {
    -webkit-background-clip: content-box;
    -webkit-text-fill-color: transparent;
    background-size: 1px 6px;
  }
  to {
    -webkit-background-clip: content-box;
    -webkit-text-fill-color: transparent;
    background-size: 1px 6px;
  }
}

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
D7460N
  • 29
  • 8

1 Answers1

0

I guess you are out of luck to do this using one gradient but here is an idea that rely on mask where you will need at least 3 gradient to create the holes. The good thing is that the gradient is the same so using CSS variables we can see it as one gradient.

body {
  background-color: #222;
}

a {
  color: white;
  font-size: 30px;
  text-decoration: none;
  position: relative;
  display: inline-block;
  overflow: hidden;
}

a:before {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  right: -150%;
  height: 2px;
  background: currentcolor;
  --grad: linear-gradient(to right, white calc(50% - 5px), transparent calc(50% - 5px) calc(50% + 5px), white 0);
  -webkit-mask: var(--grad), var(--grad), var(--grad);
  -webkit-mask-size: 230% 100%, 280% 100%, 350% 100%;
  -webkit-mask-position: 100% 0;
  -webkit-mask-composite: destination-in;
  mask: var(--grad), var(--grad), var(--grad);
  mask-size: 230% 100%, 280% 100%, 350% 100%;
  mask-position: 100% 0;
  mask-composite: intersect;
  animation: move 4s infinite ease-out;
}

@keyframes move {
  100% {
    -webkit-mask-position: 54% 0;
    mask-position: 54% 0;
  }
}
<a href="#">Animated link underline</a>

The mask part isn't difficult. All the trick rely on the gradient and position animation.

here is a better illustration to understand the trick. The green square are the holes in the previous code:

body {
  background-color: #222;
}

a {
  color: white;
  font-size: 30px;
  text-decoration: none;
  position: relative;
  display: inline-block;
  overflow:hidden;
}

a:before {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  right: -150%;
  height: 8px;
  --grad: linear-gradient(to right, transparent calc(50% - 5px), green calc(50% - 5px) calc(50% + 5px), transparent 0);
  background: var(--grad), var(--grad), var(--grad);
  background-size: 230% 100%, 280% 100%, 350% 100%;
  background-position: 100% 0;
  animation: move 4s infinite ease-out;
}

@keyframes move {
  100% {
    background-position: 54% 0;
  }
}
<a href="#">Animated link underline</a>

Related question to understand the calculation: Using percentage values with background-position on a linear-gradient


Another idea using only background:

body {
  background-color: #222;
}

a {
  color: white;
  font-size: 30px;
  text-decoration: none;
  padding-bottom:5px;
  background:
    linear-gradient(to right, 
      currentColor 0 80%,
      transparent  0 calc(80% + 10px),
      currentColor 0 85%,
      transparent  0 calc(85% + 10px),
      currentColor 0 90%,
      transparent  0 calc(90% + 10px),
      currentColor 0) bottom right/1000% 2px no-repeat;
  animation:move 2s linear infinite;
}
.alt {
  -webkit-box-decoration-break: clone;
}

@keyframes move {
  100% {
     background-size:calc(100% + 60px) 2px;
     background-position:bottom 0 right -60px;
  }
}
<a href="#">Animated link underline</a>
<br>
<br>
<a href="#" style="color:red;">Animated multil line<br> underline</a>
<br>
<br>
<a href="#" class="alt" style="color:pink;">Animated multil line<br> underline</a>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Thank you for your in depth reply! The animation should wrap with the text though. Would pseudo elements follow wrapped text? As long as there is no extra HTML markup and it wraps with the text, it doesn't matter how many gradients. In fact, wouldn't we need to use background-gradients to wrap with the text? Created another Codepen to illustrate what I was thinking. Doesn't work. Just what I was thinking. WDYT? [https://codepen.io/dragontheory/pen/XWJydQE](https://codepen.io/dragontheory/pen/XWJydQE) – D7460N Jan 20 '20 at 18:22
  • Also since there is a `currentColor`, is there a `backgroundColor` or `currentBackgroundColor` that can be used for the 3 identical background-gradients in the Codepen above? – D7460N Jan 20 '20 at 18:32
  • @D4A60N yes pseudo element won't wrap and only background will allow the wrap. Will edit my answer and yes I would need more gradient but the idea will remain the same. – Temani Afif Jan 20 '20 at 18:36
  • @D4A60N *is there a backgroundColor or currentBackgroundColor that can be used for the 3 identical background-gradients in the Codepen above?* --> no but we have CSS variables that we can use to avoid duplication – Temani Afif Jan 20 '20 at 18:37
  • Got the animation going, even when the text wraps! The problem is not all three linear-gradient animations show. Should work. What am I doing wrong? https://codepen.io/dragontheory/pen/XWJydQE – D7460N Jan 30 '20 at 06:08
  • Would you mind editting your answer so the background-gradients will wrap with the text instead of the pseudo element? Thank you! – D7460N Dec 11 '20 at 16:37
  • @D7460N I saw your message. I am quite busy this period but will try to update when I can. If not I will refund you before the end of the week. – Temani Afif Jan 12 '21 at 23:26
  • Or just update your answer above. I can take it from there. Thank you. Happy new year! – D7460N Jan 13 '21 at 00:38
  • Thank you for your update. Please see my [codepen](https://codepen.io/dragontheory/pen/XWJydQE). If you refresh and carefully look at the the three "holes", they seem to overlap each other and then just one "hole" repeats. The text describes in depth what I am attempting to do. Any fixes would be appreciated and caffeinated (more coffee)! lol – D7460N Jan 26 '21 at 13:45