How do you animate form fields without harming accessibility?

Animated forms guide people while they type: labels that float above the field, underlines that grow on focus, inputs that shake on an error and buttons that show sending and success states. They rely on CSS transitions and selectors such as :focus-visible, :placeholder-shown and :user-invalid, with JavaScript only for richer states.

How to choose, performance and accessibility
  • Floating Label saves space on sign-up and contact forms, Password Strength and Shake Validation give instant feedback, and Submit Button States reassure during slow requests.
  • Always keep a real label element, announce errors in text rather than by motion or colour alone, and make sure no animation hides what the user typed.
  • Floating Label and Underline Focus are free with their full code; the other form effects come with Premium.

Floating Label

The label floats upward when the input is focused or filled.

CSS Focus Transform
View source code
HTML
<div class="demo-preview">
  <div class="floating-label-group">
    <input type="text" id="floating-input" placeholder=" " />
    <label for="floating-input">Your email</label>
  </div>
</div>
CSS
.demo-preview,
.demo-preview *,
.demo-preview *::before,
.demo-preview *::after {
  box-sizing: border-box
}

.demo-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 250px;
  overflow: hidden;
  position: relative;
  background: rgb(26, 26, 36);
  color: rgb(255, 255, 255);
  font-family: sans-serif;
}

/* Variables du design system du site, dont ce code dépend (valeurs de css/style.css — à adapter librement). */
.demo-preview {
  --bg-elevated: #1a1a24;
  --text-muted: #8b8b93;
}

.floating-label-group {
  position: relative;
  width: 280px;
}

.floating-label-group input {
  width: 100%;
  padding: 16px 12px 8px;
  font-size: 1rem;
  font-family: inherit;
  background: rgba(255, 255, 255, 0.05);
  border: 2px solid rgba(255, 255, 255, 0.1);
  border-radius: 8px;
  color: white;
  outline: none;
  transition: all 0.3s ease;
}

.floating-label-group label {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-muted);
  pointer-events: none;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  background: transparent;
  padding: 0 4px;
}

.floating-label-group input:focus,
.floating-label-group input:not(:placeholder-shown) {
  border-color: #6366f1;
  background: rgba(99, 102, 241, 0.05);
}

.floating-label-group input:focus+label,
.floating-label-group input:not(:placeholder-shown)+label {
  top: 0;
  font-size: 0.75rem;
  color: #6366f1;
  background: var(--bg-elevated);
}
JavaScript
/* Pure CSS — no JavaScript required */

Underline Focus

Animated line that extends from the center on focus.

CSS Focus Gradient
View source code
HTML
<div class="demo-preview">
  <div class="underline-input-group">
    <input type="text" id="underline-input" placeholder=" " />
    <label for="underline-input">Full name</label>
    <span class="underline"></span>
  </div>
</div>
CSS
.demo-preview,
.demo-preview *,
.demo-preview *::before,
.demo-preview *::after {
  box-sizing: border-box
}

.demo-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 250px;
  overflow: hidden;
  position: relative;
  background: rgb(26, 26, 36);
  color: rgb(255, 255, 255);
  font-family: sans-serif;
}

/* Variables du design system du site, dont ce code dépend (valeurs de css/style.css — à adapter librement). */
.demo-preview {
  --text-muted: #8b8b93;
}

.underline-input-group {
  position: relative;
  width: 280px;
}

.underline-input-group input {
  width: 100%;
  padding: 12px 0;
  font-size: 1rem;
  font-family: inherit;
  background: transparent;
  border: none;
  border-bottom: 2px solid rgba(255, 255, 255, 0.2);
  color: white;
  outline: none;
}

.underline-input-group .underline {
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 0;
  height: 2px;
  background: linear-gradient(90deg, #6366f1, #d946ef);
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

.underline-input-group input:focus~.underline {
  left: 0;
  width: 100%;
}

.underline-input-group label {
  position: absolute;
  left: 0;
  top: 12px;
  color: var(--text-muted);
  pointer-events: none;
  transition: all 0.3s ease;
}

.underline-input-group input:focus+label,
.underline-input-group input:not(:placeholder-shown)+label {
  top: -16px;
  font-size: 0.75rem;
  color: #6366f1;
}
JavaScript
/* Pure CSS — no JavaScript required */

Border Animation

Border that draws itself progressively around the input.

CSS Focus Border

Shake Validation

The input shakes to indicate a validation error.

JS Animation Validation

Success Checkmark

Animated checkmark that appears when the input is valid.

JS SVG Validation

Password Strength

Animated password strength indicator.

JS Animation Security

Search Expand

Search field that expands on click.

CSS Focus Transform

Input with Icon

Icon that animates on input focus.

CSS Focus Icon

Textarea Auto-grow

Text area that auto-grows.

JS Resize Interactive

Submit Button States

Button with animated loading, success and error states.

JS Animation States

Floating Label V2

Label that elegantly floats above the input with colored background.

CSS Focus Transform

Underline Animation

Line that extends from the center on focus.

CSS Focus Pseudo-element

Glow Input

Input with glow effect on focus.

CSS Box-shadow Focus

Checkbox Animated

Checkbox with animated checkmark that appears progressively.

CSS Transform Checkbox

Toggle iOS Style

Toggle switch with elastic iOS-style animation.

CSS Cubic-bezier Toggle

Radio Ripple

Radio buttons with ripple effect on selection.

CSS Animation Radio

Password Strength V2

Compact strength indicator with colored bar.

JS Animation Security

Select Animated

Dropdown with animated arrow on focus.

CSS Transform Select

Character Counter

Textarea with built-in character counter.

JS Counter Textarea

Search Expand V2

Compact search field that expands on focus.

CSS Focus Width

Pricing Toggle Odometer

Monthly/annual toggle where the price scrolls digit by digit (odometer effect) with an animated savings badge. Perfect for pushing annual subscriptions.

💡 Perfect for: pricing page, SaaS, plan comparison, annual upsell, Black Friday.

Vanilla JS Odometer Pricing Premium

Frequently Asked Questions

How to create a floating label in CSS? +

Place the label after the input in the HTML. Use the :placeholder-shown selector to detect if the input is empty, and the :focus selector for the active state. Animate the label position and size with transform and transition.

How to style form validation in CSS? +

Use the :valid and :invalid pseudo-classes to change input styles based on their state. Add a green or red border with a smooth transition. Combine with :not(:placeholder-shown) to only validate filled fields.

Are animated forms accessible? +

Yes, as long as you keep labels associated with inputs (for/id attribute), maintain sufficient contrast, and do not hide error messages behind animations. Always test with a screen reader.

How to animate input focus? +

Use the :focus-within selector on the container and :focus on the input. Animate the border, add a colored box-shadow, or reveal an animated line with a ::after pseudo-element and a width transition.

What is the best framework for animated forms? +

For simple forms, pure CSS is enough with the :focus, :valid, :invalid selectors. For complex forms, combine with vanilla JavaScript for real-time validation. No framework needed — Effect.Labs provides ready-to-use CSS code.