By Tim King · Updated
Multi Step Form Builder
Per-Step Validation, Back and Next Buttons, Step Indicators and Copyable Code
OneTask is free, with no sign-up, and built by one person.
If this tool saved you time, a coffee helps keep new ones coming.
How the Multi-Step Form Builder works
This multi step form builder splits a form into a wizard. Long forms finish more often when they are split into short steps. Describe each step as a title and a list of fields, pick a step indicator, and copy a wizard with Back and Next buttons, per-step validation and a tiny script — click Next in the preview to walk through it.
Multi step form: splitting a long form
Each step is a <fieldset class="msf-step"> inside one <form>, so all the data submits
together at the end. Only one fieldset is visible at a time; the others carry the hidden
attribute. The step indicator is an ordered list at the top and the navigation is two plain
buttons at the bottom. Nothing here depends on a framework.
Defining steps. Type one step per line as Title: field, field. Field names become labels,
ids and names; anything containing "email" gets type="email" and anything containing
"password" gets type="password". Edit the generated markup to add selects, checkboxes or
textareas — the script does not care what kind of controls a step holds.
Step indicator. Numbered circles show the step number, turn into a tick when complete and
take the accent colour for the current and completed steps. Progress segments are a row of
bars that fill from left to right. Both are built from CSS counters and ::before, so adding a
step to the markup updates the indicator automatically.
Per-step validation. Before advancing, the script calls reportValidity() on each input in
the current step. If a required field is empty or an email is malformed, the browser shows its
own message on that field and the step stays put. On the last step the Next button reads Submit
and calls form.submit(), which triggers full-form validation once more.
Hidden, not display none in CSS. Using the hidden attribute means the inactive steps are
removed from both the visual layout and the accessibility tree, and the script only has to flip
one boolean. If your stylesheet resets [hidden], add .msf-step[hidden] { display: none }.
Why one form, not three pages. Keeping every step in one form means no session storage, no server-side state between pages and a single submit. The trade-off is that the whole form loads at once — fine for a handful of fields, less so for a fifty-question survey.
Keyboard and screen readers. Focus moves naturally because the buttons are real buttons and
the hidden steps are not focusable. For a more polished experience, move focus to the new step's
heading when it appears by giving the <h2> tabindex="-1" and calling focus() after show().
FAQ
How do I add a different input type to a step?
Edit the generated HTML. Any control inside a .msf-step fieldset is validated by the script, so
you can drop in a <select>, <textarea> or a group of radio buttons. Change the selector in the
script from input to input, select, textarea if you use the latter two.
Why does the form use fieldset for each step?
A fieldset groups related controls semantically and can be hidden as a unit. It also gives screen reader users a natural boundary between steps. The default fieldset border is removed in the CSS, so it looks like a plain block.
Can I save progress if the user leaves?
Yes, but it is extra code. On each Next click, serialise the form with FormData and store it
in localStorage; on load, restore the values and jump to the last completed step. Clear the
stored data after a successful submit.
How does per-step validation work without a library?
The script calls reportValidity() on every input in the current step. That runs the browser's
built-in checks — required, type="email", pattern, minlength — and displays the native
error bubble on the first failing field. It returns false, so the step does not advance.
Should the Back button re-validate?
No. Going back should always be allowed, even with an invalid field, because the user may need to change an earlier answer before they can complete the current one. The script only validates on Next.
See also: all Forms & Inputs tools, Layout & Spacing, Shadows & Motion, Shapes & SVG, UI Components, Colour.
Related tools
Custom Radio Button Builder
Accessible custom radio buttons as dots, cards or pill segments.
Floating Label Form
Material-style floating labels in pure CSS with outlined, filled and underline variants.
Form Progress Bar
Step indicators and progress bars for multi-step forms and checkouts.
Dual Range Slider
Two-thumb min/max slider for price filters, no library needed.
Input Mask Generator
Auto-formatting inputs for phone, date, card and custom patterns.