Home HTML Intermediate Lesson 9 — HTML Best Practices

1. Introduction

You have now learned all the fundamental and intermediate HTML topics. This final lesson consolidates everything into a set of best practices — habits that professional developers follow on every project.

Writing HTML that simply works is not enough. Professional HTML should be readable, maintainable, accessible, performant, and semantic. These practices will make you a better developer and make working in teams much easier.

2. Theory — The Complete Best Practices List

1. Always Start with a Valid Boilerplate

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Descriptive Page Title</title>
</head>
<body>
  <!-- content -->
</body>
</html>

Use Emmet in VS Code: type ! and press Tab to generate this automatically.

2. Write Lowercase Tag and Attribute Names

<!-- ❌ Wrong -->
<DIV CLASS="container"><P>Text</P></DIV>

<!-- ✅ Right -->
<div class="container"><p>Text</p></div>

3. Quote All Attribute Values

<!-- ❌ Wrong (works but poor practice) -->
<img src=photo.jpg alt=My photo>

<!-- ✅ Right -->
<img src="photo.jpg" alt="My photo">

4. Close All Tags

<!-- ❌ Wrong -->
<p>Paragraph 1
<p>Paragraph 2

<!-- ✅ Right -->
<p>Paragraph 1</p>
<p>Paragraph 2</p>

Void elements (<img>, <br>, <input>) are self-closing and do not need a closing tag.

5. Use Proper Indentation

<!-- ❌ Wrong -- hard to read -->
<ul><li>Item 1</li><li>Item 2</li></ul>

<!-- ✅ Right -- clean hierarchy -->
<ul>
  <li>Item 1</li>
  <li>Item 2</li>
</ul>

Use 2 spaces per level. VS Code auto-formats with Alt+Shift+F.

6. Use Semantic Elements

<!-- ❌ Wrong -- divs everywhere -->
<div class="header">
  <div class="nav">...</div>
</div>

<!-- ✅ Right -- meaningful elements -->
<header>
  <nav>...</nav>
</header>

7. Separate HTML, CSS, and JavaScript

<!-- ❌ Wrong -- styles inline -->
<p style="color: red; font-size: 18px;">Text</p>

<!-- ❌ Wrong -- script inline -->
<button onclick="alert('Hello')">Click</button>

<!-- ✅ Right -- external files -->
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>

Inline styles and scripts make code harder to maintain and violate the separation of concerns principle.

8. Always Use Alt Text on Images

<!-- ❌ Missing alt -->
<img src="logo.png">

<!-- ✅ Descriptive alt -->
<img src="logo.png" alt="Acme Corp company logo">

<!-- ✅ Empty alt for decorative images -->
<img src="divider.png" alt="">

9. Name Things Meaningfully

<!-- ❌ Meaningless IDs -->
<div id="div1">
<input id="i1">

<!-- ✅ Descriptive IDs and names -->
<div id="newsletter-signup">
<input id="email-input" name="email">

10. Validate Your HTML

Always check your HTML using the W3C Validator at validator.w3.org. It catches errors like unclosed tags, missing required attributes, and invalid nesting that browsers silently "fix" — often in unexpected ways.

11. Optimise Images

<!-- Always set width/height -->
<img src="photo.webp" alt="Description" width="800" height="600">

<!-- Lazy load below-fold images -->
<img src="far-down.webp" alt="Description" loading="lazy" width="600" height="400">

<!-- Use modern formats -->
<picture>
  <source srcset="photo.avif" type="image/avif">
  <source srcset="photo.webp" type="image/webp">
  <img src="photo.jpg" alt="Description" width="800" height="600">
</picture>

12. Use Comments Sparingly

<!-- ✅ Useful comment: marks a major section -->
<!-- ===== HERO SECTION ===== -->
<section class="hero">...</section>

<!-- ❌ Unnecessary comment (code is self-explanatory) -->
<!-- This is a paragraph -->
<p>Lorem ipsum...</p>

13. Test in Multiple Browsers

Always test in Chrome, Firefox, and Safari (Edge is Chrome-based so similar). Pay particular attention to form inputs, which render differently across browsers.

