Files
awesome-copilot/skills/create-web-form/references/form-controls.md
jhauga 27149859a4 Add skill to create web forms
Add skill to create web forms
2026-02-09 19:22:54 -05:00

23 KiB

Form Controls Reference

A consolidated reference guide covering HTML form structure, native form controls, HTML5 input types, and additional form elements. Content sourced from the Mozilla Developer Network (MDN) Web Docs.


Table of Contents

  1. How to Structure a Web Form
  2. Basic Native Form Controls
  3. HTML5 Input Types
  4. Other Form Controls

How to Structure a Web Form

Source: https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Forms/How_to_structure_a_web_form

The <form> Element

The <form> element formally defines a form and determines its behavior. It must wrap all form contents.

Important: Never nest a form inside another form -- this causes unpredictable behavior.

<form>
  <!-- form contents -->
</form>

Form controls can exist outside a <form> element using the form attribute to associate them with a specific form by its ID.

Grouping and Semantic Structure

The <fieldset> and <legend> Elements

<fieldset> groups widgets that share the same purpose, improving usability and accessibility. <legend> provides a descriptive label for the fieldset.

Key Benefits:

  • Screen readers (like JAWS and NVDA) speak the legend before each control inside the fieldset
  • Essential for grouping radio buttons and checkboxes
  • Useful for sectioning long forms across multiple pages
<form>
  <fieldset>
    <legend>Fruit juice size</legend>
    <p>
      <input type="radio" name="size" id="size_1" value="small" />
      <label for="size_1">Small</label>
    </p>
    <p>
      <input type="radio" name="size" id="size_2" value="medium" />
      <label for="size_2">Medium</label>
    </p>
    <p>
      <input type="radio" name="size" id="size_3" value="large" />
      <label for="size_3">Large</label>
    </p>
  </fieldset>
</form>

Result: Screen readers announce: "Fruit juice size small," "Fruit juice size medium," "Fruit juice size large"

Labels: The Foundation of Accessibility

The <label> Element

Labels formally associate text with form controls. The for attribute connects a label to its input via the input's id.

<label for="name">Name:</label>
<input type="text" id="name" name="user_name" />

Implicit Association: Nest the control inside the label (though explicit for attribute is still best practice):

<label for="name">
  Name: <input type="text" id="name" name="user_name" />
</label>

Accessibility Impact:

  • Screen readers announce: "Name, edit text"
  • Without proper labels: "Edit text blank" (not helpful)

Labels Are Clickable

Clicking or tapping a label activates its associated control -- especially useful for checkboxes and radio buttons with small hit areas.

<form>
  <p>
    <input type="checkbox" id="taste_1" name="taste_cherry" value="cherry" />
    <label for="taste_1">I like cherry</label>
  </p>
</form>

Multiple Labels (Best Practices)

Avoid putting multiple labels on a single widget. Instead, include all text within one label:

<!-- Not recommended -->
<label for="username">Name:</label>
<input id="username" type="text" name="username" required />
<label for="username">*</label>

<!-- Better -->
<label for="username">
  <span>Name:</span>
  <input id="username" type="text" name="username" required />
  <span>*</span>
</label>

<!-- Best -->
<label for="username">Name *:</label>
<input id="username" type="text" name="username" required />

Common HTML Structures with Forms

Use these semantic HTML elements to structure forms:

  • <ul> / <ol> with <li>: Recommended for grouping checkboxes or radio buttons
  • <p>: Wrap label-control pairs
  • <div>: General grouping
  • <section>: Group related form sections
  • <h1>, <h2>: Organize complex forms into sections

Complete Payment Form Example

