Skip to content

Accessible forms

Forms are where accessibility matters most. A contact form, a search box, a newsletter signup -- if a user cannot understand what a field expects, cannot identify errors, or cannot submit the form with a keyboard, the form is broken for them.

Two guiding principles:

  1. Every input needs a visible label. Placeholders are not labels. Screen readers may not announce placeholders, and they disappear as soon as the user starts typing.
  2. Errors must be clear and specific. "There was an error" is useless. "Email address must include an @ symbol" is actionable.

Labeling form fields

Every <input>, <textarea>, and <select> needs an associated <label>. The label tells screen readers what the field is for. Without it, a screen reader may announce "edit text, blank" -- the user has no idea what to type.

How to create a label in Silex

  1. Drag a Label block from the Blocks panel (or drag a Text block and change its Tag Name to LABEL in the Element settings, gear icon at the top of the right panel)
  2. Type the label text (e.g., "Email address")
  3. Select the label element
  4. In the Element settings (gear icon), a For field appears when the tag is LABEL
  5. Enter the input's id in the For field

To set an id on the input:

  1. Select the input element
  2. In the Element settings (gear icon), fill the ID field with something descriptive (e.g., email)

Now the label and input are programmatically linked. Clicking the label focuses the input, and screen readers announce the label text when the input receives focus. The published HTML reads <label for="email"> and <input id="email">.

A label selected in a form on the canvas, with the Element settings on the right showing its For field set to name, the ID of the input next to it

Placeholder is not a label

Placeholder text disappears when the user types. This means:

  • Users cannot check what the field expects after they start typing
  • Placeholder text often has insufficient contrast (light gray)
  • Some screen readers do not announce placeholder text
  • Users with cognitive disabilities may think the field is already filled in

Use placeholders for examples ("e.g., name@example.com"), not for the field name. Always have a visible <label>.

When fields are related -- like first name and last name, or a set of radio buttons -- group them so the relationship is clear.

In standard HTML, <fieldset> and <legend> create labeled groups. Silex does not have a dedicated fieldset block, but you can achieve the same effect:

  1. Wrap related fields in a container
  2. Change the container's Tag Name to SECTION
  3. Add a heading (h2, h3, etc.) as the first child to describe the group
  4. Screen readers will announce the section and its heading, providing context

For radio buttons and checkboxes that form a group (e.g., "Preferred contact method: Email / Phone / SMS"), this grouping is essential -- without it, the user hears each option in isolation.

Required fields

To mark a field as required:

  1. Select the field (Input, Textarea, Select, Checkbox or Radio)
  2. In the Element settings (gear icon), check Required
  3. Add a visual indicator next to the label: an asterisk (*) with an explanation at the top of the form ("Fields marked * are required")

Do not rely on color alone (e.g., red border) to indicate required fields. See Text, contrast, and readability for why.

Autocomplete

The autocomplete attribute helps browsers and password managers fill in common fields automatically. This is especially important for users with motor impairments or cognitive disabilities -- fewer keystrokes means fewer errors.

Add autocomplete via the Attributes section:

Field Autocomplete value
Full name name
Email email
Phone tel
Street address street-address
City address-level2
Postal code postal-code
Country country
Credit card number cc-number
Username username
Current password current-password
New password new-password

To add:

  1. Select the input
  2. In the Attributes section, click +
  3. Name the attribute autocomplete
  4. Set the value (e.g., email)

Error messages

When form validation fails, error messages must be:

  • Visible -- not just a color change, not hidden in a tooltip
  • Specific -- "Email address must include an @ symbol" not "Invalid input"
  • Associated with the field -- placed near the field, ideally right below it

For client-side validation, modern browsers handle basic validation automatically when you use the correct input types (email, number) and check Required. The browser displays native error messages that are already accessible.

For custom validation using JavaScript (via Custom code), associate error messages with inputs using aria-describedby:

  1. Add a text element below the input for the error message
  2. Give the error element an id (via the Attributes section): e.g., email-error
  3. On the input, add an aria-describedby attribute (via the Attributes section) with the error element's id: email-error
  4. Screen readers will announce the error text when the input is focused

