Falytom logoFALYTOM
Games
ToolsUI ComponentsServicesProductsAbout
LoginSign Up
menu
  1. Home
  2. /Web Development
  3. /Html
  4. /Form Validation
Your Progress0%
0 of 76 completed

HTML Topics

Getting Started

  • What is HTML?
  • How the Web Works
  • Setting Up Your Environment
  • Your First HTML Page

HTML Document Structure

  • The DOCTYPE Declaration
  • The HTML Element
  • The Head Section
  • Meta Tags
  • The Body Element
  • HTML Comments

Text and Formatting

  • Headings (h1-h6)
  • Paragraphs
  • Line Breaks and Horizontal Rules
  • Text Formatting (Bold, Italic, etc.)
  • Quotations and Citations
  • Preformatted Text and Code
  • Subscript and Superscript

Links and Navigation

  • Creating Links
  • Absolute vs Relative URLs
  • Link Targets and Attributes
  • Email and Phone Links
  • Internal Page Links

Images and Media

  • Adding Images
  • Image Attributes
  • Image Formats
  • Figure and Figcaption
  • Responsive Images
  • Audio Elements
  • Video Elements
  • Embedding Content

Lists

  • Unordered Lists
  • Ordered Lists
  • Description Lists
  • Nested Lists

Tables

  • Table Basics
  • Table Headers and Footers
  • Spanning Columns and Rows
  • Table Captions
  • Styling Tables

Forms - Part 1 (Basics)

  • Introduction to Forms
  • Text Input Fields
  • Labels and Placeholders
  • Textarea Element
  • Checkboxes
  • Radio Buttons

Forms - Part 2 (Advanced)

  • Select Dropdowns
  • File Upload Inputs
  • HTML5 Input Types
  • Form Validation
  • Form Buttons
  • Fieldsets and Legends
  • Form Accessibility

Semantic HTML

  • What is Semantic HTML?
  • Header and Footer
  • Nav Element
  • Main and Article
  • Section and Aside
  • Div vs Semantic Elements
  • Time and Mark Elements

HTML5 Features

  • HTML5 Overview
  • Canvas Element
  • SVG in HTML
  • Geolocation API
  • Drag and Drop
  • Local Storage
  • Web Workers

Web Accessibility

  • Introduction to Accessibility
  • ARIA Attributes
  • Keyboard Navigation
  • Alt Text Best Practices
  • Color Contrast and Typography
  • Testing for Accessibility

Best Practices & SEO

  • HTML Best Practices
  • SEO Fundamentals
  • Meta Tags for SEO
  • Structured Data

Form Validation

Required, pattern, and validation attributes

Form validation ensures users enter the correct data before submitting a form. HTML5 provides built-in validation attributes that work without JavaScript, making forms more user-friendly and reducing errors. This improves data quality and user experience.

Why Form Validation Matters

Proper form validation provides several benefits:

  • Prevents incomplete form submissions
  • Catches errors before data reaches the server
  • Provides immediate feedback to users
  • Reduces server load and processing time
  • Improves data quality and accuracy
  • Enhances user experience with clear guidance

The required Attribute

The required attribute makes a field mandatory. Users cannot submit the form until required fields are filled.

required-fields.html
<form>
  <!-- Required text input -->
  <label for="name">Full Name: *</label>
  <input type="text" id="name" name="name" required>
  
  <!-- Required email -->
  <label for="email">Email: *</label>
  <input type="email" id="email" name="email" required>
  
  <!-- Required select -->
  <label for="country">Country: *</label>
  <select id="country" name="country" required>
    <option value="">Select a country</option>
    <option value="us">United States</option>
    <option value="uk">United Kingdom</option>
  </select>
  
  <!-- Required checkbox -->
  <input type="checkbox" id="terms" name="terms" required>
  <label for="terms">I agree to the terms and conditions *</label>
  
  <button type="submit">Submit</button>
</form>

The pattern Attribute

The pattern attribute uses regular expressions to validate input format. It's perfect for enforcing specific formats like phone numbers, postal codes, or custom patterns.

