Advertisement

Animated Futuristic State Button

| by Vladimir | 2 min read | code by dexter-st
A11y Ready Intermediate

Tech & Dependencies

HTML CSS

Features

  • Staggered Animation
  • Focus State Interaction
  • Text Swapping
  • Advanced Box Shadows

Browser Support

Chrome 80+ Edge 80+ Firefox 75+ Safari 13+

Core

This Animated Futuristic State Button is more than just a clickable element; it’s a self-contained micro-interaction. Designed for actions like “Generate” or “Processing,” it features a idle flicker animation that transitions into an intense, glowing state upon focus. The text cleverly swaps from a call-to-action to a continuous verb (“Generate” → “Generating”) using purely CSS animations, providing immediate visual feedback without JavaScript.

Core Technique

The complexity lies in managing multiple animation timelines triggered by the :focus pseudo-class.

  1. Text Swapping: Two containers (.txt-1 and .txt-2) hold the text. By default, .txt-2 is hidden. On focus, contrasting animations (opacity-anim) fade the first text out and the second text in.
  2. Staggered Letters: Each letter is wrapped in a span with a .btn-letter class. A huge block of CSS :nth-child selectors assigns a specific animation-delay to each letter (0s, 0.08s, 0.16s…). This creates the wave-like motion of the text.
  3. Glow & Depth: The button uses detailed box-shadow layers (both inset and drop shadows) to create a tactile, recessed look. On hover and focus, linear-gradient masks and brightness filters on pseudo-elements (::before, ::after) simulate a light source intensifying.

Customization

The button relies on CSS variables for its core appearance, making it easy to recolor.

.btn {
  /* Change the highlight color (Hue 0-360) */
  --highlight-color-hue: 210deg; /* Blue */
  /* --highlight-color-hue: 120deg; Green */
  
  /* Background color */
  --button-color: #101010;
}

Since the text is hardcoded into span tags for the staggered animation, changing the label requires editing the HTML structure.

<div class="txt-1">
  <!-- Each letter needs a separate span -->
  <span class="btn-letter">S</span>
  <span class="btn-letter">a</span>
  <span class="btn-letter">v</span>
  <span class="btn-letter">e</span>
</div>

Tips

1. Accessibility Nuance: Breaking text into individual <span> letters can sometimes be confusing for screen readers (reading “G-e-n-e-r-a-t-e” instead of the word). Use aria-label on the button container to ensure accessible names are clear.

<button class="btn" aria-label="Generate">
  <!-- spans ... -->
</button>

2. Focus vs. Active: This demo uses :focus to trigger the “Generating” state. In a real app, you might want to toggle a class like .is-loading via JavaScript instead, so the state persists while an actual API call is happening, rather than just when the user clicks/tabs into it.

Advertisement