HTML5 Fundamentals

Form Validation & Submission

25 min Lesson 12 of 18

Why Validate Forms?

Form validation ensures that users provide correct and complete data before it is sent to the server. Without validation, your application might receive empty fields, improperly formatted emails, or values outside acceptable ranges. HTML5 provides powerful built-in validation that works without any JavaScript, giving users immediate feedback right in the browser. In this lesson, you will learn how to use native HTML validation attributes, style valid and invalid fields with CSS, and understand how form submission works.

The required Attribute

The simplest form of validation is making a field mandatory. When the required attribute is present, the browser will prevent form submission and display an error message if the field is left empty.

Example: Required Fields

<form action="/register" method="POST">
  <label for="name">Full Name:</label>
  <input type="text" id="name" name="name" required>

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

  <label for="age">Age:</label>
  <input type="number" id="age" name="age" required min="18" max="120">

  <button type="submit">Register</button>
</form>

Try submitting this form with empty fields in your browser. The browser will highlight the first invalid field and show a tooltip message. The email type also validates that the value looks like a proper email address. The number type with min and max ensures the value falls within the specified range.

Note: Built-in validation messages are displayed in the user's browser language and cannot be easily styled. For fully custom error messages and styling, you will eventually need JavaScript, but HTML5 validation is an excellent first layer of defense.

Pattern Validation with Regular Expressions

The pattern attribute lets you define a regular expression that the input value must match. This is powerful for enforcing specific formats like phone numbers, postal codes, or usernames.

Example: Pattern-Based Validation

<form action="/profile" method="POST">
  <label for="username">Username (letters and numbers only, 3-16 chars):</label>
  <input type="text" id="username" name="username"
         pattern="[a-zA-Z0-9]{3,16}"
         title="3 to 16 letters or numbers, no spaces or symbols"
         required>

  <label for="phone">Phone (format: 555-123-4567):</label>
  <input type="tel" id="phone" name="phone"
         pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"
         title="Format: 555-123-4567"
         required>

  <label for="zip">US Zip Code:</label>
  <input type="text" id="zip" name="zip"
         pattern="[0-9]{5}(-[0-9]{4})?"
         title="5-digit zip code, optionally followed by dash and 4 digits">

  <button type="submit">Save Profile</button>
</form>

The title attribute provides a human-readable description that browsers include in the validation error message. Always pair pattern with title so users understand the expected format. The pattern is automatically anchored, meaning it must match the entire value, not just a portion of it.

Length and Range Constraints

You can control the minimum and maximum length of text inputs with minlength and maxlength. For numeric inputs, min, max, and step control the acceptable range and increment. These attributes work together with required to create comprehensive validation rules.

Common Mistake: The maxlength attribute silently prevents typing beyond the limit, but minlength only triggers validation on submission. Users might not realize why they cannot submit if there is no visible indication of the minimum length requirement. Always add placeholder text or a label that communicates the requirement.

Styling Valid and Invalid Fields with CSS

CSS provides pseudo-classes that let you visually indicate the validation state of form fields. These styles update automatically as the user types, providing real-time visual feedback.

Example: CSS Validation Pseudo-Classes

<style>
  /* Fields that pass validation */
  input:valid {
    border: 2px solid #27ae60;
  }

  /* Fields that fail validation */
  input:invalid {
    border: 2px solid #e74c3c;
  }

  /* Required fields that are empty */
  input:required {
    border-left: 4px solid #f39c12;
  }

  /* Optional fields */
  input:optional {
    border-left: 4px solid #95a5a6;
  }

  /* Fields currently being edited */
  input:focus:invalid {
    outline: none;
    box-shadow: 0 0 4px #e74c3c;
  }

  input:focus:valid {
    outline: none;
    box-shadow: 0 0 4px #27ae60;
  }
</style>

The :valid and :invalid pseudo-classes apply based on whether the current value satisfies all validation constraints. The :required and :optional pseudo-classes let you differentiate styling based on whether the field is mandatory. Combining these with :focus creates a polished experience where users see validation feedback only while actively editing a field.

Pro Tip: Empty required fields are considered :invalid from the moment the page loads. To avoid showing red borders before the user has interacted with the form, use the :focus:invalid combination or add a class via JavaScript after the first interaction. Some developers also use the :placeholder-shown pseudo-class to detect untouched fields.

Form Submission: GET vs POST

When a form is submitted, the browser sends the data to the URL specified in the action attribute using the HTTP method specified in method. The two methods behave very differently.

Example: GET vs POST Submission

<!-- GET: data appears in the URL as query parameters -->
<form action="/search" method="GET">
  <input type="text" name="q" placeholder="Search...">
  <button type="submit">Search</button>
</form>
<!-- Submitting "html forms" produces: /search?q=html+forms -->

<!-- POST: data is sent in the request body, not visible in URL -->
<form action="/register" method="POST">
  <input type="text" name="username">
  <input type="password" name="password">
  <button type="submit">Register</button>
</form>

<!-- File uploads require POST with enctype -->
<form action="/upload" method="POST" enctype="multipart/form-data">
  <input type="file" name="document">
  <button type="submit">Upload</button>
</form>

Use GET for searches and filters where the URL should be bookmarkable and shareable. Use POST for creating or modifying data, submitting passwords, or any sensitive information. GET requests have URL length limits and expose data in the address bar and browser history. POST sends data in the request body where it is not visible in the URL.

The enctype attribute is critical when uploading files. The default encoding application/x-www-form-urlencoded cannot handle file data. You must use multipart/form-data when your form includes a file input. Without it, the server will receive the filename but not the actual file content.

The novalidate Attribute

Sometimes during development or in certain workflows, you may want to bypass browser validation temporarily. The novalidate attribute on the form element disables all built-in validation, allowing the form to submit regardless of field values. You can also use formnovalidate on a specific submit button to skip validation only for that button while keeping it active for others.

Common Mistake: Never rely solely on client-side validation for security. HTML validation can be bypassed by anyone using browser developer tools or by submitting requests directly. Always validate data on the server side as well. Client-side validation is about user experience, while server-side validation is about security.

Practice Exercise

Create a job application form with the following validated fields: a required full name field with a minimum length of 2 characters, a required email field, a phone number field with a pattern matching your local format, a required URL field for a portfolio website, a number field for years of experience between 0 and 50, a password field requiring at least 8 characters with a pattern that enforces one uppercase letter and one digit, and a file upload for a resume accepting only PDF files. Add CSS styles using the validation pseudo-classes to show green borders for valid fields and red borders for invalid ones. Create two submit buttons: one normal submit and one with formnovalidate labeled "Save Draft". Test the form thoroughly by trying to submit with empty fields, invalid patterns, and out-of-range numbers.

ES
Edrees Salih
20 hours ago

We are still cooking the magic in the way!