<form>
  <h1>Payment form</h1>
  <p>Please complete all required (*) fields.</p>

  <!-- Contact Information Section -->
  <section>
    <h2>Contact information</h2>

    <fieldset>
      <legend>Title</legend>
      <ul>
        <li>
          <label for="title_1">
            <input type="radio" id="title_1" name="title" value="A" />
            Ace
          </label>
        </li>
        <li>
          <label for="title_2">
            <input type="radio" id="title_2" name="title" value="K" />
            King
          </label>
        </li>
      </ul>
    </fieldset>

    <p>
      <label for="name">Name *:</label>
      <input type="text" id="name" name="username" required />
    </p>

    <p>
      <label for="mail">Email *:</label>
      <input type="email" id="mail" name="user-mail" required />
    </p>

    <p>
      <label for="pwd">Password *:</label>
      <input type="password" id="pwd" name="password" required />
    </p>
  </section>

  <!-- Payment Information Section -->
  <section>
    <h2>Payment information</h2>

    <p>
      <label for="card">Card type:</label>
      <select id="card" name="user-card">
        <option value="visa">Visa</option>
        <option value="mc">Mastercard</option>
        <option value="amex">American Express</option>
      </select>
    </p>

    <p>
      <label for="number">Card number *:</label>
      <input type="tel" id="number" name="card-number" required />
    </p>
  </section>

  <!-- Submit Section -->
  <section>
    <p>
      <button type="submit">Validate the payment</button>
    </p>
  </section>
</form>

Form Structure Best Practices

Practice Benefit
Always use <form> wrapper Recognized by assistive tech and browser plugins
Wrap related controls in <fieldset> with <legend> Improves usability and accessibility
Always associate labels with for attribute Screen readers announce label with control
Use semantic HTML (<section>, <h2>, etc.) Better form structure and accessibility
Group radio buttons/checkboxes in lists Clearer visual and semantic organization
Indicate required fields clearly Users and AT know which fields are mandatory
Test with screen readers Verify the form is truly accessible

Basic Native Form Controls

Source: https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Forms/Basic_native_form_controls

Text Input Fields

Single Line Text Fields

Created with <input type="text"> or omitting the type attribute (text is the default).

<input type="text" id="comment" name="comment" value="I'm a text field" />

Common text field behaviors:

  • Can be marked as readonly (value shown but not modifiable, still sent in form submission) or disabled (not sent with form)
  • Support placeholder attribute for brief descriptions
  • Can be constrained with size (physical box size) and maxlength (character limit)
  • Benefit from spellcheck attribute
  • Remove line breaks automatically before sending to server

Password Field

Obscures input characters (shown as dots or asterisks) for security.

<input type="password" id="pwd" name="pwd" />

Security Note: This only hides the text visually. Always use HTTPS for secure form transmission to prevent data interception.

Hidden Content

Invisible form control sent with form data (e.g., timestamps, tracking information).

<input type="hidden" id="timestamp" name="timestamp" value="1286705410" />
  • Not visible to users
  • Never receives focus
  • Cannot be intentionally edited by users
  • Screen readers will not notice it
  • Must have name and value attributes

Checkable Items: Checkboxes and Radio Buttons

Checkbox

Multiple selections allowed. Each checkbox can be independently checked or unchecked.

<fieldset>
  <legend>Choose all the vegetables you like to eat</legend>
  <ul>
    <li>
      <label for="carrots">Carrots</label>
      <input
        type="checkbox"
        id="carrots"
        name="vegetable"
        value="carrots"
        checked />
    </li>
    <li>
      <label for="peas">Peas</label>
      <input type="checkbox" id="peas" name="vegetable" value="peas" />
    </li>
    <li>
      <label for="cabbage">Cabbage</label>
      <input type="checkbox" id="cabbage" name="vegetable" value="cabbage" />
    </li>
  </ul>
</fieldset>

Properties:

  • Use same name attribute for related checkboxes
  • Include checked attribute to pre-select
  • Only values of checked boxes are sent with form

Radio Button

Only one selection allowed per group. Tied together by the same name attribute.

<fieldset>
  <legend>What is your favorite meal?</legend>
  <ul>
    <li>
      <label for="soup">Soup</label>
      <input type="radio" id="soup" name="meal" value="soup" checked />
    </li>
    <li>
      <label for="curry">Curry</label>
      <input type="radio" id="curry" name="meal" value="curry" />
    </li>
    <li>
      <label for="pizza">Pizza</label>
      <input type="radio" id="pizza" name="meal" value="pizza" />
    </li>
  </ul>