Common Pattern Examples

pattern-examples.html
<!-- US Phone Number: (123) 456-7890 -->
<label for="phone">Phone Number:</label>
<input 
  type="tel" 
  id="phone" 
  name="phone" 
  pattern="([0-9]{3}) [0-9]{3}-[0-9]{4}"
  placeholder="(123) 456-7890"
  title="Format: (123) 456-7890"
>

<!-- US Zip Code: 12345 or 12345-6789 -->
<label for="zip">Zip Code:</label>
<input 
  type="text" 
  id="zip" 
  name="zip" 
  pattern="[0-9]{5}(-[0-9]{4})?"
  placeholder="12345 or 12345-6789"
  title="5 digits or 5+4 format"
>

<!-- Username: 3-16 alphanumeric characters -->
<label for="username">Username:</label>
<input 
  type="text" 
  id="username" 
  name="username" 
  pattern="[a-zA-Z0-9]{3,16}"
  placeholder="username123"
  title="3-16 letters and numbers only"
>

<!-- Alphanumeric only -->
<label for="code">Product Code:</label>
<input 
  type="text" 
  id="code" 
  name="code" 
  pattern="[A-Z0-9]+"
  placeholder="ABC123"
  title="Uppercase letters and numbers only"
>

<!-- Credit Card: 16 digits -->
<label for="card">Credit Card Number:</label>
<input 
  type="text" 
  id="card" 
  name="card" 
  pattern="[0-9]{16}"
  placeholder="1234567890123456"
  title="16 digits"
  maxlength="16"
>

💡 Pro Tip:

Always use the title attribute with pattern to explain the expected format. This message appears when validation fails.

Length Validation

Control the length of text input with minlength and maxlength attributes.

length-validation.html
<!-- Minimum length -->
<label for="password">Password (minimum 8 characters):</label>
<input 
  type="password" 
  id="password" 
  name="password" 
  minlength="8"
  required
>

<!-- Maximum length -->
<label for="username">Username (max 20 characters):</label>
<input 
  type="text" 
  id="username" 
  name="username" 
  maxlength="20"
  required
>

<!-- Both min and max -->
<label for="bio">Bio (50-200 characters):</label>
<textarea 
  id="bio" 
  name="bio" 
  minlength="50"
  maxlength="200"
  rows="4"
></textarea>

Numeric Validation

Use min, max, and step to validate numeric inputs.

numeric-validation.html
<!-- Age validation -->
<label for="age">Age (must be 18 or older):</label>
<input 
  type="number" 
  id="age" 
  name="age" 
  min="18"
  max="120"
  required
>

<!-- Quantity with step -->
<label for="quantity">Quantity (in multiples of 5):</label>
<input 
  type="number" 
  id="quantity" 
  name="quantity" 
  min="5"
  max="100"
  step="5"
  value="5"
>

<!-- Price with decimals -->
<label for="price">Price ($):</label>
<input 
  type="number" 
  id="price" 
  name="price" 
  min="0.01"
  step="0.01"
  placeholder="0.00"
  required
>

<!-- Date range -->
<label for="appointment">Appointment Date:</label>
<input 
  type="date" 
  id="appointment" 
  name="appointment" 
  min="2024-01-01"
  max="2024-12-31"
  required
>

Email and URL Validation

Input types like email and url have built-in format validation.

email-url-validation.html
<!-- Email validation (automatic) -->
<label for="email">Email Address:</label>
<input 
  type="email" 
  id="email" 
  name="email" 
  placeholder="user@example.com"
  required
>

<!-- URL validation (automatic) -->
<label for="website">Website URL:</label>
<input 
  type="url" 
  id="website" 
  name="website" 
  placeholder="https://example.com"
  required
>

<!-- Multiple emails -->
<label for="emails">Email Addresses (comma-separated):</label>
<input 
  type="email" 
  id="emails" 
  name="emails" 
  multiple
  placeholder="email1@example.com, email2@example.com"
>

Custom Validation Messages

