HTML Forms Table

Element / attributePurposeKey attributes
<form>Container; owns submit and the action/method pairaction, method, novalidate
<label>Caption bound to a control - click it to focusfor (must match the control id)
<input>The workhorse - type switches its personalitytype, name, required, value, placeholder
<textarea>Multi-line textrows, cols, maxlength
<select> / <option>Dropdown; option list insidemultiple, size, selected
<optgroup>Grouped options inside a selectlabel
<datalist>Suggested values for a text inputid (linked by input list attribute)
<fieldset> / <legend>Grouped controls with a captiondisabled (disables the whole group)
<button>Clickable action - type switches behaviortype=submit|reset|button
<output>Result of a calculationfor (the inputs it reflects)
<progress>Task completion barvalue, max
<meter>Scalar gauge within a known rangevalue, min, max, low, high, optimum
requiredNative mandatory validationBoolean attribute on input/select/textarea
pattern / minlength / maxlengthNative format and length validationpattern takes a regex; CSS :invalid styles the state
Every row is native HTML - no JavaScript until you want custom messages. Reference: the MDN forms guide. The two rules that fix most forms: every input needs a <label for> (placeholder text is not a label - it vanishes on first keystroke and screen readers skim past it), and every input needs a name (unnamed fields are silently dropped from the submission). Native validation (required, pattern, type=email) runs before your submit handler - let it. Related tools: HTML attributes table, semantic elements table, HTML entities table, and escape html for the user content that comes back out of forms.

HTML forms have quietly become excellent: native validation, accessible grouping, keyboard handling and mobile keyboard hints all ship with the platform - no JavaScript required until you want custom error messages. The table below is the working set: the elements, the validation attributes, and the pairing rules that make them behave.

Bottom line: two rules fix most forms before any code is written. Every input needs a real label - a &lt;label for&gt; bound to the control's id, because placeholder text disappears on the first keystroke and screen readers treat it as a hint, not a name. And every input needs a name attribute - unnamed fields are silently dropped from the submission, which is the classic "the field was there but the email never contained it" bug.

The honest part: native validation runs before your submit handler and it is better than most hand-rolled JavaScript - required, type=email, pattern, minlength all produce browser-localized messages for free. The catch: it only validates what the attributes say, so a type=text field with a pattern is fine, but a custom rule (password strength, username availability) is where JavaScript earns its place.

How to use

  1. Find the element or attribute in the table - the first column is the exact tag or attribute name to type.
  2. Check the key-attributes column for the pairing rule: label for matches input id, datalist links by list attribute, output for names its inputs.
  3. Start native: required, pattern and the right input type cover most validation - add JavaScript only for custom rules and messages.

Frequently asked questions

How does native HTML validation work?

Attributes, not scripts: required rejects empty values, type=email and type=url check format, pattern takes a regular expression, min/max/length bound the value. The browser blocks submission and shows a localized message when a constraint fails - before any JavaScript runs. Style the states with CSS pseudo-classes (:invalid, :valid, :required) and read validity in JS through the element's validity object when you need custom messages.

What is the difference between placeholder and label?

A label is the field's name - always visible, bound with for=id, read aloud by screen readers, click-to-focus. A placeholder is a hint inside the empty field - it disappears on the first keystroke, its contrast is usually too low, and screen readers treat it as supplementary. Replacing labels with placeholders is the most common form accessibility failure; the fix is one line: <label for="email">Email</label> in front of the input.

Why is the name attribute required on form fields?

The submission format is name=value pairs - an input without a name has nothing to submit under, so the browser drops it silently. Everything works on screen and the backend never receives the field, which makes this the most confusing silent failure in HTML. Checkboxes are the special case: an unchecked checkbox submits nothing at all, which is why servers treat its absence as false.

When should a button be type="button"?

The default button type inside a form is submit - a plain <button> in a form sends the form, which surprises everyone exactly once. type="button" opts out of submission for click-handled actions (show a picker, copy text); type="reset" clears the form. The rule of thumb: buttons that save or send data keep the default submit so Enter works; buttons that do something else on the page declare type="button" explicitly.

Related tools