W3docs

HTML Forms

Learn HTML forms: the form element, action and method (GET vs POST), labels, inputs, textarea, select, buttons, and HTML5 validation.

An HTML form collects user input and sends it to a server for processing. A form is a container — the <form> element — that holds one or more controls such as text fields, checkboxes, radio buttons, drop-down lists, and submit buttons. This page covers the <form> element itself, the controls you put inside it, how data is sent (GET vs POST), and how to label and validate input.

The <form> element

Every form starts with the <form> tag. The controls a user fills in live between the opening <form> and closing </form> tags. Two attributes do most of the work:

  • action — the URL that receives the form data when the user submits.
  • method — the HTTP method used to send the data, either GET or POST.
<form action="/subscribe" method="POST">
  <!-- form controls go here -->
  <button type="submit">Subscribe</button>
</form>

If you omit action, the form submits back to the current page's URL. If you omit method, the browser uses GET by default.

Labeling controls

Every input should have a <label>. Connect the label to its control by giving the control an id and pointing the label's for attribute at that same id:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <h2>Text Input Example</h2>
    <form>
      <label for="name">Name:</label>
      <input type="text" id="name" name="name" />

      <label for="surname">Surname:</label>
      <input type="text" id="surname" name="surname" />
    </form>
  </body>
</html>
Info

Use a real <label> instead of plain text like Name:<br />. A connected label is read aloud by screen readers and makes the clickable area bigger, so tapping the label focuses the field. See more in the HTML <label> tag chapter.

The HTML <input> element

The <input> element is the most common form control. Its type attribute changes how it looks and behaves — text, email, password, number, checkbox, radio, file, submit, and many more.

Let’s look at some of the input types.

Text input

<input type="text"> creates a single-line text field. The name attribute is the key sent to the server with the field's value.

Example of the text input:

<form>
  <label for="username">Username:</label>
  <input type="text" id="username" name="username" />
</form>

Radio button input

<input type="radio"> lets the user pick exactly one option from a set. Radio buttons share the same name, so selecting one clears the others in that group.

Example of the radio button input:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <h2>Radio Button Example</h2>
    <form>
      <input type="radio" id="football" name="game" value="football" checked />
      <label for="football">Football</label>

      <input type="radio" id="basketball" name="game" value="basketball" />
      <label for="basketball">Basketball</label>
    </form>
  </body>
</html>

Submit input

<input type="submit"> (or a <button type="submit">) sends the form data to the form handler — the server URL named in the form's action attribute.

Example of the submit input:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <h2>HTML Form Example</h2>
    <form action="/form/submit" method="POST">
      <label for="firstname">Name:</label>
      <input type="text" id="firstname" name="firstname" value="Tom" />

      <label for="lastname">Surname:</label>
      <input type="text" id="lastname" name="lastname" value="Brown" />

      <label for="age">Age:</label>
      <input type="number" id="age" name="age" value="21" />

      <input type="submit" value="Submit" />
    </form>
    <p>Click the Submit button to send the form data to the action page.</p>
  </body>
</html>

Other form controls

Inputs are not the only controls. These elements give you multi-line text, drop-downs, custom buttons, and a way to group related fields.

Multi-line text with <textarea>

Use <textarea> for longer text such as comments or messages. Unlike <input>, it has separate opening and closing tags, and rows/cols set its visible size.

<form>
  <label for="message">Your message:</label>
  <textarea id="message" name="message" rows="4" cols="40"></textarea>
</form>

A <select> element creates a drop-down list. Each choice is an <option>; the value is what gets submitted, and selected sets the default.

<form>
  <label for="country">Country:</label>
  <select id="country" name="country">
    <option value="us">United States</option>
    <option value="uk" selected>United Kingdom</option>
    <option value="ca">Canada</option>
  </select>
</form>

The <button> element

The <button> element is more flexible than <input type="submit"> because it can contain HTML (text, icons). Always set its type: submit sends the form, reset clears it, and button does nothing on its own (use it with JavaScript).

<form>
  <button type="submit">Send</button>
  <button type="reset">Clear</button>
</form>

Grouping with <fieldset> and <legend>

Wrap related controls in a <fieldset> and describe the group with a <legend>. This draws a labeled border and helps screen-reader users understand how fields relate — useful for things like an address block or a set of radio buttons.

<form>
  <fieldset>
    <legend>Contact details</legend>

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

    <label for="phone">Phone:</label>
    <input type="tel" id="phone" name="phone" />
  </fieldset>
</form>

The action attribute

The action attribute specifies the URL where the form data is sent when the form is submitted. When the user clicks the submit button, the browser packages the controls' values and sends them to that URL.

