20 CSS Gradient Text Designs 13 / 20

CSS Hover Reveal Gradient Text Effect

Each line of text sits in a muted grey state until hovered, triggering a smooth transition that unveils a distinct gradient per line using -webkit-text-fill-color toggling.

Pure CSS MIT licensed
Live Demo Open in tab
Open in playground

The code

<div class="gt-13">
  <span class="gt-13__label">Hover to reveal gradient</span>
  <span class="gt-13__hint">↓ mouse over each line ↓</span>
  <div class="gt-13__line gt-13__line--a">CREATIVITY</div>
  <div class="gt-13__line gt-13__line--b">EXPLORATION</div>
  <div class="gt-13__line gt-13__line--c">INNOVATION</div>
  <div class="gt-13__line gt-13__line--d">EXPRESSION</div>
  <div class="gt-13__line gt-13__line--e">INSPIRATION</div>
  <div class="gt-13__line gt-13__line--f">MOMENTUM</div>
</div>
.gt-13, .gt-13 *, .gt-13 *::before, .gt-13 *::after {
  margin: 0; padding: 0; box-sizing: border-box;
}
.gt-13 {
  --bg: #0f0f14;
  --plain: #888;
  font-family: 'Plus Jakarta Sans', sans-serif;
  background: var(--bg);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  padding: 3rem 2rem;
  cursor: default;
}
.gt-13__label {
  font-size: .7rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: #333;
  margin-bottom: 1rem;
}
.gt-13__hint {
  font-size: .75rem;
  letter-spacing: .1em;
  color: #444;
  margin-bottom: 1rem;
}
/* Each line transitions from plain → gradient on hover */
.gt-13__line {
  font-size: clamp(2.5rem, 9vw, 6rem);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -.01em;
  position: relative;
  display: inline-block;
  cursor: pointer;
  /* Plain state */
  color: var(--plain);
  transition: color .4s ease;
  /* Gradient hidden under colour */
  background: linear-gradient(90deg, #f093fb, #f5576c, #fda085);
  background-size: 200% 100%;
  -webkit-background-clip: text;
  background-clip: text;
}
.gt-13__line:hover {
  -webkit-text-fill-color: transparent;
  color: transparent;
  background-position: 100% center;
  transition: background-position .6s ease, color .1s;
  animation: gt-13-flow .6s ease forwards;
}
.gt-13__line--b {
  background-image: linear-gradient(90deg, #43e97b, #38f9d7, #4facfe);
}
.gt-13__line--c {
  background-image: linear-gradient(90deg, #fa709a, #fee140, #a18cd1);
}
.gt-13__line--d {
  background-image: linear-gradient(90deg, #30cfd0, #330867, #e0c3fc);
}
.gt-13__line--e {
  background-image: linear-gradient(90deg, #ff9a9e, #fecfef, #ffecd2);
}
.gt-13__line--f {
  background-image: linear-gradient(90deg, #a1c4fd, #c2e9fb, #d4fc79);
}
@keyframes gt-13-flow {
  0%   { background-position: 0% center; }
  100% { background-position: 100% center; }
}
@media (prefers-reduced-motion: reduce) {
  .gt-13__line:hover { animation: none; background-position: 0% center; }
}

How this works

In the default state, -webkit-text-fill-color is set to the muted var(--plain) colour which paints over the background-clipped gradient beneath. On :hover, a CSS rule sets -webkit-text-fill-color: transparent, which unmasks the pre-painted gradient. Because the gradient is always present as the background, the reveal is instant — there is no gradient recalculation on hover, only a property toggle.

The color and -webkit-text-fill-color transition in opposite directions during hover entry and exit, which produces the smooth reveal without animating the gradient itself. Each line has its own gradient image defined via a modifier class (.gt-13__line--b, etc.) so all six gradients are parsed at load time.

Customize

  • Add a transform: skewX(-2deg) on :hover to give the reveal a subtle italic lean that emphasises the motion.
  • Replace the hover trigger with :focus-within to make the effect keyboard-accessible — wrap each line in a button element.
  • Set transition-duration: .2s for a snappier reveal, or 1s ease-in-out for a cinematic slow unveil of each gradient.

Watch out for

  • Setting both color and -webkit-text-fill-color on the same element at the same time causes unexpected results in Firefox — set only -webkit-text-fill-color for the masking trick and keep color as a fallback.
  • Touch devices do not have a persistent hover state — the gradient reveals and immediately resets on touch. Use a :focus rule as a touch-compatible alternative.
  • The background gradient is always painted even in the masked (grey) state — this wastes GPU memory if many gradient-text elements exist off-screen; use content-visibility: auto on sections below the fold.

Browser support

ChromeSafariFirefoxEdge
4+ 3.1+ 49+ 4+

The -webkit-text-fill-color toggling technique works in all modern browsers; the prefixed property is necessary for this specific masking trick on all platforms.

Search CodeFronts

Loading…