From 2314f7817c31d1f4aad6828fc06e3950bfc1710f Mon Sep 17 00:00:00 2001 From: Ajay Dhangar Date: Tue, 13 Oct 2026 09:32:55 +0530 Subject: [PATCH] Added HTML Forms docs --- tutorials/html/08-forms/accessible-forms.mdx | 570 ++++++++++++- tutorials/html/08-forms/autocomplete.mdx | 528 +++++++++++- tutorials/html/08-forms/button.mdx | 646 ++++++++++++++- tutorials/html/08-forms/datalist.mdx | 498 +++++++++++- .../html/08-forms/fieldset-and-legend.mdx | 572 ++++++++++++- tutorials/html/08-forms/form-action.mdx | 520 +++++++++++- tutorials/html/08-forms/form-element.mdx | 523 +++++++++++- tutorials/html/08-forms/form-methods.mdx | 507 +++++++++++- tutorials/html/08-forms/form-validation.mdx | 769 +++++++++++++++++- tutorials/html/08-forms/index.mdx | 374 +++++++-- tutorials/html/08-forms/input-element.mdx | 626 +++++++++++++- .../html/08-forms/input-types/_category_.json | 17 + .../html/08-forms/input-types/checkbox.mdx | 521 +++++++++++- tutorials/html/08-forms/input-types/color.mdx | 512 +++++++++++- tutorials/html/08-forms/input-types/date.mdx | 508 +++++++++++- .../08-forms/input-types/datetime-local.mdx | 496 ++++++++++- tutorials/html/08-forms/input-types/email.mdx | 489 ++++++++++- tutorials/html/08-forms/input-types/file.mdx | 537 +++++++++++- .../html/08-forms/input-types/hidden.mdx | 444 +++++++++- tutorials/html/08-forms/input-types/month.mdx | 498 +++++++++++- .../html/08-forms/input-types/number.mdx | 549 ++++++++++++- .../html/08-forms/input-types/password.mdx | 517 +++++++++++- tutorials/html/08-forms/input-types/radio.mdx | 541 +++++++++++- tutorials/html/08-forms/input-types/range.mdx | 516 +++++++++++- .../html/08-forms/input-types/search.mdx | 515 +++++++++++- .../input-types/submit-reset-button.mdx | 508 +++++++++++- tutorials/html/08-forms/input-types/tel.mdx | 415 +++++++++- tutorials/html/08-forms/input-types/text.mdx | 476 ++++++++++- tutorials/html/08-forms/input-types/time.mdx | 463 +++++++++++ tutorials/html/08-forms/input-types/url.mdx | 472 ++++++++++- tutorials/html/08-forms/input-types/week.mdx | 503 +++++++++++- tutorials/html/08-forms/label-element.mdx | 619 +++++++++++++- tutorials/html/08-forms/min-and-max.mdx | 543 ++++++++++++- .../html/08-forms/minlength-and-maxlength.mdx | 496 ++++++++++- .../html/08-forms/multipart-form-data.mdx | 531 +++++++++++- .../html/08-forms/option-and-optgroup.mdx | 560 ++++++++++++- tutorials/html/08-forms/pattern.mdx | 532 +++++++++++- tutorials/html/08-forms/required.mdx | 490 ++++++++++- .../html/08-forms/secure-form-design.mdx | 637 ++++++++++++++- tutorials/html/08-forms/select.mdx | 592 +++++++++++++- tutorials/html/08-forms/textarea.mdx | 632 +++++++++++++- 41 files changed, 20801 insertions(+), 461 deletions(-) create mode 100644 tutorials/html/08-forms/input-types/_category_.json diff --git a/tutorials/html/08-forms/accessible-forms.mdx b/tutorials/html/08-forms/accessible-forms.mdx index ab2a288b0..eade1946d 100644 --- a/tutorials/html/08-forms/accessible-forms.mdx +++ b/tutorials/html/08-forms/accessible-forms.mdx @@ -1,16 +1,566 @@ --- -id: accessible-forms -title: "Best Practices for Accessible HTML Forms" +id: html-accessible-forms +title: "Accessible HTML Forms" sidebar_label: "Accessible Forms" -sidebar_position: 20 +sidebar_position: 21 slug: /html/forms/accessible-forms -description: "Ensure forms comply with WCAG standards using proper labeling, explicit field grouping, clear error messages, and ARIA attributes." +description: "Learn how to build accessible HTML forms: visible labels, grouping with fieldset and legend, hints and instructions, marking required fields, clear error messages with aria-invalid and aria-describedby, autocomplete, keyboard and focus, touch target size, WCAG 2.2 rules for forms, redundant entry and accessible authentication, and a practical testing checklist." keywords: - accessible HTML forms - - WCAG form accessibility - - aria-describedby form errors - - screen reader form navigation + - form accessibility + - WCAG forms + - label for input + - fieldset legend accessibility + - aria-describedby aria-invalid + - accessible form errors + - placeholder is not a label + - WCAG 2.2 target size + - form accessibility checklist + - learn HTML forms - CodeHarborHub HTML -authors: [ajay-dhangar] -tags: [html, forms, accessibility, a11y] ---- \ No newline at end of file +tags: [html, web-development, beginner, forms, accessibility, wcag, a11y, frontend] +--- + +import {useState, useRef} from 'react'; + +export function audit(form) { + const issues = []; + const fields = Array.from(form.elements).filter( + (el) => ["INPUT", "SELECT", "TEXTAREA"].includes(el.tagName) && !["hidden", "submit", "button", "reset"].includes(el.type) + ); + fields.forEach((el) => { + const label = el.name || el.type; + const hasName = + (el.labels && el.labels.length > 0) || + el.getAttribute("aria-label") || + el.getAttribute("aria-labelledby"); + if (!hasName) { + issues.push("The " + label + " field has no label. Screen readers cannot tell what it is for." + (el.placeholder ? " (A placeholder is not a label.)" : "")); + } + const wantsAutocomplete = ["name", "email", "tel", "username"].includes(el.name) || ["email", "tel"].includes(el.type); + if (wantsAutocomplete && !el.getAttribute("autocomplete")) { + issues.push("The " + label + " field is about the visitor but has no autocomplete token."); + } + }); + return {count: fields.length, issues}; +} + +export function AuditDemo() { + const poorRef = useRef(null); + const goodRef = useRef(null); + const [report, setReport] = useState(null); + return ( +
+
+
event.preventDefault()} style={{flex: "1 1 14rem"}}> +

Form A

+
+
+
+ +
+
event.preventDefault()} style={{flex: "1 1 14rem"}}> +

