174

Accessible Form Components

£29
or the whole Vault, £99

Eight-page form component library with 59 controls and six complete forms: inputs, choices, selects, date and time pickers, uploads, validation and feedback. The controls carry no design of their own: they inherit your font and take colour, corners and size from a few CSS variables, and each one is a block of HTML you copy into your own page.

intermediate
10 more details
form-validationform-animationkeyboard-navigationfocus-managementstate-transitiondialog-animationtheme-switchdragstaggerprogressive-enhancement

Released

About this template

A library of form controls to drop into a site or product you already have. There is no brand, no fictional business and no page design around them: the controls inherit your page's font, and one accent colour, a corner radius and a control height restyle the whole set. Light and dark are the same variables at two values.

Read the full template overview

Every control has its own entry on a reference page showing each state it can be in, the HTML to copy and the options it accepts. The simple ones are native inputs restyled with CSS and need no script. The ones that open, move or measure, such as the date range picker, combobox, wheel pickers, dropzone and signature pad, each add one small script file, so a page only loads what it uses.

Validation is built in. A field names its rules and its own messages, is checked when someone leaves it and again on submit, and a form can list every problem in a summary that links to the fields. Six complete forms show the controls working together: contact, sign-up with an email code, checkout, booking, account settings and a four-step application with a review page.

GSAP is optional. With it, menus, calendars, errors and selections animate; without it, or with reduced motion on, every state still changes at once.

Accessible Form Components - website template preview

What's included

14 items
  • 59 controls on eight pages, each shown in every state with the markup to copy and a list of its options
  • Text inputs: text field, prefix and suffix, textarea with counter, password with strength meter, number stepper, search, masked input, phone with country code, one-time code, inline edit and copy field
  • Choices: checkbox, select all, radio, switch, choice cards, segmented control, chips, star rating, slider, two-thumb range slider and consent
  • Select and search: native select, select menu, combobox with match highlighting, multi-select with pills, tag input, country select, address lookup and colour picker
  • Dates and times: date in three boxes, date picker, two-month date range picker with presets, inline calendar, month picker, time picker, bookable time slots, wheel date and time pickers and duration
  • Files and drawing: styled file input, dropzone with progress and rejections, image upload with preview, reorderable image gallery and a signature pad with a typed alternative
  • Structure and feedback: buttons with loading and done states, fieldsets, form layout, error summary, alerts, toasts, tooltips, conditional fields, repeater rows, multi-step forms, check your answers, success panel and progress
  • Six complete forms assembled only from those controls: contact, sign-up, checkout, booking, account settings and a four-step application
  • Restyled with a few CSS variables: accent, corner radius, control height and the page font, in light and dark
  • One stylesheet, one core script and one small script per interactive control, with no build step and no framework
  • Validation with per-field rules and messages, errors linked to their inputs, and an error summary that focuses each field
  • Every custom control keeps its value in a real input, so ordinary form posts and FormData work unchanged
  • Built and tested to WCAG 2.2 AAA criteria: 7:1 text contrast in light and dark, 44px tap targets, full keyboard operation following the WAI-ARIA patterns, visible focus and reduced-motion support
  • Native fallbacks without JavaScript: inputs, selects, checkboxes and radios still work and multi-step forms show as one long form

Perfect for

5 use cases
  • Adding polished form controls to an existing website
  • SaaS sign-up, settings and onboarding forms
  • Booking and appointment forms
  • Checkout and order forms
  • Internal tools and admin forms

How it works

5 sections

Variables instead of a theme

Every colour, corner and height in the stylesheet reads from a short list of CSS variables, and smaller parts derive theirs from the main ones. Setting an accent colour, a radius and a control height on your page restyles all 59 controls at once, and the font is simply inherited. Set the variables on a wrapper rather than the page to style one form differently from the rest.

Native inputs first

Checkboxes, radios, switches, choice cards, selects and sliders are the browser's own inputs with new styling, so they need no script and behave as people expect. Custom controls such as the date picker or combobox keep their value in a real input as well, which means a normal form post, FormData and the built-in validation all see the answer without extra wiring.

One small script per control

A core script provides validation, the error summary and the shared popover that menus and calendars open in. Each interactive control then has its own file, started by a data attribute on its markup. A page loads only the files for the controls it uses, and controls added to the page later can be started and stopped on request.

