Marigold
Marigold
App Shellalpha
Admin- and Mastermarknew
Async Data Loading
Feedback Messages
Filteralpha
Form Implementation
Formsnew
Loading States
Multiple Selection
Patterns

Forms

Guidelines for building a consistent form structure

How you design forms affects whether people can actually use them. This page covers layout, spacing, and content organization so your forms stay consistent and accessible.

For implementation details, state management, and validation, see the Form Implementation guide.

Layout & Structure

Layout and structure determine whether a form feels easy or overwhelming. Good spacing and a clear visual hierarchy help people move through a form without getting lost.

Overall form layout

Left-align your forms to match natural reading flow. Keep the width at 800px max (use the container spacing token) so nothing gets too wide to read comfortably.

Whitespace matters more than most people think. Enough breathing room between sections and fields keeps the form scannable and prevents everything from blurring together. Use our spacing tokens to keep that whitespace consistent.

Do
  • Align form content to the left for better scanning and organization.

  • Use a maximum width of 800px (spacing token container) for forms to ensure readability across devices.

  • Ensure sufficient whitespace around and within the form for a clear visual hierarchy.

  • Group related fields together to provide more context and make the UI easier to scan.

Available components

See the Form Fields page for a full guide on input components.

Beyond those, you'll likely need some of these to put a form together:

  • Layout components: <Stack> and <Inset> to organize fields and sections.
  • Accordion: Group fields with an accordion for lengthy forms or optional fields. Use accordions for sections that can be collapsed to save space and reduce cognitive load.
  • Buttons: Use primary buttons for form submission, secondary for additional actions like "View PDF".
  • Links: Use links for navigation to privacy policies or terms of service, not for form actions.
  • Feedback components: <SectionMessage> and <Toast> for inline hints or notifications.

Content Organization

Forms have three levels of hierarchy: fields are the individual inputs, sections divide the form into topics, and groups cluster related fields within a section. Spacing signals how closely things belong together. Tighter spacing means a stronger relationship, wider spacing separates them.

Want to learn more about spacing?

Visit the Spacing page for a full overview of our spacing tokens and how to use them.

Field

Fields are the most fundamental building block of any form. How you arrange and size them affects how easily people can work through it.

  • Use a predictable order. People expect forms to follow a logical sequence, like personal info before payment or name before email. A familiar order reduces cognitive load because users don't have to search for what comes next. When in doubt, follow the conventions people already know from similar forms.
  • Place required fields before optional ones. Within each section, lead with what the user must fill in. This lets people complete the essentials first and decide later whether to provide optional details. It also prevents frustration: nobody wants to discover required fields buried at the bottom after filling in optional ones.
  • Position dependent fields right after their parent. If selecting a country changes the list of available states, those two fields should sit next to each other. Placing dependent fields immediately after the field they depend on makes the relationship obvious and prevents confusion when values change.
  • Match field width to expected content. A postal code field doesn't need the same width as a street address. Setting a maximum width based on the expected input length gives users a visual hint about what's expected and keeps the form looking tidy.

Fields stack vertically by default, but some belong side by side. Two spacing tokens handle this:

  • regular: Vertical spacing between stacked fields. Wrap fields in <Stack space="regular"> within any section or group.
  • related: Horizontal spacing for fields that belong together, like postcode + city or start/end dates. Place them side by side with <Inline space="related">.

Shipping Address

Section

Sections split a form by topic so longer forms stay scannable. They pay off once a form collects different kinds of data or grows past 6-8 fields.

Separate sections with <Stack space="section">. Inside each section, add a headline and wrap the fields in a <Stack space="regular">.

Section headlines can have a short description underneath. Use <Text> with the muted variant for this, and wrap both in a <Stack space="tight"> so they feel connected.

Personal Information

Please provide your name and contact details.

Account Details

Group

Groups are sub-clusters of related fields within a section. Use them when a section contains many fields that benefit from additional visual separation, for example an address block within a personal information section.

To create a group, wrap the fields with <Stack space="group"> to add spacing that visually separates the group from surrounding fields. Inside the group, use <Stack space="regular"> to space the fields as usual. The group token only controls the separation around the group, not the spacing between fields within it.

Personal Information

Enter your full name
Enter your email address

Address

Country

Accordions

Accordions can replace regular sections to create collapsible groups of fields. This is useful for optional information or advanced settings that don't need to be visible by default. Ensure required fields remain visible and are not hidden within collapsed sections.

Accordions can also be used within a section to group content. This lets users focus on what matters while still having access to additional options. The demo below shows both patterns.

Event Details

What is this event about?
Start Date
MM/DD/YYYY
End Date
MM/DD/YYYY

Event Category
Leave empty for unlimited
Used for registration

Location

How to find the venue