Use JavaScript to customize validation messages for better user experience:

custom-messages.html
<form>
  <label for="username">Username:</label>
  <input 
    type="text" 
    id="username" 
    name="username" 
    pattern="[a-zA-Z0-9]{3,16}"
    required
  >
  
  <label for="email">Email:</label>
  <input 
    type="email" 
    id="email" 
    name="email" 
    required
  >
  
  <button type="submit">Submit</button>
</form>

<script>
const username = document.getElementById('username');
const email = document.getElementById('email');

username.addEventListener('invalid', function(e) {
  if (this.validity.valueMissing) {
    this.setCustomValidity('Please enter a username');
  } else if (this.validity.patternMismatch) {
    this.setCustomValidity('Username must be 3-16 characters (letters and numbers only)');
  }
});

username.addEventListener('input', function() {
  this.setCustomValidity(''); // Clear custom message on input
});

email.addEventListener('invalid', function(e) {
  if (this.validity.valueMissing) {
    this.setCustomValidity('Please enter your email address');
  } else if (this.validity.typeMismatch) {
    this.setCustomValidity('Please enter a valid email address');
  }
});

email.addEventListener('input', function() {
  this.setCustomValidity('');
});
</script>

Complete Validated Form Example

complete-validation-form.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Registration Form with Validation</title>
  <style>
    form {
      max-width: 500px;
      margin: 40px auto;
      padding: 30px;
      border: 1px solid #ddd;
      border-radius: 8px;
    }
    
    .form-group {
      margin-bottom: 20px;
    }
    
    label {
      display: block;
      margin-bottom: 5px;
      font-weight: 600;
    }
    
    input, select, textarea {
      width: 100%;
      padding: 10px;
      border: 2px solid #ddd;
      border-radius: 4px;
      font-size: 14px;
    }
    
    input:invalid, select:invalid, textarea:invalid {
      border-color: #ff6b6b;
    }
    
    input:valid, select:valid, textarea:valid {
      border-color: #51cf66;
    }
    
    small {
      display: block;
      margin-top: 5px;
      color: #666;
      font-size: 12px;
    }
    
    .required::after {
      content: " *";
      color: red;
    }
    
    button {
      width: 100%;
      padding: 12px;
      background-color: #4CAF50;
      color: white;
      border: none;
      border-radius: 4px;
      font-size: 16px;
      cursor: pointer;
    }
    
    button:hover {
      background-color: #45a049;
    }
  </style>
</head>
<body>
  <form action="/register" method="post">
    <h2>User Registration</h2>
    
    <div class="form-group">
      <label for="fullname" class="required">Full Name</label>
      <input 
        type="text" 
        id="fullname" 
        name="fullname"
        minlength="3"
        maxlength="50"
        required
      >
      <small>3-50 characters</small>
    </div>
    
    <div class="form-group">
      <label for="username" class="required">Username</label>
      <input 
        type="text" 
        id="username" 
        name="username"
        pattern="[a-zA-Z0-9_]{3,20}"
        title="3-20 characters: letters, numbers, and underscore only"
        required
      >
      <small>3-20 characters (letters, numbers, underscore)</small>
    </div>
    
    <div class="form-group">
      <label for="email" class="required">Email</label>
      <input 
        type="email" 
        id="email" 
        name="email"
        required
      >
    </div>
    
    <div class="form-group">
      <label for="phone">Phone Number</label>
      <input 
        type="tel" 
        id="phone" 
        name="phone"
        pattern="([0-9]{3}) [0-9]{3}-[0-9]{4}"
        placeholder="(123) 456-7890"
        title="Format: (123) 456-7890"
      >
      <small>Optional - Format: (123) 456-7890</small>
    </div>
    
    <div class="form-group">
      <label for="password" class="required">Password</label>
      <input 
        type="password" 
        id="password" 
        name="password"
        minlength="8"
        pattern="(?=.*d)(?=.*[a-z])(?=.*[A-Z]).{8,}"
        title="Must contain at least one number, one uppercase and lowercase letter, and at least 8 characters"
        required
      >
      <small>Min 8 characters with uppercase, lowercase, and number</small>
    </div>
    
    <div class="form-group">
      <label for="age" class="required">Age</label>
      <input 
        type="number" 
        id="age" 
        name="age"
        min="18"
        max="120"
        required
      >
      <small>Must be 18 or older</small>
    </div>
    
    <div class="form-group">
      <label for="country" class="required">Country</label>
      <select id="country" name="country" required>
        <option value="">Select a country</option>
        <option value="us">United States</option>
        <option value="uk">United Kingdom</option>
        <option value="ca">Canada</option>
        <option value="au">Australia</option>
      </select>
    </div>
    
    <div class="form-group">
      <label for="bio">Bio</label>
      <textarea 
        id="bio" 
        name="bio"
        minlength="20"
        maxlength="200"
        rows="4"
      ></textarea>
      <small>Optional - 20-200 characters if provided</small>
    </div>
    
    <div class="form-group">
      <input type="checkbox" id="terms" name="terms" required>
      <label for="terms" class="required">
        I agree to the Terms and Conditions
      </label>
    </div>
    
    <button type="submit">Register</button>
  </form>