</fieldset>

Properties:

  • Buttons in same group share name attribute
  • Checking one automatically unchecks others
  • Only checked value is sent with form
  • Cannot uncheck all without resetting form

Accessibility Best Practice: Wrap related items in <fieldset> with <legend> describing the group, and place each <label>/<input> pair together.

Buttons

Submit Button

Sends form data to server.

<!-- Using <input> -->
<input type="submit" value="Submit this form" />

<!-- Using <button> -->
<button type="submit">Submit this form</button>

Reset Button

Resets all form widgets to default values.

<!-- Using <input> -->
<input type="reset" value="Reset this form" />

<!-- Using <button> -->
<button type="reset">Reset this form</button>

Anonymous Button

No automatic effect; requires JavaScript customization.

<!-- Using <input> -->
<input type="button" value="Do Nothing without JavaScript" />

<!-- Using <button> -->
<button type="button">Do Nothing without JavaScript</button>

Advantage of <button> elements: Much easier to style and supports HTML content inside tags.

Image Button

Renders as an image but behaves as a submit button. Submits X and Y coordinates of click.

<input type="image" alt="Click me!" src="my-img.png" width="80" height="30" />

Coordinate Submission:

  • X coordinate key: [name].x
  • Y coordinate key: [name].y

Example URL with GET method:

https://example.com?pos.x=123&pos.y=456

File Picker

Allows users to select one or more files to send to server.

<!-- Single file -->
<input type="file" name="file" id="file" accept="image/*" />

<!-- Multiple files -->
<input type="file" name="file" id="file" accept="image/*" multiple />

Mobile Device Capture -- access device camera, microphone, or storage directly:

<input type="file" accept="image/*;capture=camera" />
<input type="file" accept="video/*;capture=camcorder" />
<input type="file" accept="audio/*;capture=microphone" />

