Skip to content
Development
Skill

/form-design

Helper text, placeholders, validation and submit behaviour. Use when designing or reviewing a form, input field or data entry UI.

From plugin
dembrandt
18045 skills1 MCP

Claude Code

$ npx -y skills add dembrandt/dembrandt-skills --skill form-design --agent claude-code

SKILL.md

form-design.SKILL.md
name: form-design
description: Helper text, placeholders, validation and submit behaviour. Use when designing or reviewing a form, input field or data entry UI.
metadata:
  priority: 8
  pathPatterns:
    - "components/**"
    - "src/components/**"
    - "**/*.tsx"
    - "**/*.jsx"
    - "**/*.html"
    - "design-system/**"
    - "ui/**"
  promptSignals:
    phrases:
      - "form"
      - "input"
      - "validation"
      - "placeholder"
      - "helper text"
      - "field"
      - "submit"
      - "required"
      - "error message"
      - "fieldset"
retrieval:
  aliases:
    - form design
    - input validation
    - helper text
    - placeholder
    - form validation
    - real-time validation
    - submit button state
  intents:
    - design a form
    - add validation to inputs
    - write helper text
    - enable submit when valid
    - add real-time validation
    - improve form usability
  examples:
    - add helper text to this input
    - validate this field in real time
    - disable the submit button until the form is valid
    - design this form with proper validation

Form Design

Forms are where users give the product data. Every unnecessary obstacle between the user and a completed form is a failure. The design goal is to make correct input easy and incorrect input obvious — before the user submits.

---

The Three Guidance Layers

Each layer serves a distinct purpose. Do not collapse them.

Layer 1 — Helper Text

Explains *what* to enter. Appears below the input, always visible, in small secondary text.

Email address
[                              ]
Use the email you signed up with.
  • Write in plain language from the user's perspective
  • Keep it to one sentence — if you need more, the field is too complex or misnamed
  • Do not repeat the label ("Enter your email" below a label that says "Email" is redundant)
  • Helper text is not a replacement for a label — the label is still required

Layer 2 — Placeholder

Shows the *format* or an example value. Appears inside the input, disappears on typing.

[jane@example.com              ]
  • Use a realistic example, not a description: `+358 40 123 4567` not `Enter phone number`
  • Never use placeholder as a label — it disappears and leaves the user without context
  • Keep it grey (`--color-text-secondary`) and lighter than actual input text
  • Optional — not every field needs a placeholder

Layer 3 — Validation

Confirms whether the input is correct. The most important layer.

Email address
[jane@           ] ← invalid
✗ Enter a valid email address.

**Validation timing:**

  • **On blur** (leaving the field): default for most fields — validates once the user has finished
  • **Real-time** (on input): use when the format is complex or the error is likely — password strength, IBAN, VAT number, URL, regex-heavy fields
  • **On submit**: catches anything missed, scrolls to the first error

Real-time validation must be forgiving at the start — do not show an error the instant the user starts typing. Show it after a short debounce (300–500ms) or after the first character that makes the input definitively wrong.

---

Submit Button State

The submit button enables when the form is valid. This is one of the clearest affordance signals in form design — the user sees the goal and knows when they have reached it.

[Submit]   ← disabled, low contrast, cursor: not-allowed
           (fields incomplete or invalid)

[Submit]   ← enabled, full colour, cursor: pointer
           (all required fields valid)

**Implementation:**

<button type="submit" disabled={!isFormValid}>Submit</button>

For long or complex forms where real-time validation is not practical, do not disable the submit — validate on submit and scroll to errors instead. Disabled submit on a long form frustrates users who cannot tell what is missing.

**Loading state on submit:** Replace label with spinner, disable the button. Prevent double-submission.

---

Field Anatomy

[Label]                           [Optional badge if optional]
[Input field                                                  ]
[Helper text — what to enter, format, constraints            ]
[Error message — appears below helper text on validation fail ]
<div class="field">
  <label for="vat">VAT number <span class="optional">Optional</span></label>
  <input
    id="vat"
    type="text"
    placeholder="FI12345678"
    aria-describedby="vat-helper vat-error"
    aria-invalid="true"
  >
  <p id="vat-helper" class="helper-text">Finnish VAT numbers start with FI followed by 8 digits.</p>
  <p id="vat-error" class="error-text" role="alert">Enter a valid Finnish VAT number (e.g. FI12345678).</p>
</div>

---

Required vs Optional

Mark the minority. If most fields are required, mark the optional ones. If most are optional, mark the required ones.

  • Do not rely on colour alone — add a text label ("Required" or asterisk with legend)
  • Place the required/optional indicator in the label, not only in the placeholder or helper text
<label>Email <abbr title="Required">*</abbr></label>
<!-- or -->
<label>Phone <span class="badge">Optional</span></label>

---

Grouping with Fieldset

Related fields belong in a `<fieldset>` with a `<legend>`. This is semantic HTML and helps screen readers announce the group context.

<fieldset>
  <legend>Billing address</legend>
  <label>Street</label><input type="text">
  <label>City</label><input type="text">
  <label>Postal code</label><input type="text">
</fieldset>

Use fieldsets for:

  • Address groups
  • Payment details
  • Radio button groups
  • Checkbox groups

---

Input Types

Use the correct `type` — browsers provide free validation, appropriate keyboards, and autofill.

| Data | Input type | |---|---| | Email | `type="email"` | | Phone | `type="tel"` | | URL | `type="url"` | | Number | `type="number"` | | Password | `type="password"` | | Date | `type="date"` | | Search | `

Read more
@dembrandt
Ships withdembrandt

Enterprise UX secrets, now built into your AI agent. Your agent writes the component in seconds. It does not know the modal should be a drawer, or that the grey it picked fails contrast. These skills carry that judgment: what to do, and what breaks otherwise.

18045 skills1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
180
Star history of dembrandt/dembrandt-skills on GitHub, a chart by star-history.com

Other skills on dembrandt.

app-shell

app-shell

Top bar, sidebar rail, app launcher, tenant and environment cue, status bar. Use when designing the persistent shell, a…

@dembrandt@dembrandtInstall Skill
brand-visual-language

brand-visual-language

Shape language across type, radius and icons carries brand personality. Use when starting a design system, picking icons or…

@dembrandt@dembrandtInstall Skill
button-states

button-states

Rest, hover, active, focus, disabled and loading states, derived from the base colour. Use when designing buttons, links, inputs…

@dembrandt@dembrandtInstall Skill
clone-website

clone-website

Rebuild a live web page 1:1 from measurement into Figma, Penpot or code, then verify it. Use when reproducing a page or checking…

@dembrandt@dembrandtInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills11d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc13d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react2d252k
@facebook@facebookInstall Skill

Questions about form-design.

Which coding agents can use form-design?
form-design installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.