Advanced20 min read

Best Practices & Validation

Learn HTML best practices including W3C validation, performance optimization with script loading strategies, progressive enhancement, and common mistakes to avoid.

W3C Validation

The W3C Markup Validation Service checks your HTML against the specification and reports errors and warnings. Valid HTML ensures:

  • Consistent rendering across browsers.
  • Better accessibility — assistive technologies rely on correct markup.
  • Easier debugging — invalid HTML causes unpredictable browser behaviour.

Common validation errors

ErrorFix
Missing alt on <img>Add alt attribute (use alt="" for decorative images)
Unclosed elementsEnsure every opening tag has a matching closing tag
Duplicate id attributesEach id must be unique on the page
Block elements inside <p>Move block elements outside the paragraph
Missing <!DOCTYPE html>Always start with the doctype declaration
Obsolete elements (<center>, <font>)Use CSS instead

Make validation part of your workflow — run it during development, not just before launch.

Script Loading Strategies

How you load JavaScript affects page performance. The key attributes on <script> are:

defer

html
<script src="app.js" defer></script>
  • Downloads in parallel with HTML parsing.
  • Executes after the DOM is fully parsed.
  • Multiple deferred scripts execute in order.
  • Best for most scripts that need the DOM.

async

html
<script src="analytics.js" async></script>
  • Downloads in parallel with HTML parsing.
  • Executes as soon as downloaded (may interrupt parsing).
  • No guaranteed execution order.
  • Best for independent scripts (analytics, ads).

type="module"

html
<script type="module" src="app.js"></script>
  • Deferred by default.
  • Supports import/export.
  • Strict mode enabled.

Resource hints

  • <link rel="preload"> — Fetch a resource immediately (fonts, critical CSS).
  • <link rel="prefetch"> — Fetch a resource for future navigation (low priority).
  • <link rel="preconnect"> — Establish early connection to a third-party origin.
html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>

Progressive Enhancement

Progressive enhancement is a strategy that starts with a baseline of functional HTML and layers on CSS and JavaScript as enhancements.

The principle

  1. HTML first — Content is accessible with just HTML. Links work, forms submit, content is readable.
  2. CSS second — Visual design, layout, and polish.
  3. JavaScript third — Interactive features and dynamic behaviour.

Practical examples

  • Use <a href="/page"> for navigation (works without JS). Enhance with client-side routing.
  • Use <form action="/submit"> for data submission (works without JS). Enhance with AJAX.
  • Use <details>/<summary> for collapsible content (works without JS). Enhance with animations.
  • Use <dialog> for modals (works without complex JS).

The opposite approach — graceful degradation — starts with a full-featured experience and tries to make it work in limited environments. Progressive enhancement is generally preferred because it guarantees the baseline works everywhere.

Common Mistakes and Anti-patterns

Mistakes to avoid

  1. Using <div> for everything — Use semantic elements (<nav>, <main>, <section>, <article>, <aside>, <header>, <footer>).
  2. Skipping heading levels — Do not jump from <h1> to <h3>. The document outline should be logical.
  3. Using <br> for spacing — Use CSS margin and padding instead.
  4. Inline styles everywhere — Move styles to CSS classes.
  5. Missing lang on <html> — Always declare the document language.
  6. Images without dimensions — Always include width and height to prevent layout shift.
  7. Using <table> for layout — Tables are for tabular data only.
  8. Empty links and buttons — Every interactive element needs accessible text.

The HTML Living Standard

HTML is a living standard maintained by WHATWG. There are no version numbers ("HTML5" is a marketing term). The specification is continuously updated at html.spec.whatwg.org.

A Well-Structured HTML Page

html
<!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="A well-structured HTML page example">

  <!-- Preconnect to external origins -->
  <link rel="preconnect" href="https://fonts.googleapis.com">

  <title>Best Practices Example</title>

  <!-- CSS: non-blocking -->
  <link rel="stylesheet" href="styles.css">

  <!-- JS: deferred -->
  <script src="app.js" defer></script>
</head>
<body>
  <a href="#main" class="skip-link">Skip to content</a>

  <header>
    <nav aria-label="Primary">
      <ul>
        <li><a href="/">Home</a></li>
        <li><a href="/about">About</a></li>
      </ul>
    </nav>
  </header>

  <main id="main">
    <article>
      <h1>Page Title</h1>
      <p>Content goes here.</p>
      <img src="photo.jpg" alt="Description" width="800" height="600" loading="lazy">
    </article>
  </main>

  <footer>
    <p>&copy; 2025 Example Site</p>
  </footer>
</body>
</html>

What is the difference between the `defer` and `async` attributes on a <script> tag?

Ready to practice?

Create your free account to access the interactive code editor, run challenges, and track your progress.