Skip to content
Laviyx Learn

Try

HTML course menu

HTML Form Validation: required, minlength, pattern, min, max and type

Let the browser validate forms without JavaScript: required fields, minlength and maxlength, min, max and step, email and url types, pattern with regular expressions, novalidate, and why the server must validate too.

Intermediate5 min readUpdated
On this page

Browsers can check form fields before the form is submitted and show a message next to the first problem. This is called built-in or constraint validation, and it needs only HTML attributes.

required#

required means the field must not be empty:

HTML
<form action="/join" method="post">
  <p>
    <label for="name">Name</label>
    <input id="name" name="name" required>
  </p>
  <button type="submit">Join</button>
</form>
Result

Press Join with the field empty: the browser stops the submission and shows a message. Fill it in and submit again to see the data that would be sent.

required works on text inputs, checkboxes, radio groups (on any radio in the group), <select> and <textarea>.

Length limits#

HTML
<form action="/username" method="post">
  <label for="user">Username (4 to 12 characters)</label>
  <input id="user" name="user" required minlength="4" maxlength="12">
  <button type="submit">Check</button>
</form>
Result
  • maxlength stops the user typing more characters.
  • minlength shows an error on submit if the value is too short. An empty optional field is not checked; add required too if it must be filled.

Numbers and dates#

HTML
<form action="/order" method="post">
  <label for="qty">Quantity (1 to 5)</label>
  <input type="number" id="qty" name="qty" min="1" max="5" step="1" value="1">
  <button type="submit">Order</button>
</form>
Result

Type 9 or 2.5 and submit: both are rejected, one by max and one by step. min and max also work on date, time and range inputs.

Built-in format checks#

type="email" and type="url" check the format automatically:

HTML
<form action="/contact" method="post">
  <label for="mail">Email</label>
  <input type="email" id="mail" name="mail" required>
  <button type="submit">Send</button>
</form>
Result

Try asha and then asha@example.com. The check is deliberately simple: it confirms the shape of an address, not that the mailbox exists.

pattern#

pattern checks a text field against a regular expression. The whole value must match:

HTML
<form action="/address" method="post">
  <label for="pin">PIN code</label>
  <input id="pin" name="pin" required pattern="[0-9]{6}" inputmode="numeric"
         title="Six digits, for example 500001" aria-describedby="pin-hint">
  <p id="pin-hint">Six digits, for example 500001.</p>
  <button type="submit">Save</button>
</form>
Result
  • [0-9]{6} means "exactly six digits".
  • Browsers add the title text to their error message, but also show the format in visible text, as done here, so everyone sees it before making a mistake.

Styling valid and invalid fields#

CSS can style fields based on their state with the :invalid, :valid and :user-invalid pseudo-classes. :user-invalid only applies after the user has interacted with the field, so the form does not start covered in red. You will learn these in the CSS course.

Turning validation off#

novalidate on the <form> switches off the browser's checks, usually because JavaScript shows custom messages instead:

HTML
<form action="/signup" method="post" novalidate>

A submit button can skip validation for one action with formnovalidate, useful for a "Save draft" button.

Always validate on the server#

Practice#

Practice exercise

Build a registration form where: the name is required; the email is required and must be an email; the age must be a whole number from 18 to 99; and the username is 3 to 15 lowercase letters only ([a-z]{3,15}). Test each rule in the preview.

Show solution
HTML
<form action="/register" method="post">
  <p><label>Name <input name="name" required></label></p>
  <p><label>Email <input type="email" name="email" required></label></p>
  <p><label>Age <input type="number" name="age" min="18" max="99" step="1" required></label></p>
  <p>
    <label>Username <input name="username" required pattern="[a-z]{3,15}"
      title="3 to 15 lowercase letters"></label>
    (3 to 15 lowercase letters)
  </p>
  <button type="submit">Register</button>
</form>
Result

Key takeaway#

Finished this lesson?