· Best Practices

Common HTML Mistakes and How to Avoid Them

Learn about frequent HTML errors and best practices to prevent them.

Even experienced developers make HTML mistakes. Some are minor cosmetic issues, while others can break accessibility, hurt SEO, or cause browser compatibility problems. The good news? Most HTML mistakes are easy to fix once you know what to look for.

In this article, we’ll explore the most common HTML errors—from beginners to seasoned pros—and show you exactly how to avoid them. By the end, you’ll have a checklist of best practices that will level up your HTML game.

1. Missing or Incorrect DOCTYPE

The Mistake

Forgetting to include a DOCTYPE declaration or using an outdated one from HTML4 or XHTML days.

<!-- ❌ Bad: No DOCTYPE -->
<html>
  <head>
    <title>My Page</title>
  </head>
</html>

<!-- ❌ Bad: Outdated HTML 4.01 DOCTYPE -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<!-- ✅ Good: Modern HTML5 DOCTYPE -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>My Page</title>
  </head>
</html>

Why It Matters

Without a proper DOCTYPE, browsers render your page in “quirks mode,” which can cause inconsistent styling and layout across different browsers. The HTML5 DOCTYPE is short, simple, and ensures standards mode rendering.

The Fix

Always start every HTML document with <!DOCTYPE html> as the very first line—no exceptions.

2. Not Using Semantic HTML

The Mistake

Wrapping everything in generic <div> and <span> tags instead of using semantic elements that describe their content.

<!-- ❌ Bad: Divs for everything -->
<div class="header">
  <div class="nav">
    <div class="link">Home</div>
    <div class="link">About</div>
  </div>
</div>
<div class="content">
  <div class="post">
    <div class="title">Article Title</div>
    <div class="text">Content here...</div>
  </div>
</div>
<div class="footer">
  <div class="copyright">© 2024</div>
</div>

<!-- ✅ Good: Semantic elements -->
<header>
  <nav>
    <a href="/">Home</a>
    <a href="/about">About</a>
  </nav>
</header>
<main>
  <article>
    <h1>Article Title</h1>
    <p>Content here...</p>
  </article>
</main>
<footer>
  <p>&copy; 2024</p>
</footer>

Why It Matters

Semantic HTML improves:

  • Accessibility - Screen readers understand your page structure
  • SEO - Search engines better understand your content
  • Maintainability - Other developers (including future you) understand the code faster
  • Styling - CSS is easier to write when you have meaningful elements

The Fix

Use these semantic elements instead of generic divs:

  • <header> for page or section headers
  • <nav> for navigation menus
  • <main> for main page content
  • <article> for self-contained content
  • <section> for thematic groupings
  • <aside> for sidebar content
  • <footer> for page or section footers

3. Forgetting Alt Text on Images

The Mistake

Leaving out the alt attribute entirely, or writing useless alt text like “image” or the filename.

<!-- ❌ Bad: No alt attribute -->
<img src="team-photo.jpg" />

<!-- ❌ Bad: Useless alt text -->
<img src="DSC_0482.jpg" alt="image" />
<img src="graph.png" alt="graph" />

<!-- ✅ Good: Descriptive alt text -->
<img src="team-photo.jpg" alt="Development team at 2024 company retreat in Portland" />
<img src="graph.png" alt="Bar chart showing 35% revenue growth from Q1 to Q4 2023" />

<!-- ✅ Good: Empty alt for decorative images -->
<img src="decorative-flourish.png" alt="" />

Why It Matters

Alt text is critical for:

  • Screen reader users who can’t see the image
  • SEO - search engines read alt text
  • Slow connections - alt text displays while images load
  • Broken images - users see description instead of broken image icon

The Fix

Every <img> must have an alt attribute:

  • For informative images: describe what the image shows
  • For decorative images: use empty alt (alt="")
  • For complex images (charts, diagrams): provide detailed description or link to text alternative

4. Using <br> for Spacing

The Mistake

Using multiple <br> tags to create vertical space instead of using CSS margins or padding.