Input types

Using the correct input type improves accessibility and usability:

Type Effect
text Any text (default)
email Shows email keyboard on mobile, validates @
number Shows numeric keyboard, allows increment buttons
password Masks input, triggers password manager

Set the input type in the Type menu of the Element settings (gear icon) when the input element is selected. The menu offers only these four types.

Practical example: accessible contact form

You are building a contact form with name, email, message, and submit button.

  1. Form container: Drag a Form block. The <form> element is already correct. It comes with sample fields (Name, Email, Gender checkboxes, Message and a Send button): reuse them and delete the Gender row.

  2. Name field:

  3. Label: double-click it and type "Full name *". In the Element settings, set For: name
  4. Input: set ID to name and check Required in the Element settings. In Attributes, click +, name it autocomplete and give it the value name

  5. Email field:

  6. Label: "Email address *", For: email
  7. Input: its Type is already email. Set ID to email, check Required, and add the attribute autocomplete = email

  8. Message field:

  9. Label: "Your message *", For: message
  10. Textarea: set ID to message and check Required

  11. Submit button:

  12. Select the button. In the Element settings, set Text to "Send message" and Type to submit: the Form block's button is of type button, which neither submits the form nor triggers the validation
  13. The <button> element is already keyboard-accessible

  14. Required fields notice:

  15. Add a Text element above the first field: "Fields marked * are required"

  16. Test (on the published page: in the editor, even in preview, Tab doesn't move the focus between the fields):

  17. Tab through the form: each field should receive focus in order
  18. Screen reader should announce: "Full name, required, edit text" for the first field
  19. Submit with empty fields: browser should show validation messages

Common mistakes

  • No labels on inputs. The most common form accessibility failure. Every input needs a <label> with a matching for attribute.
  • Placeholder as the only label. Placeholder text disappears on input, has poor contrast, and may not be announced by screen readers.
  • Required fields indicated only by color. Add text ("required" or "*" with explanation) alongside any color indicator.
  • Generic error messages. "Error" or "Invalid input" does not help the user fix the problem. Be specific.
  • No autocomplete. Users with motor impairments benefit greatly from autocomplete. Add the attribute to standard fields.
  • Wrong input types. Using type="text" for email means no email keyboard on mobile and no browser validation. Use the right type.

Learn more


Reference: WCAG form requirements summary
Criterion Level Requirement
1.3.1 Info and Relationships A Labels, instructions, and groupings are programmatically associated
1.3.5 Identify Input Purpose AA Input purpose is programmatically determinable (autocomplete)
2.4.6 Headings and Labels AA Labels describe topic or purpose
3.3.1 Error Identification A Errors are identified and described in text
3.3.2 Labels or Instructions A Labels or instructions provided for user input
3.3.3 Error Suggestion AA Suggestions for fixing errors are provided

Quiz

Q1: A form field has placeholder text "Enter your email" but no <label> element. A screen reader user focuses the field. What do they hear?

  • A) "Enter your email, edit text"
  • B) "Edit text, blank" (the placeholder may not be announced)
  • C) "Email, required, edit text"
Answer

B) "Edit text, blank" -- Some screen readers do not announce placeholder text. Without a <label>, the user has no way to know what the field expects. Always use a visible label.

Q2: You want to mark a field as required. Which approach is most accessible?

  • A) Red border only
  • B) Red border + asterisk (*) in the label + "Fields marked * are required" at the top + required attribute
  • C) Placeholder text that says "Required"
Answer

B) Red border + asterisk + explanation + required attribute -- This covers all users: visual (red border + asterisk), text-based (explanation), and programmatic (the required attribute tells browsers and screen readers).

Q3: A contact form has fields for name, email, and phone, but no autocomplete attributes. Who is most affected?

  • A) Sighted users with a mouse
  • B) Users with motor impairments who struggle with typing
  • C) Screen reader users
Answer

B) Users with motor impairments -- autocomplete reduces the number of keystrokes needed. For users who find typing physically difficult, this is a significant usability improvement.

Edit this page on GitLab