Blog / CSS

CSS Text Effects: Gradient, Glitch and Reveal

Master modern CSS text effects: animated gradient, cyberpunk glitch effect, scroll reveal, typewriter and animated stroke. Complete code and interactive demos.

Introduction

CSS text effects have become essential for creating modern and engaging interfaces. From simple animated gradients to glitch effects worthy of a cyberpunk film, CSS today offers impressive possibilities without JavaScript.

In this tutorial, we will explore 5 text effect techniques that you can directly integrate into your projects. Each effect is accompanied by an interactive demo and the complete code ready to copy.

💡
Good to know

All these effects are made in pure CSS and are compatible with modern browsers (Chrome, Firefox, Safari, Edge). Some use -webkit-background-clip which requires the prefix for Safari.

1. Animated gradient text

Text with an animated gradient is one of the most popular effects. It immediately attracts attention and gives a modern and dynamic appearance to your headings.

Effect.Labs
text-gradient.css
.text-gradient {
  font-size: 3.5rem;
  font-weight: 900;

  /* Gradient with repetition for animation */
  background: linear-gradient(
    90deg,
    #6366f1,
    #8b5cf6,
    #d946ef,
    #f472b6,
    #6366f1
  );
  background-size: 200% auto;

  /* Apply gradient to text */
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;

  /* Animation fluide */
  animation: gradientFlow 3s ease infinite;
}

@keyframes gradientFlow {
  0% {
    background-position: 0% center;
  }
  100% {
    background-position: 200% center;
  }
}

How it works

The trick relies on three key properties:

  • background-clip: text: Limits the background display to the shape of the text
  • -webkit-text-fill-color: transparent: Makes the text transparent to see the gradient
  • background-size: 200%: Allows moving the gradient in the animation

2. Glitch / distortion effect

The glitch effect gives a very trendy cyberpunk style. It uses pseudo-elements to create offset copies of the text with different colors.

GLITCH
text-glitch.css
.text-glitch {
  font-size: 3.5rem;
  font-weight: 900;
  position: relative;
  color: #fff;
  letter-spacing: 2px;
}

/* Upper layer - Red/Pink */
.text-glitch::before,
.text-glitch::after {
  content: attr(data-text);
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.text-glitch::before {
  color: #ff0080;
  animation: glitchTop 1s infinite linear alternate-reverse;
  /* Masks the upper third */
  clip-path: polygon(0 0, 100% 0, 100% 33%, 0 33%);
}

/* Lower layer - Cyan/Green */
.text-glitch::after {
  color: #00ff88;
  animation: glitchBottom 1.5s infinite linear alternate-reverse;
  /* Masks the lower third */
  clip-path: polygon(0 67%, 100% 67%, 100% 100%, 0 100%);
}

@keyframes glitchTop {
  0% { transform: translate(0); }
  20% { transform: translate(-3px, 3px); }
  40% { transform: translate(-3px, -3px); }
  60% { transform: translate(3px, 3px); }
  80% { transform: translate(3px, -3px); }
  100% { transform: translate(0); }
}

@keyframes glitchBottom {
  0% { transform: translate(0); }
  20% { transform: translate(3px, -3px); }
  40% { transform: translate(3px, 3px); }
  60% { transform: translate(-3px, -3px); }
  80% { transform: translate(-3px, 3px); }
  100% { transform: translate(0); }
}

/* Intensify on hover */
.text-glitch:hover::before,
.text-glitch:hover::after {
  animation-duration: 0.2s;
}

The data-text attribute

Don't forget to add the data-text attribute on your HTML element:

index.html
<h1 class="text-glitch" data-text="GLITCH">GLITCH</h1>

3. Text with scroll reveal

The progressive text reveal effect is very elegant for landing pages. The text appears line by line with a fluid upward movement.

Welcome to
Effect.Labs
The CSS effects library
text-reveal.css
.text-reveal-wrapper {
  overflow: hidden;
  display: inline-block;
}

.text-reveal-line {
  display: block;
  overflow: hidden;
}

.text-reveal-line span {
  display: inline-block;
  transform: translateY(100%);
  opacity: 0;
  animation: revealLine 0.8s ease forwards;
}

/* Progressive delays for each line */
.text-reveal-line:nth-child(1) span { animation-delay: 0s; }
.text-reveal-line:nth-child(2) span { animation-delay: 0.2s; }
.text-reveal-line:nth-child(3) span { animation-delay: 0.4s; }
.text-reveal-line:nth-child(4) span { animation-delay: 0.6s; }

@keyframes revealLine {
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

Triggering on scroll with JavaScript

To trigger the animation when the element becomes visible, use the Intersection Observer:

scroll-reveal.js
const observer = new IntersectionObserver(
  (entries) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        entry.target.classList.add('visible');
      }
    });
  },
  { threshold: 0.1 }
);

// Observe all elements with the .scroll-reveal class
document.querySelectorAll('.scroll-reveal')
  .forEach(el => observer.observe(el));