Attributes:

  • accept: Constrains file types (e.g., image/*, .pdf)
  • multiple: Allows selecting multiple files

Common Attributes for All Form Controls

Attribute Default Description
autofocus false Element automatically receives focus when page loads (only one per document)
disabled false User cannot interact; inherits from containing <fieldset> if applicable
form -- Associates control with <form> element by ID (allows control outside form)
name -- Control name; submitted with form data
value -- Element's initial value

Form Data Submission Behavior

Checkable Items Special Case:

  • Values sent only if checked
  • Unchecked items: nothing is sent (not even name)
  • Checked but no value attribute: name is sent with value of "on"
<input type="checkbox" name="subscribe" value="yes" />
  • If checked: subscribe=yes
  • If unchecked: (nothing)

HTML5 Input Types

Source: https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Forms/HTML5_input_types

HTML5 introduced new <input type> values to create native form controls with built-in validation and improved user experience across devices.

Email Address Field (type="email")

<label for="email">Enter your email address:</label>
<input type="email" id="email" name="email" />

Key Features:

  • Validation: Browser validates email format before submission
  • Multiple emails: Use multiple attribute for comma-separated addresses
  • Mobile keyboards: Displays @ symbol by default on touch devices
  • Invalid state: Matches :invalid pseudo-class and returns typeMismatch validity
<input type="email" id="email" name="email" multiple />

Important Notes:

  • a@b is considered valid (allows intranet addresses)
  • Use the pattern attribute for custom validation

Search Field (type="search")

<label for="search">Enter a search term:</label>
<input type="search" id="search" name="search" />

Key Features:

  • Visual styling: Rounded corners in some browsers
  • Clear icon: Displays a clear button to empty the field when focused with a value
  • Keyboard: Enter key may display "search" or magnifying glass icon
  • Auto-completion: Values saved and reused across site pages

Phone Number Field (type="tel")

<label for="tel">Enter a telephone number:</label>
<input type="tel" id="tel" name="tel" />

Key Features:

  • Mobile keyboards: Displays numeric keypad on touch devices
  • No format enforcement: Allows letters and special characters (accommodates various international formats)
  • Pattern validation: Use pattern attribute to enforce specific formats

URL Field (type="url")

<label for="url">Enter a URL:</label>
<input type="url" id="url" name="url" />

Key Features:

  • Validation requirements: Protocol required (e.g., http:) and proper URL format enforced
  • Mobile keyboards: Displays colon, period, and forward slash by default
  • Note: Well-formed URLs do not guarantee the site exists

Numeric Field (type="number")

<label for="number">Enter a number:</label>
<input type="number" id="number" name="number" />

Attributes:

Attribute Purpose Example
min Minimum value min="1"
max Maximum value max="10"
step Increment/decrement value step="2"

Examples:

Odd numbers between 1-10:

<input type="number" name="age" id="age" min="1" max="10" step="2" />

Decimal values (0-1):

<input type="number" name="change" id="pennies" min="0" max="1" step="0.01" />

Key Features:

  • Spinner buttons: Increase/decrease values
  • Mobile: Numeric keyboard displayed
  • Default step: 1 (only allows integers unless changed)
  • Float numbers: Use step="any" or step="0.01"

Slider Controls (type="range")

<label for="price">Choose a maximum house price:</label>
<input
  type="range"
  name="price"
  id="price"
  min="50000"
  max="500000"
  step="1000"
  value="250000" />
<output class="price-output" for="price"></output>

JavaScript to Display Value:

const price = document.querySelector("#price");
const output = document.querySelector(".price-output");

output.textContent = price.value;

price.addEventListener("input", () => {
  output.textContent = price.value;
});

Key Features:

  • Less precise than text input (best for approximate values)
  • Thumb movement via mouse, touch, or keyboard arrows
  • Use <output> element for displaying current value
  • Configure with min, max, step attributes

Date and Time Pickers

Date (type="date")

<label for="date">Enter the date:</label>
<input type="date" name="date" id="date" />

Captures: Year, month, day (no time).

Date and Time Local (type="datetime-local")

<label for="datetime">Enter the date and time:</label>
<input type="datetime-local" name="datetime" id="datetime" />

Captures: Date and time (no timezone).

Month (type="month")

<label for="month">Enter the month:</label>
<input type="month" name="month" id="month" />

Captures: Month and year.

Time (type="time")

<label for="time">Enter a time:</label>
<input type="time" name="time" id="time" />
  • Display format: 12-hour (in some browsers)
  • Return format: Always 24-hour

Week (type="week")

<label for="week">Enter the week:</label>
<input type="week" name="week" id="week" />
  • Weeks: Monday-Sunday
  • Week 1: Contains first Thursday of the year

Date/Time Constraints

<label for="myDate">When are you available this summer?</label>
<input
  type="date"
  name="myDate"
  min="2025-06-01"
  max="2025-08-31"
  step="7"
  id="myDate" />

Validation Example (CSS)

input:invalid + span::after {
  content: " X";
}

input:valid + span::after {
  content: " checkmark";
}

Color Picker (type="color")

<label for="color">Pick a color:</label>
<input type="color" name="color" id="color" />

Key Features:

  • Opens OS default color-picking functionality
  • Return value: Always lowercase 6-digit hexadecimal (e.g., #ff0000)
  • No manual format entry: System color picker handles selection

Client-Side Validation Notes

Advantages:

  • Immediate user feedback
  • Guides accurate form completion
  • Saves server round trips

Important Limitations:

  • NOT a security measure -- easily disabled by users
  • Server-side validation is always required
  • Prevents only obvious mistakes, not malicious data

HTML5 Input Types Summary

Type Purpose Key Attribute Mobile Keyboard
email Email address multiple @ symbol
search Search queries pattern Standard
tel Phone numbers pattern Numeric
url Web URLs Required protocol :/. symbols
number Numeric values min, max, step Numeric
range Slider selection min, max, step N/A
date Date picker min, max Calendar
time Time picker min, max Clock
color Color picker Default hex Color picker

Other Form Controls

Source: https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Forms/Other_form_controls

Multi-Line Text Fields (<textarea>)

<textarea cols="30" rows="8"></textarea>

Key Characteristics:

  • Allows users to input multiple lines of text
  • Supports hard line breaks (pressing return)
  • Content is placed between opening and closing tags
  • Requires a closing tag (unlike <input>)

Controlling Multi-Line Rendering:

Attribute Description
cols Visible width in average character widths (default: 20)
rows Number of visible text rows (default: 2)
wrap Text wrapping behavior: soft (default), hard, or off

Example with wrapping:

<textarea cols="30" rows="8" wrap="hard"></textarea>

Controlling Resizability (CSS):

textarea {
  resize: both;        /* horizontal and vertical */
  resize: horizontal;  /* horizontal only */
  resize: vertical;    /* vertical only */
  resize: none;        /* no resizing */
}