</body>
</html>

CSS Validation States

Style inputs based on their validation state using CSS pseudo-classes:

validation-states.css
/* Valid input */
input:valid {
  border-color: #51cf66;
}

/* Invalid input */
input:invalid {
  border-color: #ff6b6b;
}

/* Required but empty */
input:required {
  border-left: 4px solid #ffd43b;
}

/* Optional field */
input:optional {
  border-left: 4px solid #adb5bd;
}

/* In range (for number/date inputs) */
input:in-range {
  border-color: #51cf66;
}

/* Out of range */
input:out-of-range {
  border-color: #ff6b6b;
}

/* Only show validation after user interaction */
input:not(:placeholder-shown):invalid {
  border-color: #ff6b6b;
  background-color: #fff5f5;
}

input:not(:placeholder-shown):valid {
  border-color: #51cf66;
  background-color: #f0fff4;
}

Disabling Validation

Use novalidate on the form or formnovalidate on buttons to skip validation:

novalidate.html
<!-- Disable validation for entire form -->
<form action="/submit" method="post" novalidate>
  <input type="email" required>
  <button type="submit">Submit</button>
</form>

<!-- Multiple buttons with different validation -->
<form action="/submit" method="post">
  <input type="email" name="email" required>
  
  <!-- Submit with validation -->
  <button type="submit">Submit</button>
  
  <!-- Save draft without validation -->
  <button type="submit" formnovalidate formaction="/save-draft">
    Save as Draft
  </button>
</form>

Best Practices

Provide Clear Feedback

Make validation messages helpful and specific:

clear-feedback.html
<!-- Good: Specific guidance -->
<label for="password">Password:</label>
<input 
  type="password" 
  id="password" 
  pattern="(?=.*d)(?=.*[a-z])(?=.*[A-Z]).{8,}"
  title="Password must be at least 8 characters and include uppercase, lowercase, and numbers"
>
<small>Must be 8+ characters with uppercase, lowercase, and number</small>

<!-- Bad: Vague -->
<input type="password" title="Invalid password">

Validate on Both Client and Server

Client-side validation improves user experience but should NEVER be your only validation. Always validate data on the server side for security. Users can bypass client-side validation, so server validation is essential.

Clearly Indicate Required Fields

Mark required fields consistently:

required-indication.html
<style>
  .required::after {
    content: " *";
    color: red;
  }
</style>

<form>
  <label for="name" class="required">Name</label>
  <input type="text" id="name" required>
  
  <label for="email" class="required">Email</label>
  <input type="email" id="email" required>
  
  <label for="phone">Phone (optional)</label>
  <input type="tel" id="phone">
  
  <p><small>* Required fields</small></p>
</form>