4. Typing / typewriter effect

The typewriter effect is perfect for terminals, code presentations or messages that need to gradually capture attention.

text-typing.css
/* Version CSS pure (texte fixe) */
.text-typing {
  font-family: monospace;
  font-size: 1.5rem;
  white-space: nowrap;
  overflow: hidden;
  border-right: 3px solid #6366f1;
  width: 0;
  animation:
    typing 3s steps(30) forwards,
    blink 0.75s step-end infinite;
}

@keyframes typing {
  to { width: 30ch; } /* 30 caracteres */
}

@keyframes blink {
  50% { border-color: transparent; }
}

Advanced JavaScript version

For total control (dynamic text, delays, deletion), use JavaScript:

typing-effect.js
class TypeWriter {
  constructor(element, texts, options = {}) {
    this.element = element;
    this.texts = texts;
    this.typeSpeed = options.typeSpeed || 100;
    this.deleteSpeed = options.deleteSpeed || 50;
    this.pauseTime = options.pauseTime || 2000;
    this.loop = options.loop !== false;
    this.textIndex = 0;
    this.charIndex = 0;
    this.isDeleting = false;
    this.type();
  }

  type() {
    const currentText = this.texts[this.textIndex];

    if (this.isDeleting) {
      this.element.textContent = currentText.substring(0, this.charIndex - 1);
      this.charIndex--;
    } else {
      this.element.textContent = currentText.substring(0, this.charIndex + 1);
      this.charIndex++;
    }

    let timeout = this.isDeleting ? this.deleteSpeed : this.typeSpeed;

    if (!this.isDeleting && this.charIndex === currentText.length) {
      timeout = this.pauseTime;
      this.isDeleting = true;
    } else if (this.isDeleting && this.charIndex === 0) {
      this.isDeleting = false;
      this.textIndex = (this.textIndex + 1) % this.texts.length;
    }

    setTimeout(() => this.type(), timeout);
  }
}

// Utilisation
new TypeWriter(
  document.getElementById('typing'),
  ['Web Developer', 'Designer UI/UX', 'Effects Creator']
);

5. Text with animated stroke/outline

The text effect with animated stroke/outline is very impactful for hero headings. The text fills progressively on hover or on load.

STROKE
text-stroke.css
.text-stroke {
  font-size: 4rem;
  font-weight: 900;
  color: transparent;
  -webkit-text-stroke: 2px #6366f1;
  position: relative;
  transition: all 0.5s ease;
}

/* Fill layer */
.text-stroke::before {
  content: attr(data-text);
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 100%;
  color: #6366f1;
  -webkit-text-stroke: 0;
  overflow: hidden;
  white-space: nowrap;
  transition: width 0.5s ease;
}

/* Fill on hover */
.text-stroke:hover::before {
  width: 100%;
}

Variant with animated gradient

For an even more spectacular effect, combine stroke and animated gradient:

PREMIUM
text-stroke-gradient.css
.text-stroke-gradient {
  font-size: 4rem;
  font-weight: 900;
  color: transparent;

  /* Gradient applied to stroke */
  background: linear-gradient(
    90deg,
    #6366f1,
    #8b5cf6,
    #d946ef,
    #6366f1
  );
  background-size: 200% auto;
  -webkit-background-clip: text;
  background-clip: text;

  /* The stroke takes the text color via currentColor
     or use SVG for a true stroke gradient */
  -webkit-text-stroke: 2px transparent;

  animation: strokeGradient 3s linear infinite;
}

@keyframes strokeGradient {
  to {
    background-position: 200% center;
  }
}

Best practices

Before implementing these effects in your projects, keep these recommendations in mind:

Performance

  • Limit simultaneous animations: Avoid having more than 2-3 animated texts visible at the same time
  • Prefer transform and opacity: These properties are GPU-optimized
  • Use will-change sparingly: Only for complex animations that stutter

Accessibility

Respect user preferences for reduced motion:

accessibility.css
@media (prefers-reduced-motion: reduce) {
  .text-gradient,
  .text-glitch::before,
  .text-glitch::after,
  .text-typing,
  .text-stroke-animated {
    animation: none;
  }

  .text-typing {
    width: auto;
    border-right: none;
  }

  .text-reveal-line span {
    transform: none;
    opacity: 1;
  }
}
⚠️
Contrast warning

Text effects can reduce readability. Make sure the text remains readable even without animations, especially for users with visual impairments.

Browser compatibility

  • -webkit-background-clip: text: Requires the prefix for Safari
  • -webkit-text-stroke: Excellent support except IE (not supported)
  • clip-path: Modern support, not IE

Conclusion

CSS text effects offer impressive creative possibilities to energize your interfaces. From animated gradient to cyberpunk glitch, including scroll reveals, you now have 5 complete techniques to captivate your users.

Don't forget: subtlety is often more effective than excess. Use these effects strategically to highlight the important elements of your page.

🎨
Go further

Find over 50 text effects ready to use in our effects library, with one-click copyable code and real-time customization.