<!-- ❌ Bad: Using breaks for spacing -->
<p>First paragraph</p>
<br><br><br>
<p>Second paragraph</p>

<!-- ✅ Good: Use CSS for spacing -->
<p>First paragraph</p>
<p>Second paragraph</p>

<style>
  p {
    margin-bottom: 2rem;
  }
</style>

Why It Matters

Using <br> for layout:

  • Mixes presentation with content
  • Makes responsive design harder
  • Is difficult to maintain
  • Can break screen reader navigation

The Fix

  • Use <br> only for actual line breaks within content (like addresses or poetry)
  • Use CSS margins and padding for spacing
  • Structure your HTML with proper elements

5. Inline Styles Everywhere

The Mistake

Adding style attributes directly to HTML elements instead of using CSS classes or stylesheets.

<!-- ❌ Bad: Inline styles -->
<h1 style="color: blue; font-size: 32px; margin-bottom: 20px;">
  Heading
</h1>
<p style="color: #333; line-height: 1.6; margin-bottom: 16px;">
  Paragraph text
</p>

<!-- ✅ Good: CSS classes -->
<h1 class="page-title">Heading</h1>
<p class="body-text">Paragraph text</p>

<style>
  .page-title {
    color: blue;
    font-size: 2rem;
    margin-bottom: 1.25rem;
  }
  
  .body-text {
    color: #333;
    line-height: 1.6;
    margin-bottom: 1rem;
  }
</style>

Why It Matters

Inline styles:

  • Can’t be reused across elements
  • Override CSS specificity, making debugging harder
  • Mix content with presentation
  • Make maintenance difficult
  • Can’t use media queries or pseudo-classes

The Fix

  • Use external CSS files or <style> tags
  • Create reusable CSS classes
  • Reserve inline styles for rare, one-off cases or dynamic JavaScript-generated styles

6. Not Labeling Form Inputs

The Mistake

Creating form inputs without proper labels, or using placeholder text as labels.

<!-- ❌ Bad: No labels -->
<input type="text" placeholder="Enter your email" />

<!-- ❌ Bad: Unconnected label -->
<label>Email</label>
<input type="email" />

<!-- ✅ Good: Properly connected label -->
<label for="email">Email Address</label>
<input id="email" type="email" name="email" />

<!-- ✅ Also good: Wrapped label -->
<label>
  Email Address
  <input type="email" name="email" />
</label>

Why It Matters

Unlabeled inputs:

  • Are inaccessible to screen reader users
  • Can’t be clicked to focus the input (poor UX)
  • Fail WCAG accessibility standards
  • Create legal compliance issues

The Fix

Every form input needs a label:

  • Connect labels with the for attribute matching the input’s id
  • Or wrap the input inside the label
  • Never rely on placeholder text alone

7. Wrong Heading Hierarchy

The Mistake

Skipping heading levels or using headings based on visual appearance rather than content structure.

<!-- ❌ Bad: Skipping from h1 to h4 -->
<h1>Main Title</h1>
<h4>Subsection</h4>
<h4>Another Subsection</h4>

<!-- ❌ Bad: Using h3 just because it "looks right" -->
<h1>Page Title</h1>
<h3>This should be h2</h3>

<!-- ✅ Good: Logical hierarchy -->
<h1>Main Title</h1>
<h2>First Section</h2>
<h3>Subsection</h3>
<h3>Another Subsection</h3>
<h2>Second Section</h2>

Why It Matters

Proper heading hierarchy:

  • Helps screen readers navigate your page
  • Creates a clear document outline
  • Improves SEO
  • Makes content scannable

The Fix

  • Use only one <h1> per page (the main title)
  • Don’t skip heading levels (h1 → h2 → h3, not h1 → h4)
  • Use CSS to control visual appearance, not heading level
  • Think of headings as a table of contents for your page

8. Forgetting the lang Attribute

The Mistake

Not specifying the language of your content in the <html> tag.

