ui-033

Multi-Step Form

£10 or the whole Vault, £99

A multi-step form: each completed step compresses into an answer trail and the submit button springs into a confirmation receipt.

intermediate
7 more details
micro-interactionform-animationstaggerspring-physicsform-validationkeyboard-navigationstate-transition

This element reads better at your own screen size than in the frame below:

Updated

About this component

A polished four-step form card for checkout, onboarding and account setup: details, address, billing and review, each with real labelled fields and native validation. The active step glides forward with a spring settle, while each completed step compresses into a slim answer trail so the journey stays legible without the card growing heavy. On the final submit, the button morphs into a checked confirmation and the receipt values settle in with a stagger.

Read the full effect overview

The component is built on semantic form controls with real labels, native validation and a small keyboard model that keeps Enter useful without stealing textarea line breaks. Steps are read from the DOM, so a fifth step is one more fieldset. It ships in light and dark through one CSS data-variant attribute and uses GSAP core only.

Multi-Step Form - UI component preview

What's included

8 items
  • Four semantic fieldsets, each with two or three labelled, natively validated controls
  • Spring-like panel transitions with a small directional overshoot
  • Completed steps compress into a compact animated answer trail, and unwind on Back
  • Progress markers update with an active and completed state, and the step count derives from the DOM
  • Submit button morphs into a checked success state before the receipt settles
  • Staggered confirmation values and an aria-live status message
  • Back, Next and Submit reset cleanly for replay and demo testing
  • Light and dark themes from one data-variant attribute, no JavaScript branch

Perfect for

4 use cases
  • Checkout and billing flows that need a calm, legible sequence
  • Account and workspace setup with a short review step
  • Lead capture and project intake forms with a reassuring final receipt
  • Multi-step product questionnaires that need a compact review trail

How it works

2 sections

Panel glide and summary rail

The script keeps one fieldset active at a time, validates every control in it with the browser's native constraint API, then uses a GSAP timeline to send the old panel a short x, y and rotation exit while the next panel arrives from the opposite side. The step's answers are joined into the trail before the incoming panel settles with back.out easing.

Confirmation transform

A valid submit first changes the button label and animates its width to the checked state, then the current panel gives way to the confirmation receipt. The receipt values use a staggered y and opacity settle, and every success colour is a custom property in the active theme block.

Difficulty Intermediate
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates

Lighthouse, as measured

Google Lighthouse on this UI element's demo, from the latest scan. A measurement of the demo as shipped, not a promise for your page.

Accessibility
100
Best practices
100

No performance score, on purpose. That figure depends on how you deploy: your server's compression and caching, your CDN, the connection and the device doing the test, none of which the code controls. The same page can score very differently on two consecutive runs, so measure it where it will live.

Paid UI element

Purchase to unlock the code.

Buying Multi-Step Form opens the HTML, CSS and JavaScript source, the full documentation, an AI setup prompt for your editor, and every update we ship to it. Standard license: unlimited personal and commercial projects. Every paid product is tested for desktop and mobile layouts, reduced-motion handling, animation cleanup and keyboard controls wherever there is something to operate.

£10 Standard license, unlimited projects

Browse UI elements

Or the whole library: the Vault, £99, one payment.

Documentation

What's Included

  • index.html: the demo page and copy-ready semantic form markup

  • assets/style.css: component styles with the light and dark token sets

  • assets/script.js: readable GSAP core source with native validation and cleanup

  • assets/script.min.js: minified production script

  • thumbnail.html: build-only capture frame

  • Directional panel transitions use a short x/y/rotation exit and a back.out spring settle

  • Every field in a step is validated with the browser's own constraint API before the panel moves

  • Completed answers join into one line in the trail as each step advances, and unwind on Back

  • The submit button morphs to a checked Confirmed state before the receipt values stagger in

  • role="status", aria-current and aria-invalid keep state changes announced

Quick Start

1. Add to your <head>:

Code snippet omitted: it ships with the download.

2. Add before the closing </body> tag:

Code snippet omitted: it ships with the download.

3. Copy the form with id="springStepForm" from index.html into your page. Keep one [data-panel] fieldset per step with as many real controls in it as the step needs, and one matching [data-summary] item per step if you want the answer trail. Steps are read from the DOM, so adding or removing a [data-panel] fieldset (with its [data-progress] marker and [data-summary] row) is all a fifth or a third step takes; the step count in the header updates itself.

