Skip to content
Foxipa

Suggest an edit

Tell us what should be corrected, clarified, or improved. Submission will be connected to Foxipa’s contribution service later.

No information is sent anywhere yet. Your suggestion is only prepared in your browser.

Learning

HTML Forms

Learn to build forms people can actually use: labels tied to controls, the right input types, radio groups under fieldsets, and the validation attributes that do real work.

Levels: Beginner ~20 min read

Basic

Forms are where the web stops being a magazine and starts being software, and they are also where most websites quietly fail people. Every label you forget to connect, every control replaced by a styled div, every instruction written only in placeholder text lands directly on the reader trying to give you their address or their money.

Quick check

Complete the HTML with the element that groups controls into a sub-group with an accessible caption.

<form>
  <><legend>Contact</legend>
    <input name="email">
  </fieldset>
</form>

The good news is that usable forms are mostly a matter of letting the built-in elements do their jobs. This lesson covers the structural half of that: labels, controls, and grouping. What happens when the form is submitted belongs to the JavaScript curriculum.

The specification, translated

The HTML Standard uses a few precise categories that are easy to blur together. A control can be form-associated (it can have a form owner), listed (it appears in form.elements), submittable (it can contribute a name/value pair when the form is submitted), and/or resettable (it participates when the form is reset). These are specification categories, not four different kinds of form you need to memorize. The useful author rule is: use the native control for the job, give it a label, give it a meaningful name when its value should be submitted, and let the browser handle its native form behavior.

The label is not optional

Every control needs a label, connected to it by matching the label's for attribute to the control's id. That connection is not decoration: it gives screen readers the control's name, gives voice-input users a word to say, and makes the whole label clickable for everyone with an imprecise pointer, which on a small touchscreen is everyone.

html label.html
1
2
<label for="email">Email address</label>
<input type="email" id="email" name="email">

A label and its control, joined by matching for and id.

A control without a connected label has an accessible name of nothing, and screen readers announce it with just its type: a lonely edit text in a field of them. If you take one habit from this lesson, make it checking that pairing every time you write a control.

Input types earn their keep

The <input> element's type attribute changes both behavior and keyboard. An type="email" gets a keyboard with an at sign on phones and basic format checking for free. type="number" invites stepper buttons and rejects letters. type="date" opens a real calendar instead of making everyone guess your preferred date format. The browser does all of it, no script required.

The input types that carry the most weight in everyday forms.

Type

What the reader gets

Use it for

text

A plain single-line field

Anything without a better type

email

At sign on mobile keyboards, format checking

Email addresses

password

Masked entry, offered to password managers

Passwords

number

Steppers, numeric keyboard on phones

Quantities that are truly numeric

date

A real calendar picker, consistent format

Any calendar date

checkbox

A toggle the reader can operate with one key

Yes or no, terms, options

radio

A group where exactly one is on

Small exclusive choices

Resist type="number" for values that merely look numeric, like card numbers or postcodes. Steppers make no sense there, leading zeros vanish, and paste is a fight. A type="text" with inputmode="numeric" gives phones the right keyboard without the rest of the baggage.

Radio groups and the fieldset

Radio buttons only make sense as a group: same name, different value, exactly one selected. Group them inside a <fieldset> with a <legend>, and the whole question gets a name. Screen readers announce the legend with each radio, so a reader tabbing into the middle of the group still knows which question they are answering.

html radios.html
1
2
3
4
5
6
7
8
9
<fieldset>
  <legend>How should the loaf be sliced?</legend>
  <input type="radio" id="thick" name="slice" value="thick">
  <label for="thick">Thick, for toast</label>
  <input type="radio" id="thin" name="slice" value="thin">
  <label for="thin">Thin, for sandwiches</label>
  <input type="radio" id="whole" name="slice" value="whole">
  <label for="whole">Leave it whole</label>
</fieldset>

One question, three answers, one shared name.

Checkboxes answer a different question. Each one is independent and each needs its own honest label, including the ones that look like a group on screen. A row of toggles without a fieldset is fine; a row of radios without one is a trap for anyone who arrives mid-group.

Textareas, selects, and buttons

The <textarea> holds multi-line text and should always be given rows so its height is honest before any CSS loads. The <select> is a closed list of <option>s; it is the right control when the answers are known and few, and a wrong one when it hides a country list behind two clicks. Its first option should be a real choice or an explicit empty one, never a selected placeholder that pretends to be an answer.

Buttons come from <button>, which submits the form by default, resets it with type="reset", or does neither with type="button". The element takes real text, icons, and focus styling for free, which is why a div with an onclick handler is never an acceptable button no matter how it looks.

Validation the browser will do for you

A handful of attributes turn the browser into a first line of defense. required blocks empty submission. min, max, and pattern describe what valid means. autocomplete lets password managers and autofill do their work, which measurably reduces both typos and abandonment. The messages browsers produce are generic, so treat these attributes as a safety net under your own clearer guidance, not as your only explanation of the rules.

html validated.html
1
2
3
4
5
<label for="loaves">How many loaves?</label>
<input type="number" id="loaves" name="loaves"
       min="1" max="6" required
       autocomplete="off">
<p class="hint">Six is our per-customer maximum on Saturdays.</p>

Required, bounded, and explained in text that never disappears.

Quick check

A radio group has three inputs with the same name. Only the first radio has required. What does the browser require before the form can be submitted?

A form worth filling

The example below is a bakery preorder form using every idea from this lesson. In the preview you can focus fields with labels and Tab, open the date picker, and toggle the radios. Try clicking the word above a field instead of the field itself: the label being clickable is the pairing working. Submission is deliberately left unwired, so the form can be explored safely inside the preview.

Interactive Runnable example
Edit

Ready to run.

Mistakes worth avoiding

  • Placeholder-as-label. The name of the field should survive the first keystroke.

  • Radios without a fieldset and legend. The question disappears for anyone who arrives mid-group, which keyboard users always do.

  • A select for a yes-or-no question. Two radios are faster to operate than any dropdown.

  • Disabling the submit button until the form is perfect. Disabled buttons eat error messages and keyboard focus, and the reader is left guessing which field is still wrong.

  • Styling focus outlines away. The outline is the keyboard reader's cursor; move or restyle it, never remove it.


Quick check

If you can wire a label to a control without looking it up, explain why radios want a fieldset while checkboxes do not, and name two things an input type gets you for free, you have this lesson. When you are ready, take the HTML Forms quiz.

Was this page helpful?

Mark this learning resource complete to track your learning progress.