Skip to content
FormSubmit

HTML

HTML form elements: every input, textarea, select and button explained

A reference to every HTML form element: form, label, input types, textarea, select, button, fieldset, datalist and output, with a complete working example.

7 min readUpdated Oct 9, 2026

HTML form elements are the tags that make up a form: <form> itself, <label>, <input> (with more than 20 types), <textarea>, <select> with <option> and <optgroup>, <button>, <fieldset> with <legend>, <datalist> and <output>. Each field needs a name to be submitted. The form's action decides where the data goes, for example a form backend that emails it to you.

This page is a reference overview. Each section explains one element with a short example and links to a detailed guide. At the end there's a complete form that combines them and actually sends.

How form fields fit together

Every form follows the same pattern. A <form> wraps the fields. Each field has a <label> that says what it's for, and a name that becomes the key in the submitted data. When someone presses the submit button, the browser collects every named, enabled field and sends name=value pairs to the URL in action.

pattern.html
<form action="https://formsubmit.app/f/YOUR_FORM_ID" method="POST">
  <label for="email">Email</label>
  <input id="email" type="email" name="email" required>

  <input type="text" name="_gotcha" tabindex="-1" autocomplete="off" style="display:none">
  <button type="submit">Subscribe</button>
</form>

Three rules cover most "my field isn't arriving" problems:

  • No name, no data. The browser skips fields without a name.
  • Disabled fields aren't sent. Use readonly if you want a value shown, locked and submitted.
  • Unchecked checkboxes and radio buttons aren't sent at all, not even as an empty value.

The form element

<form> holds the fields and controls submission. The attributes that matter are action (where to send), method (GET or POST) and enctype (how to encode, which must be multipart/form-data for file uploads). Add novalidate only if you're replacing the browser's built-in validation with your own.

html
<form action="https://formsubmit.app/f/YOUR_FORM_ID" method="POST">
  ...
</form>

The full detail, including target, formaction and what the browser does on submit, is in HTML form action explained.

Label

<label> gives a field its accessible name and makes the text clickable, which matters most for small targets like checkboxes. Connect it with for pointing at the field's id, or wrap the field inside the label.

html
<label for="name">Full name</label>
<input id="name" type="text" name="name" autocomplete="name">

<label><input type="checkbox" name="newsletter" value="yes"> Send me the newsletter</label>

Placeholder text isn't a substitute. It disappears as soon as someone types and is often low contrast. See accessible web forms for more.

Input and its types

<input> is the workhorse. Its type attribute turns it into a text box, an email field, a date picker, a slider, a checkbox, a file picker and more. The type also decides which keyboard a phone shows and what the browser validates.

html
<input type="text" name="company">
<input type="email" name="email" autocomplete="email">
<input type="tel" name="phone" autocomplete="tel">
<input type="date" name="start_date">
<input type="number" name="guests" min="1" max="10">

There are 22 types in total. The HTML input types guide has a table of every one, with mobile keyboard behaviour and validation attributes such as required, pattern, min, max and minlength.

Textarea

<textarea> is for multi-line text such as a message or a description. Unlike <input>, it has no value attribute: any starting text goes between the tags.

html
<label for="message">Message</label>
<textarea id="message" name="message" rows="5" maxlength="2000" required></textarea>

Sizing, resizing, auto-grow, character counters and how line breaks are submitted are covered in the HTML textarea guide.

Radio buttons

Radio buttons let someone pick exactly one option from a small set. They form a group by sharing the same name, and each one has its own value.

html
<fieldset>
  <legend>Preferred contact method</legend>
  <label><input type="radio" name="contact_method" value="email" checked> Email</label>
  <label><input type="radio" name="contact_method" value="phone"> Phone</label>
</fieldset>

Grouping, yes/no questions, horizontal layouts and reading the selected value in JavaScript are in the HTML radio buttons guide.

Checkboxes

A checkbox is either on or off. Use one on its own for consent, or several with the same name to let people pick any number of options.

html
<fieldset>
  <legend>Interested in</legend>
  <label><input type="checkbox" name="interests" value="design"> Design</label>
  <label><input type="checkbox" name="interests" value="development"> Development</label>
</fieldset>

An unchecked box sends nothing, and a box without a value sends on. The HTML checkbox guide covers both, plus indeterminate and styling.

Select, option and optgroup

<select> shows a dropdown list. Each <option> has a value that is submitted and text that is shown. <optgroup> adds labelled sections to long lists.

html
<label for="budget">Budget</label>
<select id="budget" name="budget" required>
  <option value="" disabled selected hidden>Choose a range</option>
  <option value="under-5k">Under $5,000</option>
  <option value="5k-20k">$5,000 to $20,000</option>
  <option value="over-20k">Over $20,000</option>
</select>

The placeholder pattern above, multiple, size and styling the arrow are in the HTML select dropdown guide.

Datalist

<datalist> offers suggestions for a text input while still allowing free text. Link it with the input's list attribute. Only the input has a name, so only the input's value is submitted.

html
<label for="country">Country</label>
<input id="country" name="country" list="countries" autocomplete="country-name">
<datalist id="countries">
  <option value="United Kingdom"></option>
  <option value="United States"></option>
  <option value="India"></option>
</datalist>

Use it when most people will pick a common answer but some need to type their own. If only listed answers are valid, use <select> instead.

Button

<button> has three types: submit (the default inside a form), reset and button. Always set type explicitly. A <button> with no type inside a form submits it, which surprises people who add a "Show more" button and see the form send.