Validation that waits its turn

A field lists its rules and, optionally, its own wording for each message. It is checked when someone leaves it, never while they are still typing, and re-checked as they correct it. On submit a form checks every visible field, marks each one, and can list all the problems at the top with links that move focus to the field.

Motion as an extra

With GSAP on the page, popovers open and close, errors reveal, thumbs slide and selections confirm with short transitions. Without it, or when the visitor has asked for reduced motion, the same state changes happen instantly. Nothing depends on an animation finishing, so the controls work the same either way.

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

Lighthouse, as measured

Google Lighthouse on this template's demo (8 pages, lowest score shown), 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.

Questions about this template

Is this a website template or a component library?

A component library. There is no home page, brand or fictional business to replace. The eight pages are a plain reference: each control shown in every state with its markup and options, plus six complete forms. You copy the controls you need into your own site, link one stylesheet and the scripts those controls use, and delete the reference pages.

How do I make the controls match my brand?

Set a few CSS variables. The accent colour drives selection, focus rings and primary buttons, the radius sets every corner from square to fully rounded, and the height sets the size of inputs and buttons. The controls inherit your page's font. Dark mode is the same variables at second values, switched by one attribute on the page or on any wrapper.

Can I use the controls inside WordPress, a server-rendered app or a component framework?

Yes. Each control is ordinary markup started by a data attribute, so it works wherever you can output HTML: a static page, WordPress, Rails, Laravel or a framework's templates. Link the stylesheet, load the core script and one small script for each interactive control you use, then paste the control's HTML. Controls added to the page later can be started and stopped on request.

Do the forms send anything?

No. The six example forms validate and show a confirmation, but nothing leaves the browser: the contact, sign-up, checkout, booking, settings and application forms all stop at a simulated request. Point a form's action at Formspree, Netlify Forms, your own API or your CRM, or listen for the event the form fires when it is valid and send the data yourself.

Are the checkout, address lookup and file uploads real?

They are front ends only. The card fields format and check what is typed but take no payment, the address lookup searches a small sample list until you connect a lookup service, and the dropzone shows simulated progress until you supply an upload function. Each has one documented place to connect the real service.

Is GSAP required?

No. GSAP adds the transitions: menus and calendars opening, errors revealing, the segmented thumb sliding, files arriving in a list. Leave it out and every control still works, changing state at once. The same happens automatically for visitors who have asked their device for reduced motion.

How accessible are the controls?

They use native inputs wherever one exists and follow the WAI-ARIA patterns where one does not. As shipped they are built and tested to the WCAG 2.2 AAA criteria: 7:1 text contrast in light and dark, 44px tap targets, full keyboard operation, visible focus and reduced-motion support. On screens narrower than 375px, calendar days and one-time-code boxes shrink below 44px to fit. Conformance is judged on your finished page, so re-check contrast if you change the accent colour.

The Vault opens this source and the whole library.

Each product gives you the HTML, CSS and JavaScript source, the full documentation and an AI setup prompt, licensed for 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.

One payment, over 350 products, and future additions to the library.

Documentation

Quick Start

Static files, no build step. Serve the folder with any static server and open index.html:

In your downloadThe working code for this step.

To use a control in your own page:

  1. Link the stylesheet and the core script. GSAP is optional.

In your downloadThe working code for this step, in index.html.

  1. Add the script for each interactive control you use. Each control's entry names its file. Checkboxes, radios, switches, cards, native selects and plain inputs need none.

In your downloadThe working code for this step, in index.html.

  1. Paste the control's HTML, then change its label, id and name.

In your downloadThe working code for this step, in index.html.

Using It With Your Own Design

The controls are made to sit inside a design you already have.

  • Font: inherited from your page. Set --fc-font only if the forms should differ.
  • Colour, corners and size: set the variables below on :root, or on a wrapper to restyle only the forms inside it.
  • Dark mode: add data-fc-theme="dark" to <html> or to any wrapper. It is the same variables at second values, which you can also change.
  • What to keep: assets/style.css, assets/script.js and the assets/fc-*.js files for the controls you use.
  • What to delete: the eight reference pages, assets/docs.css, assets/docs.js and assets/fc-forms.css (layout for the example forms page only). The bar at the top of the reference pages only sets the same variables you would set by hand.