<!-- ❌ Bad: No language specified -->
<!DOCTYPE html>
<html>
  <head>
    <title>My Page</title>
  </head>
</html>

<!-- ✅ Good: Language specified -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>My Page</title>
  </head>
</html>

Why It Matters

The lang attribute:

  • Helps screen readers pronounce content correctly
  • Improves translation tools
  • Helps search engines serve content to the right audience
  • Assists with hyphenation and typography

The Fix

Always add lang="en" (or appropriate language code) to your <html> tag. For multilingual content, you can also specify language for specific sections:

<p>Welcome to our site!</p>
<p lang="es">¡Bienvenido a nuestro sitio!</p>
<p lang="fr">Bienvenue sur notre site!</p>

9. Using <div> or <span> as Buttons

The Mistake

Creating fake buttons with divs or links instead of using actual <button> elements.

<!-- ❌ Bad: Div styled as button -->
<div class="button" onclick="submitForm()">Submit</div>

<!-- ❌ Bad: Link as button -->
<a href="#" class="button" onclick="doSomething()">Click Me</a>

<!-- ✅ Good: Real button -->
<button type="button" onclick="doSomething()">Click Me</button>

<!-- ✅ Good: Submit button in form -->
<form onsubmit="submitForm()">
  <button type="submit">Submit</button>
</form>

Why It Matters

Real buttons provide:

  • Keyboard accessibility (Space and Enter keys work)
  • Proper focus management
  • Screen reader compatibility
  • Better semantics

The Fix

Use <button> for actions and <a> for navigation:

  • <button> - For clicking to do something (submit forms, open modals, toggle UI)
  • <a> - For going somewhere (new page, different section, external site)

10. Missing Meta Viewport Tag

The Mistake

Not including the viewport meta tag, causing mobile display issues.

<!-- ❌ Bad: No viewport tag -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>My Page</title>
  </head>
</html>

<!-- ✅ Good: Viewport tag included -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>My Page</title>
  </head>
</html>

Why It Matters

Without the viewport meta tag:

  • Mobile browsers zoom out to show “desktop” version
  • Everything appears tiny on phones
  • Users have to pinch-zoom to read content
  • Site appears broken on mobile

The Fix

Always include this meta tag in your <head>:

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

11. Not Closing Tags

The Mistake

Leaving HTML tags unclosed or improperly nested.

<!-- ❌ Bad: Unclosed tags -->
<div>
  <p>Paragraph 1
  <p>Paragraph 2
</div>

<!-- ❌ Bad: Improperly nested -->
<div>
  <p>Text here
</div>
</p>

<!-- ✅ Good: Properly closed and nested -->
<div>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</div>

Why It Matters

While modern browsers try to fix unclosed tags, this can cause:

  • Unpredictable rendering
  • CSS styling issues
  • JavaScript selection problems
  • Invalid HTML

The Fix

  • Close all tags properly
  • Maintain proper nesting (first opened, last closed)
  • Use a code editor with syntax highlighting
  • Validate your HTML with the W3C validator

12. Using Tables for Layout

The Mistake

Using HTML tables to create page layouts instead of for actual tabular data.

<!-- ❌ Bad: Table for layout -->
<table>
  <tr>
    <td>Sidebar</td>
    <td>Main Content</td>
  </tr>
</table>

<!-- ✅ Good: CSS for layout, tables for data -->
<div class="layout">
  <aside>Sidebar</aside>
  <main>Main Content</main>
</div>

<style>
  .layout {
    display: grid;
    grid-template-columns: 250px 1fr;
    gap: 2rem;
  }
</style>

<!-- ✅ Good: Tables for actual data -->
<table>
  <thead>
    <tr>
      <th>Product</th>
      <th>Price</th>
      <th>Stock</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Widget</td>
      <td>$19.99</td>
      <td>47</td>
    </tr>
  </tbody>
</table>

Why It Matters

Using tables for layout:

  • Hurts accessibility (screen readers expect data in tables)
  • Makes responsive design nearly impossible
  • Creates unnecessarily complex HTML
  • Is an outdated practice from the 1990s

