Complex forms
Start with Forms, buttons & CTAs for labels, inputs, and buttons. This page adds layout and orchestration for long flows: grouped sections, grids of fields, top-level error summaries, step indicators, repeatable line items, segmented toggles, and radio cards.
Wider rail
.sermona-form--wide—max-width~42rem (applications, settings)..sermona-form--full— drop the default cap inside split layouts or modals.
Fieldsets & sections
Use fieldset.sermona-fieldset + legend.sermona-fieldset__legend for one group name announced to assistive tech. Wrap nested controls in .sermona-fieldset__stack.
.sermona-form-section is a visual band (elevated card) with .sermona-form-section__title, optional .sermona-form-section__lede, and .sermona-form-section__stack for fields — use when you are not replacing a single fieldset (e.g. “Shipping” vs “Billing”).
Field rows
.sermona-field-row — responsive CSS grid for short inputs (ZIP, month/year codes). Add .sermona-field-row--duo for a stable two-column row (stacks ≤520px).
Error summary
Place .sermona-form-summary above the first invalid section after submit. Use role="alert" + tabindex="-1" so focus can move to it programmatically. aria-labelledby the title id.
List issues with links (href pointing at id of the field or error message) for keyboard users.
Stepper (wizard chrome)
.sermona-form-stepper is an ordered list (<ol>) of .sermona-form-stepper__item with .sermona-form-stepper__index (step number) and label text. Modifiers: --current, --done. Wire aria-current="step" on the active li when mimicking a multi-page flow.
- 1 Account
- 2 Billing
- 3 Review
Use one primary per step — “Continue” not “Continue + Save” unless they differ.
Repeatable rows
.sermona-repeatable wraps .sermona-repeatable__row blocks. Each row has .sermona-repeatable__fields (grid of .sermona-field children) and optional .sermona-repeatable__remove (ghost button). .sermona-repeatable__toolbar holds Add line (secondary).
Segmented control
.sermona-segmented groups .sermona-segmented__btn buttons for mutually exclusive options (e.g. individual vs company). Use role="group" + aria-label, aria-pressed="true" on the selected button (or --selected).
Not a tablist — if steps change the whole panel, use real tabs or route-level steps instead.
Tax profile
Radio / choice cards
.sermona-choice-grid lays out label.sermona-choice-card tiles. Put the input type="radio" first with .sermona-sr-only so the entire card is the hit target; selected state uses :checked (add .sermona-choice-card--checked from JS if you must support browsers without :has — the CSS also styles :has(input:checked)).
Meta row (hint + counter)
.sermona-field__meta-row wraps .sermona-field__hint and .sermona-field__counter on one line (e.g. bio character count).
Shown on your speaker page.
0 / 280
See also
- Forms, buttons & CTAs — core controls and CTAs
- Modals & lightbox — dialogs for sub-flows
- Data & tables — read-only review tables
- Voice & copy — errors and labels