HTML Best Practices
HTML Best Practices
Section titled “HTML Best Practices”Follow these guidelines to write HTML that’s clean, maintainable, and works everywhere.
Document Structure
Section titled “Document Structure”Always Start with DOCTYPE
Section titled “Always Start with DOCTYPE”<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Page Title</title></head><body> <!-- Content --></body></html>Specify Language
Section titled “Specify Language”Always include lang on the <html> element:
<html lang="en"> <!-- English --><html lang="es"> <!-- Spanish --><html lang="zh-CN"> <!-- Chinese (Simplified) -->Semantic HTML
Section titled “Semantic HTML”Use Elements for Their Meaning
Section titled “Use Elements for Their Meaning”<header>Site header</header><nav>Navigation</nav><main> <article> <h1>Article Title</h1> <p>Content...</p> </article> <aside>Related links</aside></main><footer>Site footer</footer><div class="header">Site header</div><div class="nav">Navigation</div><div class="main"> <div class="article"> <div class="title">Article Title</div> <div>Content...</div> </div> <div class="aside">Related links</div></div><div class="footer">Site footer</div>Common Semantic Elements
Section titled “Common Semantic Elements”| Element | Use For |
|---|---|
<header> | Page or section header |
<nav> | Navigation links |
<main> | Main content (one per page) |
<article> | Self-contained content |
<section> | Thematic grouping |
<aside> | Tangentially related content |
<footer> | Page or section footer |
Formatting & Indentation
Section titled “Formatting & Indentation”Consistent Indentation
Section titled “Consistent Indentation”Use 2 or 4 spaces (never tabs) and be consistent:
<ul> <li> <a href="/page"> Link text </a> </li></ul>Line Length
Section titled “Line Length”Keep lines under 80-100 characters. Break long attributes:
<img src="image.jpg" alt="A descriptive alt text that explains the image" width="800" height="600" loading="lazy">Attributes
Section titled “Attributes”Quote All Attribute Values
Section titled “Quote All Attribute Values”<!-- Good --><input type="text" class="form-input">
<!-- Avoid --><input type=text class=form-input>Boolean Attributes
Section titled “Boolean Attributes”Don’t add values to boolean attributes:
<!-- Good --><input type="checkbox" checked disabled>
<!-- Unnecessary --><input type="checkbox" checked="checked" disabled="disabled">Attribute Order (Convention)
Section titled “Attribute Order (Convention)”idclassnamedata-*src,href,for,typetitle,altrole,aria-*
Links and Buttons
Section titled “Links and Buttons”Use the Right Element
Section titled “Use the Right Element”<!-- Links go somewhere --><a href="/about">About Us</a>
<!-- Buttons do something --><button type="button" onclick="save()"> Save</button><!-- Don't use links as buttons --><a href="#" onclick="save()">Save</a>
<!-- Don't use divs as buttons --><div onclick="save()">Save</div>External Links
Section titled “External Links”<a href="https://example.com" target="_blank" rel="noopener noreferrer"> External Site</a>Images
Section titled “Images”Always Include Alt Text
Section titled “Always Include Alt Text”<!-- Informative image --><img src="chart.png" alt="Sales grew 50% in 2024">
<!-- Decorative image --><img src="decorative.png" alt="">
<!-- Image is a link --><a href="/products"> <img src="products.png" alt="View our products"></a>Specify Dimensions
Section titled “Specify Dimensions”<img src="photo.jpg" alt="Description" width="800" height="600">This prevents layout shift while images load.
Label Everything
Section titled “Label Everything”<label for="email">Email Address</label><input type="email" id="email" name="email" required>Group Related Fields
Section titled “Group Related Fields”<fieldset> <legend>Shipping Address</legend>
<label for="street">Street</label> <input type="text" id="street" name="street">
<label for="city">City</label> <input type="text" id="city" name="city"></fieldset>Use Appropriate Input Types
Section titled “Use Appropriate Input Types”<input type="email"> <!-- Email validation --><input type="tel"> <!-- Phone keyboard on mobile --><input type="url"> <!-- URL validation --><input type="number"> <!-- Number keyboard --><input type="date"> <!-- Date picker -->Tables
Section titled “Tables”Use for Tabular Data Only
Section titled “Use for Tabular Data Only”<table> <caption>Monthly Sales</caption> <thead> <tr> <th scope="col">Month</th> <th scope="col">Revenue</th> </tr> </thead> <tbody> <tr> <td>January</td> <td>$10,000</td> </tr> </tbody></table>Comments
Section titled “Comments”Use Comments Sparingly
Section titled “Use Comments Sparingly”<!-- Main navigation --><nav>...</nav>
<!-- User profile section --><section>...</section>
<!-- TODO: Add search functionality -->Don’t over-comment obvious code.
Validation
Section titled “Validation”Validate Your HTML
Section titled “Validate Your HTML”Use the W3C Validator to check for errors:
- Unclosed tags
- Invalid nesting
- Missing required attributes
- Deprecated elements
Checklist
Section titled “Checklist”- DOCTYPE declared
-
langattribute on<html> -
<meta charset="UTF-8">in head - Viewport meta tag included
- Semantic elements used appropriately
- All images have
altattributes - Form inputs have labels
- Links use
<a>, actions use<button> - External links have
rel="noopener noreferrer" - HTML validates without errors
- Consistent indentation throughout