In your downloadThe working code for this step, in style.css.

Pages and Configuration

Variables

Variable Sets
--fc-accent, --fc-accent-ink Selection, focus and primary buttons, and the text colour on them
--fc-ground, --fc-field, --fc-soft The page behind the controls, the inside of inputs and menus, quiet fills
--fc-ink, --fc-dim Labels and values; hints, placeholders and icons
--fc-border, --fc-line The edge of a control; dividers
--fc-error, --fc-success, --fc-warning Message colours
--fc-radius Corners. Smaller parts derive theirs from it, so 0 gives square controls throughout
--fc-height, --fc-pad, --fc-gap Control height (44px or more keeps every target at 44 by 44 px, see Accessibility), horizontal padding, spacing inside a field
--fc-font, --fc-text Font family (default inherit) and input text size

Fields and validation

A field is a .fc-field wrapper holding a label, an optional .fc-hint, the control and an empty .fc-error. Add data-fc-field and data-rules to validate it:

  • Rules: required, email, url, number, digits, min:n, max:n (length), minvalue:n, maxvalue:n, pattern:regex, match:#other-field. Separate several with spaces.
  • Messages: data-msg-<rule>="Your wording" on the field. Defaults exist for every rule.
  • Your own rule: FC.rules.postcode = function (value) { return /.../.test(value); }, then data-rules="postcode".
  • A field is checked when focus leaves it and re-checked while an error is showing. It is never checked while someone is still typing their first answer.

Forms

Add data-fc-form to a <form> to check every field on submit. If the form contains a data-fc-summary box, every problem is listed there with a link that focuses its field.

  • fc:form-valid fires on the form when everything passes; event.detail.data is the FormData.
  • fc:form-invalid fires with the list of failed fields.
  • data-fc-form="demo" also stops the page navigating, which is how the example forms run. Remove ="demo" to let the form post normally.

Controls and their scripts

Every interactive control starts from a data-fc-* attribute on its markup and takes its options as further data- attributes, listed under each control on its page.

Family Script files
Text inputs fc-textarea.js, fc-password.js, fc-number.js, fc-search.js, fc-mask.js, fc-phone.js, fc-otp.js, fc-inline-edit.js, fc-copy.js
Choices fc-check-all.js, fc-segmented.js, fc-chips.js, fc-rating.js, fc-range.js, fc-range-dual.js
Select and search fc-select.js, fc-combobox.js, fc-multiselect.js, fc-tags.js, fc-address.js, fc-color.js
Dates and times fc-calendar.js (shared, load first), fc-date.js, fc-date-fields.js, fc-date-range.js, fc-calendar-inline.js, fc-month.js, fc-time.js, fc-slots.js, fc-wheel.js, fc-duration.js
Files and drawing fc-dropzone.js, fc-image-upload.js, fc-signature.js
Structure and feedback fc-button.js, fc-alert.js, fc-toast.js, fc-tip.js, fc-reveal.js, fc-repeater.js, fc-steps.js, fc-review.js, fc-success.js, fc-progress.js

Custom controls keep their value in a real input (often a hidden one marked data-fc-value), so a normal form post and FormData include it. They fire fc:change on their root with the new value in event.detail.

Markup added later

Controls start automatically when the page loads. For markup you insert afterwards, call FC.init(element); before removing it, call FC.destroy(element).

Front end only

Nothing in this package sends data anywhere.

  • Example forms: each validates and then simulates a request. Send the data yourself where the page's script is marked.
  • Checkout: card fields format and check input but take no payment. Use your payment provider's fields for real payments.
  • Address lookup: searches a short sample list. Set FC.addressSource to a function that returns a Promise of addresses to connect a lookup service.
  • Dropzone and image upload: progress is simulated. Set FC.upload to a function that sends one file and returns a Promise to upload for real.
  • Time slots: availability on the reference pages is worked out from the date so the demo is stable. Replace it with a call to your booking system.
  • One-time code: the examples accept 123456. Check the code on your server.

Palette

Defaults, light then dark. All are variables in the first block of assets/style.css.