Accessibility Considerations

  • Always provide clear labels for all inputs
  • Use the title attribute with pattern for guidance
  • Include helpful hints with <small> or aria-describedby
  • Ensure error messages are announced to screen readers
  • Don't rely solely on color to indicate validation state
  • Make sure validation messages are keyboard accessible
  • Test with screen readers to ensure validation is announced

Key Takeaways

  • Use required to make fields mandatory
  • The pattern attribute validates format with regex
  • minlength and maxlength control text length
  • min, max, and step validate numbers and dates
  • Always include the title attribute with pattern
  • Use CSS pseudo-classes to style validation states
  • Provide clear, helpful validation messages
  • Always validate on both client and server sides

What's Next?

Now that you understand form validation, the next lesson will cover form buttons—including submit, reset, and regular button elements, and how to use them effectively in your forms.

Know someone who'd find this guide helpful? Please share!

Previous
HTML5 Input Types
Next
Form Buttons

Never Miss a New HTML Tutorial

Join 1,000+ developers learning HTML step-by-step. Get new tutorials, tips, and exclusive resources delivered to your inbox - completely FREE.

You might also like

UI Components

Ready-made components for your projects

Developer Tools

Boost productivity with handy generators

HTML Game

Learn HTML concepts through interactive gameplay

Join Our Web Development Training Program

Master frontend & backend development with hands-on projects.

HTML Tutorials

0 of 76 completed

Your Progress0%

Topics

Getting Started

  • What is HTML?
  • How the Web Works
  • Setting Up Your Environment
  • Your First HTML Page

HTML Document Structure

  • The DOCTYPE Declaration
  • The HTML Element
  • The Head Section
  • Meta Tags
  • The Body Element
  • HTML Comments

Text and Formatting

  • Headings (h1-h6)
  • Paragraphs
  • Line Breaks and Horizontal Rules
  • Text Formatting (Bold, Italic, etc.)
  • Quotations and Citations
  • Preformatted Text and Code
  • Subscript and Superscript

Links and Navigation

  • Creating Links
  • Absolute vs Relative URLs
  • Link Targets and Attributes
  • Email and Phone Links
  • Internal Page Links

Images and Media

  • Adding Images
  • Image Attributes
  • Image Formats
  • Figure and Figcaption
  • Responsive Images
  • Audio Elements
  • Video Elements
  • Embedding Content

Lists

  • Unordered Lists
  • Ordered Lists
  • Description Lists
  • Nested Lists

Tables

  • Table Basics
  • Table Headers and Footers
  • Spanning Columns and Rows
  • Table Captions
  • Styling Tables

Forms - Part 1 (Basics)

  • Introduction to Forms
  • Text Input Fields
  • Labels and Placeholders
  • Textarea Element
  • Checkboxes
  • Radio Buttons

Forms - Part 2 (Advanced)

  • Select Dropdowns
  • File Upload Inputs
  • HTML5 Input Types
  • Form Validation
  • Form Buttons
  • Fieldsets and Legends
  • Form Accessibility

Semantic HTML

  • What is Semantic HTML?
  • Header and Footer
  • Nav Element
  • Main and Article
  • Section and Aside
  • Div vs Semantic Elements
  • Time and Mark Elements

HTML5 Features

  • HTML5 Overview
  • Canvas Element
  • SVG in HTML
  • Geolocation API
  • Drag and Drop
  • Local Storage
  • Web Workers

Web Accessibility

  • Introduction to Accessibility
  • ARIA Attributes
  • Keyboard Navigation
  • Alt Text Best Practices
  • Color Contrast and Typography
  • Testing for Accessibility

Best Practices & SEO

  • HTML Best Practices
  • SEO Fundamentals
  • Meta Tags for SEO
  • Structured Data
Falytom logoFALYTOM

Learn technologies like HTML, CSS, JavaScript, React, NodeJS and more through interactive games, tutorials, components and free tools. Transform your businesses with AI chatbots, SEO-optimized websites, and professional development services.

© 2025 Tomilola Group
  • Facebook logo
  • Twitter logo
  • Instagram logo
  • LinkedIn logo
  • GitHub logo
  • YouTube logo