HTML · Production

HTML Best Practices

This lesson pulls everything together into one checklist you can use on every page you build.

Advanced 5 min Lesson 20 of 22Follows the WHATWG HTML Living Standard.
0/22 in HTML
On this page · 5 min · Advanced

Learning objectives#

  • Apply a professional HTML checklist
  • Keep markup clean, readable and valid
  • Load CSS and JavaScript efficiently
  • Avoid common security mistakes in HTML

Explanation#

Structure: full document skeleton, one <h1>, logical headings, semantic landmarks, lists for lists and tables for data.

Readability: lowercase tags, double-quoted attributes, two-space indentation, meaningful class names (card-title, not red-text).

Separation: HTML for content, CSS in .css files, JavaScript in .js files. Avoid inline style="" and onclick="" in real projects.

Performance: CSS <link> in <head>; scripts with defer; images sized, compressed and lazy-loaded.

Security: rel="noopener" on target="_blank" links, sandbox on untrusted iframes, never put secrets (API keys, passwords) in HTML — anyone can view the source.

Code example: A clean, production-ready page template#

HTMLA clean, production-ready page template Illustrative
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Products | ShopEasy</title>
  <meta name="description" content="Browse our full range of products.">
  <link rel="stylesheet" href="/css/site.css">
  <script src="/js/app.js" defer></script>
</head>
<body>
  <a class="skip-link" href="#main">Skip to content</a>
  <header class="site-header">
    <nav aria-label="Main">…</nav>
  </header>


  <main id="main">
    <h1>Products</h1>
    <section aria-labelledby="new-heading">
      <h2 id="new-heading">New arrivals</h2>
      <ul class="product-list">
        <li class="product-card">…</li>
      </ul>
    </section>
  </main>


  <footer class="site-footer">…</footer>
</body>
</html>
Expected output
A well-organised template: metadata, external CSS and JS, a skip link, landmarks, a single h1 and a list of products.

This example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.

Step-by-step explanation#

  1. Every metadata tag sits in <head>, CSS first, script with defer.
  2. A skip link is the first focusable element.
  3. Landmarks: header, nav, main, footer.
  4. The section is labelled by its own heading via aria-labelledby.
  5. Products are a list, so screen readers announce how many there are.
  6. Class names describe what things are, not how they look.

Real-world use case#

Use this checklist during code review. Teams often add an HTML validator and an accessibility checker (like axe) to their build so mistakes are caught automatically.

Common mistakes#

Inline styles everywhere

style="color:red" on 50 elements means 50 edits to change the colour. Put styles in a stylesheet.

Secrets in the HTML source

Anything in HTML — including hidden fields and comments — is visible with View Source. Keep API keys on the server.

Never validating

Small errors (an unclosed tag, a duplicate id) cause strange bugs. Run the W3C validator.

Best practices#

  • Validate with validator.w3.org
  • Audit with Lighthouse in Chrome DevTools
  • Use a formatter (Prettier) so indentation is consistent
  • Name classes by purpose (product-card) not appearance (blue-box)
  • Keep comments short and remove commented-out code

Remember this#

Checklist: Valid · Semantic · Accessible · Fast · Secure.

Content in .html, looks in .css, behaviour in .js.

If it is in the HTML, the whole world can read it.

Practice exercise#

Your task: List three problems in: <html><body><div onclick="go()" style="font-size:30px">Welcome</div><a href="x" target="_blank">here</a></body></html>

Need a hint?
Look at the document skeleton, the heading, the clickable div, the inline style and the link.
Show solution
Text Illustrative
1. Missing DOCTYPE, lang, <head> with charset, viewport and title.
2. "Welcome" should be an <h1> styled with CSS, not a div with inline style.
3. A clickable div is not keyboard accessible — use <button> (or a link if it navigates).
4. The link text "here" is not descriptive, and target="_blank" needs rel="noopener".

Mini quiz#

HTML Best Practices quizMultiple choice Question 1 of 3

Where should a script tag go for best performance in a simple site?

Score so far: 0/0

Want more? Practise all HTML MCQs · HTML interview questions

My notes#

Saved in this browser.

Progress is saved in this browser. Sign in to sync.