The demo furniture is not part of what you bought: the toolbar strip, the .stage ground and the Fill demo / Restart buttons in index.html are there to show the component off. Delete them and mount the .step-form element on its own.

Hooks the script owns: [data-step-form], [data-panel], [data-progress], [data-summary], [data-form-count], [data-action="next"], [data-action="back"], [data-submit], [data-submit-label], [data-submit-success], [data-success-state], [data-confirm="<field name>"] and the role="status" line.

Themes

Two themes, one design: light (the default) and dark. Set the attribute on the element the component lives in, or on <body>:

Code snippet omitted: it ships with the download.

Nothing else changes: same markup, same script, and no theme name is ever read in JavaScript. The demo's toggle and the ?variant=dark URL parameter only set that attribute and request a resize pass.

Both blocks in assets/style.css declare the same list, so re-valuing one block is the whole of a rebrand:

  • Ground and surfaces: --ground, --ground-2, --raised, --hover, --marker-bg, --field-bg
  • Text: --ink, --ink-2, --ink-3
  • Lines: --line, --line-strong, --field-border, --track
  • Accent (the step in play, the primary button, the focus ring, the trail marker): --accent, --accent-ink, --accent-text, --accent-wash, --accent-press, --focus-ring
  • Status: --success, --success-ink, --success-wash, --danger
  • Shape and type: --radius, --radius-sm, --radius-xs, --shadow, --font

Swap --accent and its four companions for your own brand colour and the component is on your palette; check the text on the accent still clears 4.5:1 and re-value --accent-ink if it does not.

Keyboard & Accessibility

Key What it does
Enter in an input Validates the step and advances; on the final step it submits
Enter in the textarea Inserts a new line
Ctrl+Enter / Cmd+Enter in the textarea Submits the final step
Tab / Shift+Tab Moves through the real labels, fields and buttons
Escape Does not clear or destroy input; the current step remains intact
  • Each step is a semantic <fieldset> with a real <legend>, and every control has a <label> and native validation attributes.
  • The ordered progress list marks the active step with aria-current="step".
  • The first invalid control in a step receives aria-invalid="true" and focus; the browser's reportValidity() message remains available.
  • Focus moves to the first control of the incoming panel once its transition finishes.
  • The form status is a polite role="status" live region, announcing step changes and the final confirmation.
  • prefers-reduced-motion keeps every panel, answer and success state visible while reducing GSAP durations to zero. Back, Next and Submit still work.
  • Escape intentionally has no destructive action: values stay in the fields, and the form has no modal focus trap to close.

How It Works

Panel glide and answer trail. Each Next action checks every control in the current step with the native constraint API, joins their values into the matching trail item, then runs a GSAP timeline. The outgoing fieldset slides a little in the travel direction while the next one arrives from the opposite side and settles with back.out; Back reverses the same geometry and removes the trail item it had written. Only the active fieldset is visually and interactively present when JavaScript is running.

Confirmation transform. A valid submit first swaps the button label and tweens its width into the checked state. The form then replaces the last fieldset with the receipt and staggers its submitted values into place. Resetting the form kills the component's tweens, clears state attributes and returns to step one, so a second run does not inherit a stale transform.

window.demoComplete() runs the whole flow with sample answers and window.resetStepForm() returns it to step one; both exist for the demo toolbar and can go with it.

Customisation

  • The panel area has a fixed height (.has-js .step-panels) so the card does not jump between steps; raise it if your steps carry more fields.
  • Group fields with .field-set, and put two short fields side by side with .field-row.
  • Change the spring character in assets/script.js at the back.out eases and the .68 second incoming-panel duration.
  • Keep .step-panels and .form-main positioned as the animation layers when reskinning. The active panel is position: absolute under .has-js, while no-JS leaves all fieldsets in normal flow.
  • Do not add a CSS transform to [data-panel], [data-summary], [data-confirm] or [data-submit]; GSAP owns their x, y, rotation, opacity and width.
  • Colours, radii, shadows and fonts live in the two theme blocks in assets/style.css.

Requirements

  • GSAP 3.12+ (core only)
  • No build step, no framework

Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.