Form B

+
+
+
+
+
+
+ +
+
+

+ +

+ {report ? ( +
+ {[["Form A", report.a], ["Form B", report.b]].map(([title, result]) => ( +
+ + {title}: {result.issues.length === 0 ? "no problems found in " + result.count + " fields" : result.issues.length + " problems in " + result.count + " fields"} + +
    + {result.issues.map((text) => (
  • {text}
  • ))} +
+
+ ))} +
+ ) : null} +
+ ); +} + +export function GroupedDemo() { + const [value, setValue] = useState(""); + return ( +
event.preventDefault()}> +
+ How should we contact you? (required) +

We will only use this to answer your message.

+ + + +
+ +
+ ); +} + +Think about the last time you filled in a form. You **saw** the labels, **clicked** the box you wanted, **read** the red error message, and **moved** your mouse to the button. Now imagine doing it **without seeing the screen**, or **without using a mouse**, or with a tremor, or while holding a baby in one arm, or in bright sunlight on a small phone. + +That is the point of **accessible forms**: forms that work for **everyone**, in every situation. And here is the good news: most of it comes **free** from the HTML elements you have already learned. This lesson pulls it all together into one clear set of habits. + + +
+ +## What You Will Learn + +- Why accessible forms matter, and who benefits +- The seven habits that fix most problems +- Labels, groups, hints, and required markers +- Clear errors that everyone can find and fix +- Keyboard, focus, and touch targets +- The key WCAG 2.2 rules for forms +- Easy authentication and less retyping +- A checklist to test any form + +## Why It Matters + +Accessible forms help far more people than you might think: + +| Who | How accessible forms help | +| :-- | :-- | +| Screen reader users | Hear each field's label, hints, and errors | +| Keyboard-only users (including voice control and switch users) | Reach and operate every field without a mouse | +| People with low vision | Can zoom in, and see clear focus and good contrast | +| People with motor difficulties | Have big targets and less typing (autofill) | +| People with dyslexia or cognitive differences | Get plain words, clear instructions, and forgiving errors | +| People on phones, in sunlight, or in a hurry | Get the right keyboard, big buttons, and clear messages | +| Everyone, with a temporary injury or a noisy room | Gets a form that just works | + +It is also often a **legal requirement** (many countries reference WCAG, the Web Content Accessibility Guidelines, in their laws), and accessible forms usually have **higher completion rates**, which means more sign-ups and sales. + +## The Seven Habits + +If you remember only seven things, remember these: + +1. **Every field has a visible, connected label.** +2. **Group related fields** with `fieldset` and `legend`. +3. **Use the right element and input type.** Native controls first. +4. **Say what is required, and what format is expected,** before the visitor types. +5. **Write clear errors,** linked to their fields, and move focus to the first problem. +6. **Make everything work with a keyboard,** with a clearly visible focus. +7. **Test it** with a keyboard and a screen reader, not only your eyes. + +## Try It: A Tiny Accessibility Audit + +Below are two forms that look almost the same. Press the button, and a small script inspects each field, using the same information a screen reader sees: is there a label, and is there an `autocomplete` token? + + + + +```html title="index.html" + +
+ + + + +
+ + +
+ + + + + + + + + + +
+``` + +```js title="script.js" +function audit(form) { + for (const el of form.elements) { + if (!["INPUT", "SELECT", "TEXTAREA"].includes(el.tagName)) continue; + if (["hidden", "submit", "button", "reset"].includes(el.type)) continue; + + const hasName = + el.labels.length > 0 || + el.getAttribute("aria-label") || + el.getAttribute("aria-labelledby"); + + if (!hasName) console.log(el.name + ": no label!"); + } +} +``` + +
+ + + +<> + + + + + +
+ +Form A has placeholders only. Sighted visitors can read them, but the moment they start typing, the hint vanishes, and screen readers may not announce a placeholder as a name at all. This tiny check catches only a small slice of problems, but it shows the key idea: **accessibility is built into the markup.** + +## 1. Labels: the Foundation + +Every field needs a **visible** `