HTML
I. HTML Fundamentals
1. Introduction to HTML
2. How the Web Works
3. HTML Document Structure
4. HTML Elements and Tags
5. HTML Attributes
6. Text Formatting Tags
7. Headings and Paragraphs
8. Comments and Whitespace
II. Core HTML Elements
9. Links and Navigation
10. Images and Media
11. Lists in HTML
12. Tables in HTML
13. Forms Overview
14. Input Types
15. Form Validation Basics
16. Buttons and Actions
III. Advanced HTML & Semantics
17. Semantic HTML
18. Layout Elements
19. Audio and Video
20. Iframes and Embeds
21. Meta Tags and SEO
22. Accessibility Basics
23. ARIA Attributes
24. Responsive HTML
IV. Best Practices & Projects
25. HTML Best Practices
26. Clean and Readable HTML
27. HTML Performance Tips
28. HTML Security Basics
29. Browser Compatibility
30. Debugging HTML
31. Mini Project – Portfolio Page
32. Mini Project – Landing Page
33. Mini Project – Form Page
34. Mini Project – Blog Layout
35. HTML Interview Questions
36. HTML Real-World Use Cases
37. HTML Case Study
38. HTML Project Planning
39. HTML Final Project
40. HTML Course Wrap-Up
MINI PROJECT
Mini Project – Form Page
Build Alex's contact page with proper form structure, input validation, and accessible labels
Alex needs a contact page for their portfolio. People should be able to send messages, ask about projects, and share feedback. A well-built form makes the difference between getting real inquiries and scaring visitors away. Forms are where HTML gets serious about user interaction. Every input needs a label. Every field needs proper validation. And the whole thing should work perfectly even if someone uses a screen reader or has JavaScript disabled. Your contact page will handle different types of information — names, emails, messages, and preferences. Each needs the right input type and clear instructions. When someone fills out the form, they should know exactly what to expect.Form Structure Planning
Before writing any code, map out what information you need. Contact forms typically collect: name, email, subject, message, and maybe some preferences. Each piece needs its own input with the right type. Think about the user's journey. They land on your contact page, see a clear form, fill it out without confusion, and submit it successfully. Every field should have a purpose. Every label should be crystal clear.Required Fields
Name, email, message — the absolute minimum for contact
Optional Fields
Subject line, phone number, project type preferences
Input Types
text, email, tel, textarea, select, radio, checkbox
Validation
HTML5 built-in validation plus clear error states
Basic Contact Form
Start with the essential fields. Every form needs aform element that wraps everything. Inside, each input gets paired with a label that describes what to enter.
The for attribute on labels connects to the input's id. When someone clicks the label, it focuses that input automatically. Screen readers use this connection to announce what each field is for.
<!-- Alex's contact form with proper labels and validation -->
<form action="#" method="post">
<!-- Name field with required validation -->
<label for="name">Your Name *</label>
<input type="text" id="name" name="name" required>
<!-- Email with built-in email validation -->
<label for="email">Email Address *</label>
<input type="email" id="email" name="email" required>
<!-- Optional subject line -->
<label for="subject">Subject</label>
<input type="text" id="subject" name="subject">
<!-- Message textarea for longer text -->
<label for="message">Message *</label>
<textarea id="message" name="message" rows="5" required></textarea>
<!-- Submit button -->
<button type="submit">Send Message</button>
</form>localhost/contact.html
What just happened?
The browser created interactive form fields with built-in validation. Try submitting without filling required fields — HTML5 shows error messages automatically. The email field only accepts valid email formats. Try this: Click on any label to see it focus the matching input field.
Advanced Input Types
HTML5 gives you specialized input types that work better on mobile devices and provide automatic validation. Phone inputs show number keypads. Date inputs pop up calendars. URL inputs validate web addresses. Alex's contact form could use a phone field for callbacks and a dropdown for project types. Each input type tells the browser exactly what kind of data to expect.<!-- Enhanced contact form with more input types -->
<form action="#" method="post">
<!-- Basic contact info -->
<label for="fullname">Full Name *</label>
<input type="text" id="fullname" name="fullname" placeholder="Alex Chen" required>
<label for="email">Email *</label>
<input type="email" id="email" name="email" placeholder="alex@example.com" required>
<!-- Phone number with tel input type -->
<label for="phone">Phone Number</label>
<input type="tel" id="phone" name="phone" placeholder="(555) 123-4567">
<!-- Project type dropdown -->
<label for="project-type">Project Type</label>
<select id="project-type" name="project-type">
<option value="">Select a project type</option>
<option value="website">Website Development</option>
<option value="app">Mobile App</option>
<option value="redesign">Website Redesign</option>
<option value="consultation">Consultation</option>
</select>
<!-- Budget range with radio buttons -->
<fieldset>
<legend>Estimated Budget</legend>
<input type="radio" id="budget-small" name="budget" value="small">
<label for="budget-small">Under $5,000</label>
<input type="radio" id="budget-medium" name="budget" value="medium">
<label for="budget-medium">$5,000 - $15,000</label>
<input type="radio" id="budget-large" name="budget" value="large">
<label for="budget-large">Over $15,000</label>
</fieldset>
<label for="message">Project Details *</label>
<textarea id="message" name="message" rows="6" placeholder="Tell me about your project..." required></textarea>
<button type="submit">Send Project Inquiry</button>
</form>localhost/contact.html
What just happened?
The form now collects detailed project information with specialized inputs. The
tel input shows number keyboards on mobile. Radio buttons only allow one budget selection. The fieldset groups related options together. Try this: Select different radio buttons — only one can be active at a time.Form Validation and Accessibility
Good forms prevent problems before they happen. HTML5 validation catches common mistakes — empty required fields, invalid emails, numbers outside allowed ranges. But accessibility matters just as much as validation. Screen readers need proper labels and fieldsets. Error messages should be clear and helpful. Focus indicators should be visible. Someone navigating with just a keyboard should reach every interactive element.Common Accessibility Mistakes
Using placeholder text instead of labels — screen readers can't see placeholders after you start typing. Always use both: labels for accessibility, placeholders for helpful examples.
<!-- Accessible contact form with proper validation -->
<form action="#" method="post" novalidate>
<!-- Name with custom validation message -->
<label for="client-name">Your Name *</label>
<input type="text" id="client-name" name="client-name"
minlength="2" maxlength="50" required
aria-describedby="name-help">
<div id="name-help" class="help-text">Please enter your full name (2-50 characters)</div>
<!-- Email with pattern validation -->
<label for="client-email">Email Address *</label>
<input type="email" id="client-email" name="client-email" required
aria-describedby="email-help">
<div id="email-help" class="help-text">We'll use this to respond to your inquiry</div>
<!-- Optional phone with specific format -->
<label for="client-phone">Phone Number</label>
<input type="tel" id="client-phone" name="client-phone"
pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"
placeholder="123-456-7890"
aria-describedby="phone-help">
<div id="phone-help" class="help-text">Format: 123-456-7890 (optional)</div>
<!-- Timeline with required selection -->
<fieldset>
<legend>Project Timeline *</legend>
<input type="radio" id="timeline-asap" name="timeline" value="asap" required>
<label for="timeline-asap">ASAP (Rush job)</label>
<input type="radio" id="timeline-month" name="timeline" value="month" required>
<label for="timeline-month">Within 1 month</label>
<input type="radio" id="timeline-quarter" name="timeline" value="quarter" required>
<label for="timeline-quarter">Within 3 months</label>
<input type="radio" id="timeline-flexible" name="timeline" value="flexible" required>
<label for="timeline-flexible">Flexible timing</label>
</fieldset>
<!-- Message with character count guidance -->
<label for="project-details">Project Description *</label>
<textarea id="project-details" name="project-details"
minlength="20" maxlength="1000" required
aria-describedby="details-help"></textarea>
<div id="details-help" class="help-text">Describe your project in 20-1000 characters</div>
<!-- Privacy agreement -->
<input type="checkbox" id="privacy-agree" name="privacy-agree" required>
<label for="privacy-agree">I agree to Alex's privacy policy and terms of service *</label>
<button type="submit">Send Project Inquiry</button>
</form>localhost/contact.html
Complete Contact Page Structure
Alex's contact page needs more than just the form. Add a heading that explains the purpose, some reassuring text about response times, and maybe alternative contact methods. The whole page should feel welcoming and professional. Wrap everything in semantic HTML elements. Usemain for the primary content, section elements to group related content, and proper headings to create a logical hierarchy.
header — Page title and navigation
main — Primary contact content
section — Contact form
aside — Alternative contact methods
footer — Copyright and links
<!-- Alex's complete contact.html page structure -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Contact Alex - Portfolio</title>
</head>
<body>
<header>
<h1>Contact Alex</h1>
<nav>
<a href="index.html">Home</a>
<a href="projects.html">Projects</a>
<a href="contact.html">Contact</a>
</nav>
</header>
<main>
<section>
<h2>Let's Work Together</h2>
<p>Have a project in mind? I'd love to hear about it. Fill out the form below and I'll get back to you within 24 hours.</p>
<form action="#" method="post">
<label for="name">Your Name *</label>
<input type="text" id="name" name="name" required>
<label for="email">Email Address *</label>
<input type="email" id="email" name="email" required>
<label for="project">Project Type</label>
<select id="project" name="project">
<option value="">Select a project type</option>
<option value="website">Website Development</option>
<option value="redesign">Website Redesign</option>
<option value="consultation">Consultation</option>
</select>
<label for="message">Message *</label>
<textarea id="message" name="message" rows="6" required></textarea>
<button type="submit">Send Message</button>
</form>
</section>
<aside>
<h3>Other Ways to Reach Me</h3>
<p>Email: alex@example.com</p>
<p>Phone: (555) 123-4567</p>
<p>Location: San Francisco, CA</p>
</aside>
</main>
<footer>
<p>© 2024 Alex Chen. All rights reserved.</p>
</footer>
</body>
</html>localhost/contact.html
Perfect! You've built a complete contact page with proper form structure, semantic HTML, and professional presentation. The form collects all necessary information while providing alternative contact methods for different preferences.
Form Best Practices Summary
Form Best Practices
| Element | Best Practice | Why It Matters |
| Labels | Always use for attribute |
Screen readers and click-to-focus |
| Required Fields | Mark with * and required |
Clear expectations and validation |
| Input Types | Use specific types (email, tel, url) | Mobile keyboards and validation |
| Fieldsets | Group related radio buttons | Logical organization and accessibility |
| Help Text | Use aria-describedby |
Context for complex fields |
Quiz
What does the `for` attribute on a label element do in Alex's contact form?
Why should Alex use `type="email"` instead of `type="text"` for email addresses?
What is the purpose of the `fieldset` element in Alex's budget selection?
Up Next: Mini Project – Blog Layout
Create Alex's blog page with article structure, navigation, and semantic content organization.