AI CSS Animations

Underline to Highlight Text

An underline draws in, then rises into a solid block behind the word while the letters flip to white in step with it, holds, and drains away. One easing on both, so the color edge tracks the block.

Also known as: underline grows into highlight, text highlight animation css, underline fill animation.

Now shipping

HTML

<div class="txt-underline-to-highlight">Now <span class="txt-underline-to-highlight-word">shipping</span></div>

CSS

.txt-underline-to-highlight {
  --c: var(--txt-color, #3b82f6);
  font-size: var(--txt-size, 32px);
  font-family: system-ui, sans-serif;
  font-weight: 700;
  line-height: 1.2;
  position: relative;
  isolation: isolate;
  white-space: nowrap;}
.txt-underline-to-highlight-word {
  position: relative;
  padding: 0 0.12em;
  /* white bottom half, accent top half; sliding it raises the white */
  background: linear-gradient(to top, #fff 50%, var(--c) 50%) 0 0 / 100% 200%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  animation: txt-underline-to-highlight-ink 4s cubic-bezier(0.65, 0, 0.35, 1) infinite;
}
.txt-underline-to-highlight-word::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0.06em 0 -0.06em;
  border-radius: 0.08em;
  background: var(--c);
  transform: scale(0, 0.08);
  transform-origin: 0 100%;
  animation: txt-underline-to-highlight-bar 4s cubic-bezier(0.65, 0, 0.35, 1) infinite;
}
@keyframes txt-underline-to-highlight-bar {
  0%       { transform: scale(0, 0.08); transform-origin: 0 100%; }
  20%      { transform: scale(1, 0.08); transform-origin: 0 100%; }
  36%, 70% { transform: scale(1, 1); transform-origin: 0 100%; }
  84%      { transform: scale(1, 0.08); transform-origin: 0 100%; }
  85%      { transform: scale(1, 0.08); transform-origin: 100% 100%; }
  97%, 100% { transform: scale(0, 0.08); transform-origin: 100% 100%; }
}
@keyframes txt-underline-to-highlight-ink {
  0%, 20%       { background-position: 0 0; }
  36%, 70%      { background-position: 0 100%; }
  84%, 100%     { background-position: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
  .txt-underline-to-highlight, .txt-underline-to-highlight *, .txt-underline-to-highlight::before, .txt-underline-to-highlight::after, .txt-underline-to-highlight *::before, .txt-underline-to-highlight *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Customizing this snippet

  • Color: set --txt-color on the element or a parent. Currently previewing #3b82f6.
  • Font size: set --txt-size. Every other dimension is in em, so the whole thing scales together. Currently previewing 40px.
  • Speed: change the duration on the transition or animation shorthand. Staggered delays are relative, so they keep their rhythm.
  • Reduced motion: the rule at the end of the CSS turns the motion off for people who asked their OS for less of it. Keep it.

Similar text animations