3. Real World Example

Open any large company's website and view source (Ctrl+U). You will see: properly indented HTML, semantic elements, descriptive class names, external CSS/JS files, meta tags for SEO, and no inline styles. These are not just suggestions — they are the professional standard.

4. Code Example — Professional HTML Page

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="description" content="Professional freelance web developer portfolio.">
  <title>Jane Smith — Frontend Developer Portfolio</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>

  <!-- Skip link for accessibility -->
  <a href="#main" class="skip-link">Skip to main content</a>

  <!-- ===== HEADER ===== -->
  <header>
    <a href="/" aria-label="Jane Smith — Home">
      <img src="logo.svg" alt="Jane Smith logo" width="120" height="40">
    </a>
    <nav aria-label="Primary navigation">
      <ul>
        <li><a href="#about">About</a></li>
        <li><a href="#work">Work</a></li>
        <li><a href="#contact">Contact</a></li>
      </ul>
    </nav>
  </header>

  <!-- ===== MAIN CONTENT ===== -->
  <main id="main">

    <section id="about" aria-labelledby="about-heading">
      <h1 id="about-heading">Hi, I'm Jane — Frontend Developer</h1>
      <p>I build fast, accessible, and beautiful web experiences.</p>
    </section>

    <section id="work" aria-labelledby="work-heading">
      <h2 id="work-heading">Selected Work</h2>
      <ul>
        <li>
          <article>
            <h3>E-Commerce Redesign</h3>
            <img
              src="images/project-ecommerce.webp"
              alt="E-commerce product page redesign — dark theme, product grid layout"
              width="600"
              height="400"
              loading="lazy">
            <p>Redesigned a fashion retailer's product pages, increasing conversions by 23%.</p>
            <a href="/case-study/ecommerce">View case study</a>
          </article>
        </li>
      </ul>
    </section>

    <section id="contact" aria-labelledby="contact-heading">
      <h2 id="contact-heading">Get In Touch</h2>
      <form action="/contact" method="POST" novalidate>
        <label for="contact-name">Name</label>
        <input type="text" id="contact-name" name="name" required autocomplete="name">

        <label for="contact-email">Email</label>
        <input type="email" id="contact-email" name="email" required autocomplete="email">

        <label for="contact-message">Message</label>
        <textarea id="contact-message" name="message" rows="5" required></textarea>

        <button type="submit">Send Message</button>
      </form>
    </section>

  </main>

  <!-- ===== FOOTER ===== -->
  <footer>
    <p>&copy; <time datetime="2024">2024</time> Jane Smith. All rights reserved.</p>
    <nav aria-label="Social media links">
      <a href="https://github.com/janesmith" target="_blank" rel="noopener noreferrer" aria-label="Jane Smith on GitHub">GitHub</a>
      <a href="https://linkedin.com/in/janesmith" target="_blank" rel="noopener noreferrer" aria-label="Jane Smith on LinkedIn">LinkedIn</a>
    </nav>
  </footer>

  <script src="script.js"></script>
</body>
</html>

5. Code Breakdown

Practice DemonstratedWhere in the Example
Valid boilerplateDOCTYPE, html lang, charset, viewport, title
Skip linkFirst element, links to id="main"
Semantic structureheader, nav, main, section, article, footer
ARIA labelsaria-label on nav, aria-labelledby on sections
Descriptive IDsabout, work, contact, about-heading, etc.
Alt textOn logo and project image with meaningful descriptions
Lazy loadingloading="lazy" on below-fold project image
Image dimensionswidth and height on every img
Form labelsEvery input linked to a label via for/id
Autocompleteautocomplete="name" and "email" for better UX
External JSscript at end of body
Security on external linksrel="noopener noreferrer" on all target="_blank"

6. Common Mistakes

Mistake 1 — Inline styles and scripts everywhere

Maintainability nightmare. Making a colour change requires finding every inline style. Always use external CSS and JS files.

Mistake 2 — Never validating HTML

Run your HTML through validator.w3.org. Invalid HTML can render differently across browsers and cause subtle bugs that are hard to track down.

Mistake 3 — Using presentation-only elements