Role Light Dark
Accent #0a47b0 #8ab4ff
Text on accent #ffffff #0b1220
Ground #ffffff #111317
Field #ffffff #181b21
Soft fill #f1f2f5 #1e2229
Ink #16181d #eef0f4
Dim #4a505b #b3b9c5
Border #848a96 #737a88
Error #9b1c1c #ffa199
Success #0f5a2e #5fd08a

Every default text pair meets WCAG AAA contrast (7:1) in both themes, including text on the tinted fills (alerts, the error summary, a chosen card, a file dragged over a dropzone), and the border meets 3:1 against the ground, the field and the soft fill. The accent presets on the reference pages (green, orange, violet, ink) meet the same in both themes. An accent you choose needs 7:1 against the ground and the soft fill to keep that (4.5:1 for AA), because it is used for selected text and for the focus ring, and the text-on-accent colour needs the same against the accent.

Images

None. The package ships no photographs or icon files. Icons are inline SVG, and image previews come from the files a visitor chooses.

Accessibility

The controls are built and tested to the WCAG 2.2 level AAA criteria, as shipped: the default palette, the default sizes and the markup on the reference pages. That is a statement about these files, not a certificate for your site. Conformance is judged on a finished page, so your own colours, copy and layout decide the result; if you change the accent or lower the control height, re-check contrast and target size (see Palette and Target size below). The checks were automated audits plus scripted keyboard, focus, reflow and reduced-motion tests, not an independent audit.

What that means in practice:

  • Markup: native inputs wherever one exists; custom controls follow the WAI-ARIA patterns for combobox, listbox, calendar grid and slider. Groups of controls (radios, chips, the parts of a date, a phone number, a signature) are named groups.
  • Keyboard: everything works from the keyboard, with no traps. Each control's page lists its keys where they go beyond the browser's own. The signature pad has a typed alternative, and the image gallery reorders with buttons as well as by dragging.
  • Focus: a solid 2px ring in the accent colour, with a 2px gap on filled parts, meets the focus appearance criterion (at least 3:1 against what it replaces) in both themes. On the reference pages focus is never hidden under the sticky bar, and toasts move out of the way of a focused control.
  • Target size: every pointer target is at least 44 by 44 CSS px at the default --fc-height: 44px. Small parts (the clear button in an input, a pill's remove button, a help button) keep their drawn size and get a transparent 44px hit area, with spacing so neighbouring areas never overlap. Below --fc-height: 44px the inputs themselves drop under 44px (they still clear AA's 24px). Two exceptions on narrow screens: a seven-column calendar needs 308px for 44px days, and a six-digit code needs 284px for 44px boxes; in a narrower column they shrink to fit.
  • Labels and errors: labels, hints and errors are linked to their inputs, required fields are marked for assistive technology, and personal-data inputs carry autocomplete tokens. Error messages say what to do, and the error summary receives focus on a failed submit with a link to each field. A message is announced once, not on every key.
  • Status: counts, uploads, copied text and saved states are announced through live regions without moving focus, and a character counter speaks after a pause in typing rather than on every key.
  • Timing: nothing has a time limit. Toasts stay until dismissed; give duration only to a plain confirmation that the page also shows. A button's "done" tick lasts 1.6 seconds, so keep any result people need on the page too.
  • Contrast: text meets 7:1 and control edges, state indicators and focus rings meet 3:1, in both themes and every state (see Palette). State is never shown by colour alone: errors have text, chosen options a tick, booked slots a line through, password strength a word.
  • Motion: with reduced motion requested, or without GSAP, every state changes instantly; only the busy spinners keep turning, slowly.
  • Text: nothing is cut off at 200% text size, at 320px wide or with increased letter, word and line spacing.
  • Without JavaScript, native inputs, selects, checkboxes and radios still work and multi-step forms show as one long form.

Dependencies

  • GSAP 3.15.0 from the jsDelivr CDN, optional. The controls need GSAP 3.12+ when it is present. No plugins are used.
  • No other libraries, no fonts and no build tools.

Teardown

Every control returns a cleanup that removes its listeners, stops its animations and deletes any markup it generated.

In your downloadThe working code for this step, in script.js.

FC.toast.destroy() removes the toast region.

Also in your download: the full source, worked examples, the events and programmatic API, and the class reference.

£29