HTML Structure & Semantics
HTML Structure & Semantics Semantic HTML uses elements that carry meaning about the content they contain - not just how it looks. This improves accessibility, S…
HTML Structure & Semantics
Semantic HTML uses elements that carry meaning about the content they contain - not just how it looks. This improves accessibility, SEO, and code maintainability. Screen readers, search engines, and browser reading modes all rely on semantic structure.
Document Boilerplate
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Character encoding - always first -->
<meta charset="UTF-8">
<!-- Responsive viewport - essential for mobile -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Page title (shown in tab, used by search engines) -->
<title>Page Title | Site Name</title>
<!-- SEO meta tags -->
<meta name="description" content="150-160 character page description for search results">
<meta name="robots" content="index, follow">
<link rel="canonical" href="https://example.com/page">
<!-- Open Graph (social sharing) -->
<meta property="og:title" content="Page Title">
<meta property="og:description" content="Description for social cards">
<meta property="og:image" content="https://example.com/og-image.jpg">
<meta property="og:url" content="https://example.com/page">
<meta property="og:type" content="website">
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@yourhandle">
<!-- Favicon variants -->
<link rel="icon" href="/favicon.ico" sizes="32x32">
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<!-- Performance: preload critical resources -->
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preconnect" href="https://fonts.googleapis.com">
<!-- Stylesheets -->
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<!-- page content -->
<script src="/app.js" defer></script>
</body>
</html>Semantic Page Structure
Use landmark elements to give the page a clear, machine-readable structure. Each landmark maps to an ARIA role that assistive technology uses for navigation.
<body>
<!-- Site-wide header with branding and nav -->
<header>
<a href="/" aria-label="Home"><img src="/logo.svg" alt="Company Name"></a>
<nav aria-label="Main navigation">
<ul>
<li><a href="/about" aria-current="page">About</a></li>
<li><a href="/blog">Blog</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
</header>
<!-- Main content - only one per page -->
<main id="main-content"> <!-- Skip-link target -->
<!-- Standalone, syndicate-able piece of content -->
<article>
<header>
<h1>Article Title</h1>
<p>By <address><a href="/author/jane">Jane Doe</a></address>
on <time datetime="2025-03-15">March 15, 2025</time></p>
</header>
<!-- Related content within an article -->
<section aria-labelledby="intro-heading">
<h2 id="intro-heading">Introduction</h2>
<p>Content...</p>
</section>
<section aria-labelledby="details-heading">
<h2 id="details-heading">Details</h2>
<p>Content...</p>
</section>
<footer>
<p>Filed under: <a href="/tags/html">HTML</a></p>
</footer>
</article>
<!-- Tangentially related content -->
<aside aria-label="Related articles">
<h2>You might also like</h2>
<!-- ... -->
</aside>
</main>
<!-- Site-wide footer -->
<footer>
<p>© 2025 Company Name. <a href="/privacy">Privacy Policy</a></p>
</footer>
</body>Semantic Text Elements
<!-- Headings: only one h1, use logical hierarchy -->
<h1>Page title (one per page)</h1>
<h2>Section heading</h2>
<h3>Subsection</h3>
<!-- Emphasis - semantic, not just visual -->
<p>Press <strong>Ctrl+S</strong> to save.</p> <!-- strong importance -->
<p>The word <em>semantics</em> is key here.</p> <!-- stress emphasis -->
<p>Total: <b>$42.00</b></p> <!-- visually bold, no semantic weight -->
<p>The book is called <i>Clean Code</i></p> <!-- alternative voice/mood -->
<!-- Inline code & technical text -->
<p>Use <code>npm install</code> to get started.</p>
<p>Keyboard shortcut: <kbd>Cmd</kbd> + <kbd>K</kbd></p>
<p>The variable was <var>x</var></p>
<pre><code class="language-js">const x = 42;</code></pre>
<!-- Quotes -->
<blockquote cite="https://source.example">
<p>The best code is no code at all.</p>
<footer>— <cite>Jeff Atwood</cite></footer>
</blockquote>
<p>He said <q>hello</q> and left.</p>
<!-- Other semantic inline elements -->
<p>The price is <del>$99</del> <ins>$49</ins> today.</p>
<p>Water is H<sub>2</sub>O. E = mc<sup>2</sup>.</p>
<p>Result: <mark>critically important text</mark></p>
<p>The meeting is at <time datetime="2025-03-15T14:00">2pm</time></p>
<abbr title="Hypertext Markup Language">HTML</abbr>Lists, Tables & Media
<!-- Description list (key-value pairs) -->
<dl>
<dt>HTTP</dt>
<dd>Hypertext Transfer Protocol</dd>
<dt>REST</dt>
<dd>Representational State Transfer</dd>
</dl>
<!-- Accessible table -->
<table>
<caption>Monthly Sales Report</caption>
<thead>
<tr>
<th scope="col">Month</th>
<th scope="col">Revenue</th>
<th scope="col">Users</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">January</th>
<td>$12,400</td>
<td>842</td>
</tr>
</tbody>
<tfoot>
<tr>
<th scope="row">Total</th>
<td>$12,400</td>
<td>842</td>
</tr>
</tfoot>
</table>
<!-- Responsive images -->
<picture>
<source media="(min-width: 1200px)" srcset="/hero-large.webp" type="image/webp">
<source media="(min-width: 600px)" srcset="/hero-medium.webp" type="image/webp">
<img src="/hero-small.jpg" alt="Developer working on laptop" width="800" height="400"
loading="lazy" decoding="async">
</picture>
<!-- Embedded video -->
<video controls preload="metadata" poster="/thumbnail.jpg">
<source src="/video.webm" type="video/webm">
<source src="/video.mp4" type="video/mp4">
<track kind="subtitles" src="/captions.vtt" srclang="en" label="English" default>
<p>Your browser does not support video. <a href="/video.mp4">Download</a></p>
</video>