The Fix

  • Use CSS Grid or Flexbox for layouts
  • Reserve tables for tabular data only
  • Include proper <thead>, <tbody>, <th>, and scope attributes in data tables

The Mistake

Using “click here” or “read more” as link text without context.

<!-- ❌ Bad: Generic link text -->
<p>
  To learn about accessibility, <a href="/accessibility">click here</a>.
</p>
<p>
  Article about HTML forms. <a href="/forms">Read more</a>
</p>

<!-- ✅ Good: Descriptive link text -->
<p>
  Learn how to <a href="/accessibility">build accessible websites</a>.
</p>
<p>
  <a href="/forms">Learn about HTML forms and validation</a>
</p>

Why It Matters

Descriptive link text:

  • Helps screen reader users navigate (they often browse lists of links)
  • Improves SEO (search engines use link text)
  • Provides better UX (users know where the link goes)

The Fix

Make link text describe the destination or action:

  • “Learn about CSS Grid” instead of “Click here”
  • “View our pricing plans” instead of “Learn more”
  • “Download PDF report” instead of “Download”

14. Overusing IDs

The Mistake

Using IDs for styling when classes would be more appropriate.

<!-- ❌ Bad: IDs for styling -->
<div id="header">
  <h1 id="title">Title</h1>
  <p id="subtitle">Subtitle</p>
</div>

<style>
  #header { background: #fff; }
  #title { font-size: 2rem; }
  #subtitle { color: #666; }
</style>

<!-- ✅ Good: Classes for styling -->
<header class="site-header">
  <h1 class="page-title">Title</h1>
  <p class="page-subtitle">Subtitle</p>
</header>

<style>
  .site-header { background: #fff; }
  .page-title { font-size: 2rem; }
  .page-subtitle { color: #666; }
</style>

Why It Matters

IDs should be unique per page and are primarily for:

  • JavaScript selections
  • URL fragments (#section-name)
  • Form label associations

Classes are better for styling because they’re:

  • Reusable
  • Have lower specificity (easier to override)
  • More maintainable

The Fix

  • Use classes for CSS styling
  • Reserve IDs for truly unique elements that need JavaScript access or URL fragments
  • Never use the same ID twice on a page

15. Not Validating Your HTML

The Mistake

Never checking if your HTML is valid and well-formed.

Why It Matters

Invalid HTML can cause:

  • Browser rendering inconsistencies
  • Accessibility issues
  • SEO problems
  • Mysterious bugs that are hard to debug

The Fix

Regularly validate your HTML with:

Common validation errors to watch for:

  • Unclosed tags
  • Duplicate IDs
  • Missing required attributes
  • Improperly nested elements
  • Deprecated elements or attributes

Quick Reference: HTML Mistakes Checklist

Before deploying your HTML, check for these common mistakes:

  • ✅ DOCTYPE declaration is present and correct
  • ✅ Used semantic HTML elements instead of generic divs
  • ✅ All images have descriptive alt text
  • ✅ No multiple <br> tags for spacing (use CSS)
  • ✅ Minimal inline styles (use CSS classes)
  • ✅ All form inputs have labels
  • ✅ Heading hierarchy is logical (h1 → h2 → h3)
  • ✅ Lang attribute on <html> tag
  • ✅ Used <button> for buttons, not divs or links
  • ✅ Viewport meta tag is present
  • ✅ All tags are properly closed
  • ✅ Tables used for data only, not layout
  • ✅ Link text is descriptive
  • ✅ Used classes for styling, IDs sparingly
  • ✅ HTML has been validated

Keep Learning

Avoiding these mistakes will make your HTML cleaner, more accessible, and easier to maintain. Keep improving with these resources:

Ready to practice mistake-free HTML? Try the htmlEditor.net playground and build better websites today!

Remember: Everyone makes mistakes—even experienced developers. The key is learning to spot them early and building good habits from the start. Your future self (and your users) will thank you.

← Back to all blog posts

    Share: