3 Topics
Chapter•55 Minutes

Animations and Advanced Selectors

Use animation utilities, custom keyframes, pseudo-elements, child selectors, and media variants with restraint.

Animation utilities and keyframes

Animation utilities can apply predefined motion patterns, while custom animations are useful when the motion is specific to the product. Animation should have a clear purpose: loading feedback, attention to a new status, or a transition that helps users understand a state change.

For custom keyframes, define a named animation in the appropriate theme or CSS layer for your Tailwind version, then use the resulting utility. Keep duration and iteration sensible, and respect reduced-motion preferences. Do not animate large areas continuously without a user benefit.

Custom pulse indicator (CSS plus markup)
@keyframes task-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.55; transform: scale(0.92); }
}

.task-pulse {
  animation: task-pulse 1.4s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .task-pulse { animation: none; }
}
đź’ˇ This custom CSS illustrates a named animation and a reduced-motion fallback. In a Tailwind project, you can integrate the animation with the version's supported theme or utility mechanisms. Ensure the indicator also has a textual status so animation is not the only signal.
Knowledge Check

What should a production UI do for users who prefer reduced motion?

Pseudo-elements and decorative content

Pseudo-element variants such as before: and after: can create decorative shapes, indicators, and overlays without extra markup. They are useful for nonessential decoration, not for content that users must understand or interact with. A pseudo-element usually needs a content value, which Tailwind's supported syntax can provide.

Do not use generated content as a replacement for meaningful DOM text, form labels, or accessible names. Keep decorative elements hidden from assistive technology when appropriate.

Decorative status marker
<span class="inline-flex items-center gap-2 text-sm font-medium text-emerald-800">
  <span class="relative flex size-2" aria-hidden="true">
    <span class="absolute inline-flex size-full animate-ping rounded-full bg-emerald-400 opacity-60 motion-reduce:animate-none"></span>
    <span class="relative inline-flex size-2 rounded-full bg-emerald-600"></span>
  </span>
  Live status
</span>
💡 The marker is decorative and hidden from assistive technology. The text “Live status” communicates the state independently. The ping animation is disabled for reduced-motion users; for critical status, consider avoiding continuous animation altogether.
Key Takeaways
  • Use pseudo-elements for decoration, not essential content.
  • Respect reduced-motion preferences.
  • Always communicate important state through text or semantics as well as animation.

Advanced selectors and media variants

Tailwind variants can target relationships and environment conditions, such as child states, ARIA attributes, print styles, contrast preferences, or pointer capabilities where supported. These variants are powerful, but complex selector logic can become difficult to reason about when packed into one class string.

Use an advanced variant when the relationship is local and clear. If the selector becomes a hidden contract across many elements, extract a component or write a named CSS rule with a comment. Test uncommon states such as forced colors, keyboard navigation, and printing when your product supports them.

Keep selector logic understandable

A class string should still be reviewable. When a selector becomes difficult to explain, use a named component or a small CSS rule instead of adding more variants.