Complete HTML Course Module 7: Intermediate: HTML Forms

HTML Form Validation Without JavaScript

  • Beginner
  • Lesson 7.7
  • 4 min read
  • 36 of 69 in the course

In short

HTML form validation lets the browser check user input before sending it, using attributes like required, minlength, min, max, pattern and input types. No JavaScript needed. What is form validation? Validation means checking that data is correct before you accept it. Is the email really an email?

HTML form validation lets the browser check user input before sending it, using attributes like required, minlength, min, max, pattern and input types. No JavaScript needed.

What is form validation?

Validation means checking that data is correct before you accept it. Is the email really an email? Is the required field filled in? Think of a ticket checker at a concert door: no ticket, no entry.

Modern browsers can do a lot of validation using only HTML attributes. When a user clicks submit, the browser checks every field. If something is wrong, it stops the form, highlights the first problem and shows a message in the user's language.

Required fields, length limits and number ranges

  • required means the field cannot be empty.
  • minlength sets the fewest characters allowed.
  • maxlength sets the most characters allowed. The browser simply stops the user typing more.

min, max and step for numbers and dates

For number, range, date and time inputs:

  • min is the lowest allowed value.
  • max is the highest allowed value.
  • step sets the allowed jumps. step="5" allows 0, 5, 10 and so on. step="0.01" allows prices with pennies.

Input types also validate. type="email" needs a valid email shape, and type="url" needs a full address like https://example.com.

<form action="/signup" method="post">
  <p>
    <label for="username">Username (4–20 characters)</label><br>
    <input type="text" id="username" name="username" required minlength="4" maxlength="20" autocomplete="username">
  </p>
  <p>
    <label for="email">Email</label><br>
    <input type="email" id="email" name="email" required autocomplete="email">
  </p>
  <p>
    <label for="new-password">Password (at least 8 characters)</label><br>
    <input type="password" id="new-password" name="password" required minlength="8" autocomplete="new-password">
  </p>
  <p>
    <label for="age">Age</label><br>
    <input type="number" id="age" name="age" min="16" max="120" step="1">
  </p>
  <p>
    <input type="checkbox" id="terms" name="terms" value="yes" required>
    <label for="terms">I agree to the terms</label>
  </p>
  <p>
    <button type="submit">Sign up</button>
  </p>
</form>

Click "Sign up" with empty fields: the browser stops you and points to the username. Type "abc" and it asks for at least 4 characters. An age of 12 is refused because min="16". The form only sends when every rule passes, including the ticked terms box.

Checking a format with the pattern attribute

The pattern attribute checks text against a regular expression, a small code that describes a text shape. The whole value must match. Some simple examples:

  • [0-9]{5} means exactly five digits, like a US ZIP code.
  • [A-Za-z]{3}[0-9]{4} means three letters then four digits, like an order code "ABC1234".

Always explain the expected format in the label or a hint, because the browser's error message for pattern is very general. Adding a title attribute helps some browsers show your explanation in the message.

<form action="/track-order" method="get">
  <p>
    <label for="order-code">Order code</label><br>
    <span id="order-hint">3 letters then 4 numbers, for example ABC1234</span><br>
    <input type="text" id="order-code" name="code" required pattern="[A-Za-z]{3}[0-9]{4}" title="3 letters then 4 numbers" aria-describedby="order-hint" placeholder="ABC1234">
  </p>
  <p>
    <label for="zip">ZIP code</label><br>
    <input type="text" id="zip" name="zip" inputmode="numeric" pattern="[0-9]{5}" autocomplete="postal-code">
  </p>
  <p>
    <button type="submit">Track my order</button>
  </p>
</form>

If you type "AB12" as the order code, the browser refuses it. "ABC1234" passes. The hint text is connected to the field with aria-describedby, so screen readers read it too. The ZIP field shows a number keyboard on phones.

Placeholder vs label, and autocomplete

A placeholder is grey example text inside the field. It disappears when the user starts typing. It is not a replacement for a label: once it is gone, users forget what the field was for, and the light grey text is hard to read. Use a label always, and use a placeholder only for a short example.

The autocomplete attribute tells the browser what kind of data a field holds, so it can fill it in from saved details. This saves users a lot of typing. Common values: name, email, tel, street-address, postal-code, country, username, current-password (for logins), new-password (for sign-ups) and one-time-code (for SMS codes).

Common mistake: Using only a placeholder like "Email" with no label. It fails accessibility checks and confuses users. Always add a real <label>.

Turning validation off with novalidate

Add novalidate to the <form> to turn off the browser's checks. Developers do this when they write their own validation messages with JavaScript. The attributes like required still describe the rules; the browser just doesn't block the submit.

Note: HTML validation is for the user's comfort, not for security. Anyone can remove the attributes in the browser's developer tools or send data directly to your server. Always validate again on the server. Read more on MDN: Client-side form validation.

Practice exercise

Add validation to a "Book a lesson" form: the name is required (at least 2 characters), the email is required, the number of lessons must be between 1 and 10, and a lesson code must match two letters and two numbers, like "GT01". Add correct autocomplete values.

Hint: The lesson code pattern is [A-Za-z]{2}[0-9]{2}. Test each rule by entering wrong values and clicking submit.

Key takeaways

  • The browser can check forms with attributes like required, minlength, maxlength, min, max and step.
  • Input types such as email and url validate the format for you.
  • Use pattern for custom formats, and always describe the format to the user.
  • A placeholder never replaces a label; autocomplete helps users fill forms quickly.
  • Client-side validation is not security: always validate on the server too.