~/
hackweb.dev
HTML Forms & Validation
Quiz
⌘K
...
~/
/tutorials
/html/html-forms/edit
~ Contribute
Suggest a correction or improvement. The author reviews it before it goes live.
Loading...
Comment
0 / 300
Typo
Grammar
Broken link
Clarify
Code
en/tutorials/html/6html-forms
Write
Preview
Diff
# HTML Forms & Validation Forms collect user input — from simple text fields to complex multi-step workflows. They're essential for login pages, search bars, contact forms, and more. ## Basic Form Structure Every form uses the `<form>` element: ```html <form action="/submit" method="POST"> <label for="name">Name:</label> <input type="text" id="name" name="name" /> <button type="submit">Submit</button> </form> ``` **Key attributes:** - `action` — URL where form data is sent - `method` — HTTP method (GET or POST) ## Labels Always pair inputs with labels for accessibility: ```html <label for="email">Email</label> <input type="email" id="email" name="email" /> ``` **Why labels matter:** - Clicking the label focuses the input - Screen readers announce the label - Improves touch targets on mobile ## Input Types HTML5 provides many specialized input types: ```html <!-- Text --> <input type="text" name="username" /> <!-- Email (validates format) --> <input type="email" name="email" /> <!-- Password (hides input) --> <input type="password" name="password" /> <!-- Number --> <input type="number" name="age" min="0" max="120" /> <!-- Phone --> <input type="tel" name="phone" /> <!-- URL --> <input type="url" name="website" /> <!-- Date --> <input type="date" name="birthday" /> <!-- Time --> <input type="time" name="appointment" /> <!-- Color --> <input type="color" name="favorite-color" /> <!-- File --> <input type="file" name="avatar" accept="image/*" /> <!-- Range (slider) --> <input type="range" name="volume" min="0" max="100" /> <!-- Search --> <input type="search" name="query" /> ``` ## Textarea For multi-line text input: ```html <label for="message">Message</label> <textarea id="message" name="message" rows="5" cols="40"> Default text here... </textarea> ``` ## Select Dropdown For choosing from a list of options: ```html <label for="country">Country</label> <select id="country" name="country"> <option value="">Select a country</option> <option value="eg">Egypt</option> <option value="sa">Saudi Arabia</option> <option value="ae">UAE</option> </select> ``` ## Checkboxes and Radio Buttons ```html <!-- Checkbox (multiple selections) --> <fieldset> <legend>Interests</legend> <label> <input type="checkbox" name="interests" value="html" /> HTML </label> <label> <input type="checkbox" name="interests" value="css" /> CSS </label> <label> <input type="checkbox" name="interests" value="js" /> JavaScript </label> </fieldset> <!-- Radio button (single selection) --> <fieldset> <legend>Experience Level</legend> <label> <input type="radio" name="level" value="beginner" /> Beginner </label> <label> <input type="radio" name="level" value="intermediate" /> Intermediate </label> <label> <input type="radio" name="level" value="advanced" /> Advanced </label> </fieldset> ``` ## Validation Attributes HTML5 provides built-in validation: ```html <!-- Required field --> <input type="text" name="name" required /> <!-- Minimum/maximum length --> <input type="text" name="username" minlength="3" maxlength="20" /> <!-- Pattern matching (regex) --> <input type="tel" name="phone" pattern="[0-9]{10}" /> <!-- Min/max for numbers --> <input type="number" name="age" min="18" max="120" /> <!-- Email validation --> <input type="email" name="email" required /> <!-- URL validation --> <input type="url" name="website" /> ``` ## Validation Messages Custom validation messages with JavaScript: ```html <form id="myForm"> <label for="email">Email</label> <input type="email" id="email" name="email" required /> <span class="error" aria-live="polite"></span> <button type="submit">Submit</button> </form> <script> const form = document.getElementById('myForm'); const email = document.getElementById('email'); const error = document.querySelector('.error'); email.addEventListener('input', () => { if (email.validity.valid) { error.textContent = ''; } else { error.textContent = getErrorMessage(email); } }); function getErrorMessage(input) { if (input.validity.valueMissing) return 'Email is required'; if (input.validity.typeMismatch) return 'Please enter a valid email'; return ''; } </script> ``` ## Fieldset and Legend Group related form elements: ```html <form> <fieldset> <legend>Personal Information</legend> <label for="name">Name</label> <input type="text" id="name" name="name" required /> <label for="email">Email</label> <input type="email" id="email" name="email" required /> </fieldset> <fieldset> <legend>Preferences</legend> <label> <input type="checkbox" name="newsletter" /> Subscribe to newsletter </label> </fieldset> <button type="submit">Submit</button> </form> ``` ## Complete Example Here's a complete registration form: ```html <form action="/register" method="POST"> <h2>Create Account</h2> <fieldset> <legend>Account Details</legend> <div> <label for="username">Username</label> <input type="text" id="username" name="username" required minlength="3" maxlength="20" pattern="[a-zA-Z0-9_]+" /> <small>3-20 characters, letters, numbers, and underscores only</small> </div> <div> <label for="email">Email</label> <input type="email" id="email" name="email" required /> </div> <div> <label for="password">Password</label> <input type="password" id="password" name="password" required minlength="8" /> <small>At least 8 characters</small> </div> </fieldset> <fieldset> <legend>Profile</legend> <div> <label for="bio">Bio</label> <textarea id="bio" name="bio" rows="4" maxlength="500"></textarea> <small>Max 500 characters</small> </div> <div> <label for="role">Role</label> <select id="role" name="role" required> <option value="">Select a role</option> <option value="student">Student</option> <option value="developer">Developer</option> <option value="designer">Designer</option> </select> </div> </fieldset> <label> <input type="checkbox" name="terms" required /> I agree to the <a href="/terms">Terms of Service</a> </label> <button type="submit">Create Account</button> </form> ``` ## Common Mistakes 1. **Missing labels** — Inputs without labels hurt accessibility 2. **Using placeholder as label** — Placeholder disappears when typing 3. **No validation** — Always validate on both client and server 4. **Missing required attribute** — Let HTML handle basic validation 5. **Not grouping related fields** — Use fieldset for complex forms
No changes yet
Reset to original
Submit suggestion
cancel