html
<button type="submit">Send message</button>
<button type="button" id="add-row">Add another</button>

A submit button's name and value are sent only when that button is the one that submitted the form, which lets two buttons share one form. Avoid type="reset": it's rarely wanted and easy to click by mistake.

Fieldset and legend

<fieldset> groups related controls and <legend> gives the group a name. Screen readers announce the legend with each control, which is why radio and checkbox groups should always be wrapped in one. A disabled fieldset disables every control inside it.

html
<fieldset>
  <legend>Billing address</legend>
  <label for="street">Street</label>
  <input id="street" name="street" autocomplete="street-address">
  <label for="postcode">Postcode</label>
  <input id="postcode" name="postcode" autocomplete="postal-code">
</fieldset>

Styling, the min-width quirk and multi-section forms are in the fieldset and legend guide.

Output

<output> shows the result of a calculation or a live value, such as the current position of a range slider. Its for attribute lists the ids of the fields it depends on, and screen readers can announce changes to it. It is not submitted, so if you need the value, copy it into a hidden input as well.

html
<label for="guests">Guests</label>
<input id="guests" type="range" name="guests" min="1" max="20" value="4">
<output id="guests-out" for="guests">4</output>

<script>
  const range = document.getElementById("guests");
  const out = document.getElementById("guests-out");
  range.addEventListener("input", () => { out.value = range.value; });
</script>

Hidden inputs

<input type="hidden"> sends a value the visitor doesn't see, such as the page the form was on. With FormSubmit, hidden fields whose names start with an underscore are control fields: _subject sets the email subject and _redirect sends the visitor to your own thank-you page. The _gotcha honeypot is the exception. It's a text input hidden with CSS, because some bots skip type="hidden" fields but fill in text inputs.

A complete example form

This form uses most of the elements above. It's valid, accessible HTML and works as-is once you replace YOUR_FORM_ID.

project-enquiry.html
<form action="https://formsubmit.app/f/YOUR_FORM_ID" method="POST">
  <input type="hidden" name="_subject" value="New project enquiry">

  <label for="name">Full name</label>
  <input id="name" type="text" name="name" autocomplete="name" required>

  <label for="email">Email</label>
  <input id="email" type="email" name="email" autocomplete="email" required>

  <label for="company">Company (optional)</label>
  <input id="company" type="text" name="company" autocomplete="organization">

  <label for="budget">Budget</label>
  <select id="budget" name="budget" required>
    <option value="" disabled selected hidden>Choose a range</option>
    <option value="under-5k">Under $5,000</option>
    <option value="5k-20k">$5,000 to $20,000</option>
    <option value="over-20k">Over $20,000</option>
  </select>

  <fieldset>
    <legend>Services needed</legend>
    <label><input type="checkbox" name="services" value="design"> Design</label>
    <label><input type="checkbox" name="services" value="development"> Development</label>
    <label><input type="checkbox" name="services" value="seo"> SEO</label>
  </fieldset>

  <fieldset>
    <legend>How should we contact you?</legend>
    <label><input type="radio" name="contact_method" value="email" checked> Email</label>
    <label><input type="radio" name="contact_method" value="phone"> Phone</label>
  </fieldset>

  <label for="start">Ideal start date</label>
  <input id="start" type="date" name="start_date">

  <label for="message">Project details</label>
  <textarea id="message" name="message" rows="6" maxlength="3000" required></textarea>

  <label>
    <input type="checkbox" name="consent" value="yes" required>
    I agree to be contacted about this enquiry
  </label>

  <input type="text" name="_gotcha" tabindex="-1" autocomplete="off" style="display:none">
  <button type="submit">Send enquiry</button>
</form>

A few details worth copying:

  • Every field has a name, and every name is a readable key. FormSubmit uses it as the label in the email, so contact_method shows up as "Contact method".
  • autocomplete values let browsers fill in name, email and company in one tap.
  • The radio group has a sensible default, and the checkbox group has none, so "no services ticked" is a real answer.
  • The required consent checkbox blocks submission until it's ticked.

Make the form actually send

HTML alone can't deliver form data anywhere useful. The action URL needs something on the other end that receives the request. Point it at https://formsubmit.app/f/YOUR_FORM_ID and each submission is spam-filtered, stored in your dashboard and emailed to you, with no server or PHP to maintain.

The step-by-step setup, including subject lines, file attachments and troubleshooting, is in how to send an HTML form to email. If you'd rather start from a ready-made form, see the email form page or build one visually in the form generator.

Frequently asked questions

What are the main HTML form elements?

The form element itself, plus label, input, textarea, select with option and optgroup, button, fieldset with legend, datalist and output. Most fields you build are an input with a specific type attribute.

Which form fields are submitted?

Only fields that have a name attribute, are not disabled and, for checkboxes and radio buttons, are checked. Buttons are submitted only if they have a name and were used to submit the form. The output element is never submitted.

What is the difference between input and textarea?

An input holds a single line of text and its value is set with the value attribute. A textarea holds multiple lines, and its starting value goes between the opening and closing tags.

Do I need a label for every form field?

Yes. A label gives the field an accessible name for screen readers and makes the label text clickable. Use a visible label element tied to the field with for and id, rather than relying on placeholder text.

Can an HTML form send email on its own?

No. A form can only send its data to a URL. Point the action at a hosted form backend such as FormSubmit and it receives the data, filters spam and emails it to you.

Keep reading

Your form backend is 60 seconds away

Sign up with Google or email, create a form, paste the endpoint. Free forever for small sites — no credit card.