Drop-Down Controls

Select Box (Single Selection)

<select id="simple" name="simple">
  <option>Banana</option>
  <option selected>Cherry</option>
  <option>Lemon</option>
</select>

With Grouping (<optgroup>):

<select id="groups" name="groups">
  <optgroup label="fruits">
    <option>Banana</option>
    <option selected>Cherry</option>
    <option>Lemon</option>
  </optgroup>
  <optgroup label="vegetables">
    <option>Carrot</option>
    <option>Eggplant</option>
    <option>Potato</option>
  </optgroup>
</select>

With Value Attributes:

<select id="simple" name="simple">
  <option value="banana">Big, beautiful yellow banana</option>
  <option value="cherry">Succulent, juicy cherry</option>
  <option value="lemon">Sharp, powerful lemon</option>
</select>

Attributes:

  • selected -- Sets the default selected option
  • value -- The value sent when form is submitted (if omitted, uses option text)
  • size -- Number of visible options

Multiple Choice Select Box

<select id="multi" name="multi" multiple size="2">
  <optgroup label="fruits">
    <option>Banana</option>
    <option selected>Cherry</option>
    <option>Lemon</option>
  </optgroup>
  <optgroup label="vegetables">
    <option>Carrot</option>
    <option>Eggplant</option>
    <option>Potato</option>
  </optgroup>
</select>

Notes:

  • Add multiple attribute to allow multiple selections
  • Users select via Cmd/Ctrl+click on desktop
  • All values display as a list (not dropdown)

Autocomplete Box (<datalist>)

<label for="myFruit">What's your favorite fruit?</label>
<input type="text" name="myFruit" id="myFruit" list="mySuggestion" />
<datalist id="mySuggestion">
  <option>Apple</option>
  <option>Banana</option>
  <option>Blackberry</option>
  <option>Blueberry</option>
  <option>Lemon</option>
  <option>Lychee</option>
  <option>Peach</option>
  <option>Pear</option>
</datalist>

How It Works:

  • <datalist> provides suggested values
  • Bound to input via list attribute (must match datalist id)
  • Browsers display matching values as user types
  • Works with various input types (text, email, range, color, etc.)

Progress Bar (<progress>)

<progress max="100" value="75">75/100</progress>

Attributes:

  • max -- Maximum value (default: 1.0 if not specified)
  • value -- Current progress value
  • Content inside is fallback for unsupported browsers

Use Cases: Download progress, questionnaire completion, task progress.

Meter (<meter>)

<meter min="0" max="100" value="75" low="33" high="66" optimum="0">75</meter>

Attributes:

  • min / max -- Range boundaries
  • low / high -- Define three ranges (lower, medium, higher)
  • value -- Current meter value
  • optimum -- Preferred value (determines color coding)

Color Coding:

  • Green: Value in preferred range
  • Yellow: Value in average range
  • Red: Value in worst range

Optimum Logic:

  • If optimum in lower range: lower is preferred
  • If optimum in medium range: medium is preferred
  • If optimum in higher range: higher is preferred

Use Cases: Disk space usage, temperature gauge, ratings.

Other Form Controls Summary

Element Purpose Input Type
<textarea> Multi-line text input Text content
<select> Single or multiple selection Predefined options
<datalist> Suggested autocomplete values Text input with suggestions
<progress> Progress indication Read-only display
<meter> Measurement display Read-only display