<form action="/form/submit">

The target attribute

The target attribute defines where the form result opens — in a new browser tab, a frame, or the current window.

  • _self (default) opens the result in the current window.
  • _blank opens the result in a new browser tab.
<form action="/form/submit" target="_blank">

The method attribute

The method attribute defines the HTTP method — GET or POST — used to send the form data. The choice affects where the data goes and what the request means.

Example of the GET method:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <h2>The method Attribute With the GET Method</h2>
    <form action="/form/submit" method="GET">
      <label for="g-name">Name:</label>
      <input type="text" id="g-name" name="name" value="Tom" />

      <label for="g-surname">Surname:</label>
      <input type="text" id="g-surname" name="surname" value="Brown" />

      <label for="g-age">Age:</label>
      <input type="number" id="g-age" name="age" value="21" />

      <input type="submit" value="Submit" />
    </form>
  </body>
</html>

After submitting, the data appears in the URL's query string, like /form/submit?name=Tom&surname=Brown&age=21.

Example of the POST method:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <h2>The method Attribute With the Post Method</h2>
    <form action="/form/submit" method="POST">
      <label for="p-name">Name:</label>
      <input type="text" id="p-name" name="name" value="Tom" />

      <label for="p-surname">Surname:</label>
      <input type="text" id="p-surname" name="surname" value="Brown" />

      <label for="p-age">Age:</label>
      <input type="number" id="p-age" name="age" value="21" />

      <input type="submit" value="Submit" />
    </form>
  </body>
</html>

With POST, the data travels in the request body, so it does not show up in the URL.

GET vs POST

The two methods send data differently and signal different intentions to the server.

GET appends the form data to the URL as a query string:

  • The data is visible in the address bar and can be bookmarked or shared.
  • URLs have a length limit (commonly around 2048 characters), so GET is not suited for large amounts of data.
  • GET is idempotent — repeating the same request should not change anything on the server. Use it for searches and filters that only read data.
Danger

Don’t use GET to send passwords or other sensitive data — it ends up visible in the URL, browser history, and server logs.

POST sends the data in the request body:

  • The data is not shown in the URL, and there is no practical size limit, so POST handles large payloads and file uploads.
  • POST submissions can’t be bookmarked.
  • POST is meant for requests that change server state (creating an account, posting a comment, placing an order).
Tip

Rule of thumb: use GET to read or look something up, and POST to create or change something.

Validating user input

HTML5 can check input in the browser before the form is submitted — no JavaScript required. Add these attributes to your controls:

AttributeWhat it does
requiredThe field must be filled in before the form can submit.
minlength / maxlengthMinimum / maximum number of characters for text fields.
min / maxSmallest / largest allowed value for numbers, ranges, and dates.
patternA regular expression the value must match.
typeSome types validate format automatically: email, url, number, tel.
<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <h2>Form Validation Example</h2>
    <form action="/form/submit" method="POST">
      <label for="user">Username (3–12 letters):</label>
      <input type="text" id="user" name="user"
             required minlength="3" maxlength="12" pattern="[A-Za-z]+" />

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

      <label for="qty">Quantity (1–10):</label>
      <input type="number" id="qty" name="qty" min="1" max="10" />

      <input type="submit" value="Submit" />
    </form>
  </body>
</html>

If a value fails a rule, the browser blocks submission and shows a message. To turn off this built-in checking, add the novalidate attribute to the <form>.

The enctype attribute

The enctype attribute sets how form data is encoded when sent with POST:

  • application/x-www-form-urlencoded — the default; field names and values are URL-encoded. Fine for ordinary text forms.
  • multipart/form-data — required when the form contains a file upload (<input type="file">), so the file's binary data is sent correctly.
<form action="/upload" method="POST" enctype="multipart/form-data">
  <label for="photo">Profile photo:</label>
  <input type="file" id="photo" name="photo" />
  <button type="submit">Upload</button>
</form>

Other attributes

Below are other useful <form> attributes:

AttributeDescription
accept-charsetThe character set used in the submitted form (default: the page charset).
autocompleteWhether the browser may autofill the form (default: on).
enctypeHow the submitted data is encoded (default: application/x-www-form-urlencoded).
nameA name used to identify the form.
novalidateTells the browser not to validate the form on submit.

Practice

Practice
Which attribute does an input need so its value is included when the form is submitted to the server?
Which attribute does an input need so its value is included when the form is submitted to the server?
Practice
Which HTTP method should you use to send a password, and why?
Which HTTP method should you use to send a password, and why?
Was this page helpful?