'use client';import { useState } from 'react';import {  Accordion,  Checkbox,  DatePicker,  Headline,  Inline,  Inset,  NumberField,  Select,  Stack,  Switch,  TextArea,  TextField,} from '@marigold/components';import { VisualSpacing } from '@/ui/VisualSpacing';export default () => {  const [showSpacing, setShowSpacing] = useState(false);  return (    <Stack space="8">      <Switch        label="Show spacing"        selected={showSpacing}        onChange={setShowSpacing}      />      <Inset spaceX={20}>        <Stack space="section">          <Stack space="regular">            <Headline level={2}>Event Details</Headline>            {showSpacing && (              <VisualSpacing orientation="vertical" space="regular" />            )}            <TextField label="Event Name" required />            {showSpacing && (              <VisualSpacing orientation="vertical" space="regular" />            )}            <TextArea              label="Description"              description="What is this event about?"              rows={3}              required            />            {showSpacing && (              <VisualSpacing orientation="vertical" space="regular" />            )}            <div className={showSpacing ? 'pb-8' : ''}>              <Inline space="related">                <DatePicker label="Start Date" width="fit" required />                {showSpacing && (                  <VisualSpacing space="related" orientation="horizontal" />                )}                <DatePicker label="End Date" width="fit" />              </Inline>            </div>            {showSpacing && (              <VisualSpacing orientation="vertical" space="regular" />            )}            <Accordion variant="card">              <Accordion.Item id="advanced-settings">                <Accordion.Header>Advanced Event Settings</Accordion.Header>                <Accordion.Content>                  <Stack space="regular">                    <Select                      label="Event Category"                      placeholder="Select category"                      width="fit"                    >                      <Select.Option id="conference">Conference</Select.Option>                      <Select.Option id="workshop">Workshop</Select.Option>                      <Select.Option id="meetup">Meetup</Select.Option>                      <Select.Option id="webinar">Webinar</Select.Option>                    </Select>                    <NumberField                      label="Maximum Attendees"                      description="Leave empty for unlimited"                      width={44}                    />                    <TextField                      label="Event Code"                      description="Used for registration"                      width="fit"                    />                    <Checkbox label="Require registration approval" />                    <Checkbox label="Send confirmation emails" />                  </Stack>                </Accordion.Content>              </Accordion.Item>            </Accordion>          </Stack>          {showSpacing && (            <VisualSpacing orientation="vertical" space="section" />          )}          <Stack space="regular">            <Headline level={2}>Location</Headline>            {showSpacing && (              <VisualSpacing orientation="vertical" space="regular" />            )}            <TextField label="Venue Name" required />            {showSpacing && (              <VisualSpacing orientation="vertical" space="regular" />            )}            <TextField label="Address" required />            {showSpacing && (              <VisualSpacing orientation="vertical" space="regular" />            )}            <div className={showSpacing ? 'pb-8' : ''}>              <Inline space="related">                <TextField label="Postal Code" width={20} />                {showSpacing && (                  <VisualSpacing space="related" orientation="horizontal" />                )}                <TextField label="City" required width="1/2" />              </Inline>            </div>            {showSpacing && (              <VisualSpacing orientation="vertical" space="regular" />            )}            <Accordion variant="card">              <Accordion.Item id="location-details">                <Accordion.Header>Additional Location Details</Accordion.Header>                <Accordion.Content>                  <Stack space="regular">                    <Inline space="related" alignY="input">                      <TextField label="Floor" width={10} />                      <TextField label="Room Number" width={16} />                    </Inline>                    <TextArea                      label="Directions"                      description="How to find the venue"                      rows={3}                    />                    <Checkbox label="Wheelchair accessible" />                    <Checkbox label="Parking available" />                  </Stack>                </Accordion.Content>              </Accordion.Item>            </Accordion>          </Stack>          {showSpacing && (            <VisualSpacing orientation="vertical" space="section" />          )}          <Stack space="regular">            <Accordion variant="card">              <Accordion.Item id="contact-info">                <Accordion.Header>Contact Information</Accordion.Header>                <Accordion.Content>                  <Stack space="regular">                    <TextField label="Organizer Name" width="fit" />                    <TextField label="Email" type="email" width="fit" />                    <TextField label="Phone" type="tel" width="fit" />                    <Checkbox label="Display contact info publicly" />                  </Stack>                </Accordion.Content>              </Accordion.Item>            </Accordion>            {showSpacing && (              <VisualSpacing orientation="vertical" space="regular" />            )}            <Accordion variant="card">              <Accordion.Item id="special-requirements">                <Accordion.Header>Special Requirements</Accordion.Header>                <Accordion.Content>                  <Stack space="regular">                    <Checkbox label="Catering required" />                    <Checkbox label="Audio/Visual equipment needed" />                    <Checkbox label="Security required" />                    <TextArea label="Additional Notes" rows={3} />                  </Stack>                </Accordion.Content>              </Accordion.Item>            </Accordion>          </Stack>        </Stack>      </Inset>    </Stack>  );};

Actions

Forms usually need more than just a submit button. Links, secondary buttons, and other controls handle everything from navigation to drafts. The key is making each action easy to find and hard to confuse with the primary submit.

Inline actions

Some actions belong inside the form body, next to the fields they relate to.

  • Links for navigation-like actions. Opening a map, viewing a PDF, or linking to terms of service. These aren't form operations, so style them as links. Place them near the field they support.
  • Secondary buttons for form operations. "Create new", "Reset", or "Save as Draft" should be visually distinct from the primary submit so people don't hit the wrong one.
  • Put each action close to what it affects. An action buried at the bottom of the form is easy to miss when it only matters for one specific field.
Venue
Country
Open in maps

Submit placement

Put the submit button at the bottom of the form, aligned left. The primary button stays put; other actions arrange themselves around it.

Where you place secondary actions depends on what they do:

  • "Save as Draft" and similar alternative completions go beside the primary button, styled as secondary.
  • "Cancel" also sits beside the primary button, but always after it so the most important action comes first in reading and tab order.
Primary action and cancel
With additional alternative completion

Admin- and Mastermark

Some fields are only relevant for administrators or master users. Mark and separate these from regular fields so other users aren't confused by them.

See the Admin- and Mastermark page for the full usage guide.

Full demo

Below is a fictional event registration form that puts all of these guidelines together: sections, field types, and actions.

View Demo

View Code

Related

Form Fields

A guide to all available form field components.

Form Implementation Guide

Learn how to build forms.
Last update: a day ago

Form Implementation

This page should introduce you on how to develop form logic with Marigold.

Loading States

Learn when to use which loading state.

On this page

Layout & StructureOverall form layoutAvailable componentsContent OrganizationFieldSectionGroupAccordionsActionsInline actionsSubmit placementAdmin- and MastermarkFull demoRelated