Elements like <center>, <font>, <b>, and <i> are considered poor practice. Use CSS for presentation, semantic elements (<strong>, <em>) for meaning.

7. Best Practices Summary

1. Always use a valid boilerplate — DOCTYPE, html lang, charset, viewport, title.
2. Write lowercase tags and attributes. Quote all values.
3. Close all tags. Indent consistently (2 spaces).
4. Use semantic HTML — header, nav, main, section, article, footer.
5. Separate HTML, CSS, and JavaScript into different files.
6. Alt text on every image. Captions on every video.
7. Label every form input. Test keyboard navigation.
8. Optimise images — WebP format, width/height, lazy loading.
9. Use descriptive IDs, names, and class names.
10. Validate at validator.w3.org before deploying.

8. Practice Exercise

Audit your best HTML page so far using this checklist. For each item, mark ✅ or ❌:

  • [ ] Valid DOCTYPE and boilerplate
  • [ ] Lowercase tags and quoted attributes
  • [ ] Consistent 2-space indentation
  • [ ] Semantic elements (no divs where header/main/footer would work)
  • [ ] External CSS (no inline styles)
  • [ ] All images have alt text
  • [ ] All form inputs have labels
  • [ ] External links have rel="noopener noreferrer"
  • [ ] Page passes W3C validator with no errors
  • [ ] Lighthouse Accessibility score ≥ 90

Fix every ❌ item.

9. Assignment — HTML Capstone Project

Build a complete professional portfolio page applying every best practice from this module. Requirements:

  • Complete SEO meta tags (title, description, OG tags)
  • Skip link as first element
  • Semantic structure: header, nav, main, sections, footer
  • At least one article element with time element
  • A contact form with all inputs properly labelled
  • At least 2 images with alt text, width, height, and lazy loading where appropriate
  • External CSS file linked in head, external JS at end of body
  • All external links with rel="noopener noreferrer"
  • W3C Validation: 0 errors, 0 warnings
  • Lighthouse Accessibility: 90+ score

10. Interview Questions

Q1: What are the most important HTML best practices you follow?

Answer: Using a valid HTML5 boilerplate with DOCTYPE, lang, charset, and viewport; writing semantic HTML with appropriate elements for their purpose; separating HTML, CSS, and JavaScript into external files; always providing alt text for images; labelling all form inputs; following proper heading hierarchy with one h1 per page; validating HTML with the W3C validator; and testing keyboard navigation for accessibility.

Q2: Why should you avoid inline styles?

Answer: Inline styles mix presentation with content, violating the separation of concerns principle. They make maintenance difficult — changing a colour requires finding every inline style across dozens of files. They have the highest CSS specificity, making them nearly impossible to override from external stylesheets. They also make it harder to implement consistent design systems. External CSS files should always be used instead.

Q3: What is the W3C Validator and why use it?

Answer: The W3C Markup Validation Service (validator.w3.org) checks HTML against the official HTML specification and reports errors and warnings. Modern browsers silently "fix" invalid HTML — but often differently from each other. Validating ensures your page behaves consistently across browsers, has no subtle bugs from bad nesting, and meets the standards that accessibility tools and search engines rely on.

Q4: What is the separation of concerns in web development?

Answer: Separation of concerns means keeping different aspects of a system in separate places. In web development: HTML handles structure and content, CSS handles presentation and styling, JavaScript handles behaviour and interactivity. Mixing these — like inline styles in HTML or document.write in JavaScript — creates tightly coupled code that is hard to maintain, debug, and collaborate on.

Q5: How do you write accessible form inputs?

Answer: Every input needs a <label> linked via for/id. Use appropriate input types (email, tel, number). Add required and validation attributes. Provide error messages that are announced by screen readers using aria-live or role="alert". Group related inputs in fieldsets with legends. Ensure all inputs are reachable by keyboard. Test with a screen reader. Never rely on placeholder text as a substitute for labels.

🎉 Module 02 Complete!

You have now completed all of HTML — basics and intermediate. You know everything needed to write professional, semantic, accessible, and SEO-optimised HTML. Next: learn CSS to make your pages look beautiful!