Polyglot
Languages Web (HTML / CSS / JS) html structure
Web (HTML / CSS / JS) § html-structure

Document structure

The conventional HTML document is structured as a tree of elements — opening and closing tags with optional attributes, optionally containing text or other elements. The principal top-level structure: <!DOCTYPE html> (the document type declaration), <html> (the root element), <head> (metadata, scripts, stylesheets), <body> (the visible content). The HTML Living Standard (maintained by WHATWG) defines the substantial element vocabulary; the conventional contemporary discipline uses HTML5 semantic elements (<header>, <nav>, <main>, <article>, <section>, <footer>). The combination — declarative markup, the document tree as the basis of the DOM, the substantial element vocabulary — is the substance of HTML’s structural surface.

A complete document

The minimal modern HTML document:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>My Page</title>
</head>
<body>
    <h1>Hello, world!</h1>
    <p>This is a paragraph.</p>
</body>
</html>

The principal features:

  • <!DOCTYPE html> — declares HTML5; required for standards-mode rendering.
  • <html lang="en"> — root element; lang attribute for accessibility and SEO.
  • <meta charset="UTF-8"> — declares the character encoding.
  • <meta name="viewport" ...> — admits responsive design on mobile.
  • <title> — the document title (browser tab, search results).
  • <body> — the visible content.

Elements and tags

The principal grammar:

<element>content</element>
<element attribute="value">content</element>
<element />                                      <!-- self-closing (XHTML; rare in HTML5) -->
<void-element>                                    <!-- void elements have no closing tag -->

<!-- Examples: -->
<p>A paragraph.</p>
<a href="https://example.com">A link</a>
<img src="photo.jpg" alt="A photo">              <!-- void element -->
<input type="text" name="username">              <!-- void element -->
<br>                                              <!-- void: line break -->
<hr>                                              <!-- void: thematic break -->

The void elements (no closing tag): <area>, <base>, <br>, <col>, <embed>, <hr>, <img>, <input>, <link>, <meta>, <source>, <track>, <wbr>.

The document head

The <head> admits substantial document metadata:

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="A useful page about widgets.">
    <meta name="keywords" content="widgets, gadgets, useful">
    <meta name="author" content="Alice Example">

    <title>Page Title</title>

    <link rel="stylesheet" href="styles.css">
    <link rel="icon" href="favicon.ico" type="image/x-icon">
    <link rel="canonical" href="https://example.com/page">

    <script src="app.js" type="module" defer></script>

    <!-- Open Graph (social media): -->
    <meta property="og:title" content="Page Title">
    <meta property="og:description" content="Description for social sharing">
    <meta property="og:image" content="https://example.com/preview.png">
    <meta property="og:url" content="https://example.com/page">

    <!-- Twitter cards: -->
    <meta name="twitter:card" content="summary_large_image">
</head>

The principal head elements:

  • <meta> — metadata (charset, viewport, description, OG tags).
  • <title> — document title.
  • <link> — external resources (stylesheets, icons, alternate versions).
  • <script> — JavaScript (treated below).
  • <style> — inline CSS.
  • <base> — base URL for relative links.

Headings

Six levels:

<h1>Page heading (use only one per page)</h1>
<h2>Section heading</h2>
<h3>Subsection heading</h3>
<h4>Sub-subsection</h4>
<h5>...</h5>
<h6>...</h6>

The conventional discipline:

  • <h1> once per page — the main heading.
  • Heading order matters — admit substantial accessibility through hierarchy.
  • Don’t skip levels<h1> then <h3> admits substantial confusion for screen readers.

Text content

<p>A paragraph of text.</p>

<strong>Bold (semantic: important)</strong>
<em>Italic (semantic: emphasised)</em>
<b>Bold (visual only)</b>
<i>Italic (visual only)</i>
<u>Underlined</u>
<s>Strikethrough</s>
<mark>Highlighted</mark>
<small>Small text (legal, fine print)</small>

<sub>Subscript</sub>
<sup>Superscript</sup>

<code>inline code</code>
<kbd>Ctrl+C</kbd>                                <!-- keyboard input -->
<samp>output text</samp>                          <!-- sample output -->
<var>variable</var>                               <!-- variable name -->

<abbr title="HyperText Markup Language">HTML</abbr>
<cite>The Lord of the Rings</cite>                <!-- title of a work -->
<q>An inline quote</q>
<blockquote cite="https://...">
    A block quote.
</blockquote>

<time datetime="2026-01-15">January 15, 2026</time>
<address>123 Main St, Anytown</address>

<br>                                              <!-- line break -->
<hr>                                              <!-- thematic break (horizontal rule) -->

The conventional discipline favours semantic tags (<strong>, <em>) over presentational (<b>, <i>) — admit substantial accessibility and styling flexibility.

Lists

Three forms:

<!-- Unordered list: -->
<ul>
    <li>First item</li>
    <li>Second item</li>
    <li>Third item</li>
</ul>

<!-- Ordered list: -->
<ol>
    <li>Step one</li>
    <li>Step two</li>
    <li>Step three</li>
</ol>

<ol start="5" reversed>
    <li>Item five</li>
    <li>Item four</li>
</ol>

<!-- Description list: -->
<dl>
    <dt>HTML</dt>
    <dd>HyperText Markup Language</dd>
    <dt>CSS</dt>
    <dd>Cascading Style Sheets</dd>
</dl>

<!-- Nested: -->
<ul>
    <li>Fruits
        <ul>
            <li>Apple</li>
            <li>Banana</li>
        </ul>
    </li>
    <li>Vegetables</li>
</ul>
<a href="https://example.com">External link</a>
<a href="/about">Internal link (absolute path)</a>
<a href="about.html">Relative link</a>
<a href="#section-id">Link to anchor on this page</a>
<a href="mailto:alice@example.com">Email link</a>
<a href="tel:+1-555-0100">Phone link</a>

<!-- Open in new tab (with security attributes): -->
<a href="https://example.com" target="_blank" rel="noopener noreferrer">
    External (new tab)
</a>

<!-- Download: -->
<a href="report.pdf" download>Download report</a>
<a href="report.pdf" download="my-report.pdf">Download as my-report.pdf</a>

The rel="noopener noreferrer" is conventional with target="_blank" — admits substantial security against tabnabbing.

Images

<img src="photo.jpg" alt="A photo of a dog">

<!-- With dimensions (admits substantial layout stability): -->
<img src="photo.jpg" alt="A photo" width="640" height="480">

<!-- Responsive: -->
<img src="small.jpg"
     srcset="small.jpg 640w, medium.jpg 1280w, large.jpg 1920w"
     sizes="(max-width: 768px) 640px, 1280px"
     alt="A responsive image">

<!-- Picture element (multiple sources, art direction): -->
<picture>
    <source media="(max-width: 768px)" srcset="mobile.jpg">
    <source media="(max-width: 1200px)" srcset="tablet.jpg">
    <img src="desktop.jpg" alt="A picture">
</picture>

<!-- Lazy loading: -->
<img src="photo.jpg" alt="A photo" loading="lazy">

<!-- With caption: -->
<figure>
    <img src="chart.png" alt="Sales chart for Q1">
    <figcaption>Figure 1: Q1 sales by region.</figcaption>
</figure>

The alt attribute is required for accessibility — admits substantial screen-reader access. For decorative images, alt="" admits screen readers skipping.

Sections

The HTML5 semantic elements:

<body>
    <header>
        <h1>Site title</h1>
        <nav>
            <ul>
                <li><a href="/">Home</a></li>
                <li><a href="/about">About</a></li>
                <li><a href="/contact">Contact</a></li>
            </ul>
        </nav>
    </header>

    <main>
        <article>
            <h2>Article title</h2>
            <p>Article content...</p>

            <section>
                <h3>A section</h3>
                <p>Section content...</p>
            </section>

            <aside>
                <h3>Related</h3>
                <p>Sidebar content...</p>
            </aside>
        </article>
    </main>

    <footer>
        <p>&copy; 2026 Example Corp.</p>
    </footer>
</body>

The principal semantic sectioning elements:

  • <header> — page or section header.
  • <nav> — navigation links.
  • <main> — the main content (one per page).
  • <article> — self-contained content (article, blog post, comment).
  • <section> — thematic section.
  • <aside> — tangentially-related content (sidebar).
  • <footer> — page or section footer.

Treated in Semantic and accessibility.

Tables

<table>
    <caption>Quarterly sales</caption>
    <thead>
        <tr>
            <th>Quarter</th>
            <th>Revenue</th>
            <th>Growth</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th scope="row">Q1</th>
            <td>$100,000</td>
            <td>5%</td>
        </tr>
        <tr>
            <th scope="row">Q2</th>
            <td>$120,000</td>
            <td>20%</td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
            <th scope="row">Total</th>
            <td>$220,000</td>
            <td>—</td>
        </tr>
    </tfoot>
</table>

The principal elements:

  • <table> — the table.
  • <caption> — the table caption.
  • <thead>, <tbody>, <tfoot> — semantic groupings.
  • <tr> — row.
  • <th> — header cell (use scope for accessibility).
  • <td> — data cell.

Tables are conventional for tabular data; not for layout.

Generic containers

<div class="card">
    <p>Generic block container.</p>
</div>

<span class="highlight">Generic inline container.</span>

The <div> is block-level (default display: block); <span> is inline (default display: inline). Both have no semantic meaning — admit substantial styling and scripting hooks.

The conventional discipline favours semantic elements (<article>, <section>, <nav>) over generic <div> where applicable.

Embedded content

<!-- Video: -->
<video src="movie.mp4" controls width="640" height="360" poster="thumbnail.jpg">
    <source src="movie.mp4" type="video/mp4">
    <source src="movie.webm" type="video/webm">
    <p>Your browser does not support video.</p>
</video>

<!-- Audio: -->
<audio src="song.mp3" controls>
    <source src="song.mp3" type="audio/mpeg">
    <source src="song.ogg" type="audio/ogg">
</audio>

<!-- Inline frame: -->
<iframe src="https://example.com/embed" width="640" height="480"
        title="Embedded content"></iframe>

<!-- SVG inline: -->
<svg width="100" height="100" viewBox="0 0 100 100">
    <circle cx="50" cy="50" r="40" fill="red"/>
</svg>

<!-- Canvas: -->
<canvas id="myCanvas" width="500" height="300"></canvas>

Attributes

The principal global attributes (admit on any element):

<element id="unique-id">                          <!-- unique within page -->
<element class="space separated list">            <!-- CSS classes, JS hooks -->
<element style="color: red;">                     <!-- inline CSS (avoid except quick tests) -->
<element title="Tooltip text">                    <!-- hover tooltip -->
<element lang="en">                               <!-- language -->
<element dir="ltr">                               <!-- text direction (ltr/rtl/auto) -->
<element hidden>                                  <!-- visibility (admits CSS override) -->
<element data-custom="value">                     <!-- custom data attributes -->
<element role="button" aria-label="Close">        <!-- accessibility -->
<element tabindex="0">                            <!-- keyboard tab order -->
<element draggable="true">                        <!-- drag-and-drop -->
<element contenteditable="true">                  <!-- inline editing -->

The data-* attributes admit substantial custom data — accessed via element.dataset in JavaScript.

Comments

<!-- A comment, not visible in the rendered page. -->
<!--
    Multi-line
    comment.
-->

Comments are visible in source — admit no security boundary for sensitive data.

A complete example

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="A blog post about HTML.">
    <title>Understanding HTML | My Blog</title>
    <link rel="stylesheet" href="/styles.css">
    <link rel="icon" href="/favicon.ico">
    <link rel="canonical" href="https://example.com/blog/html">
</head>
<body>
    <header>
        <h1><a href="/">My Blog</a></h1>
        <nav aria-label="Main navigation">
            <ul>
                <li><a href="/blog">Blog</a></li>
                <li><a href="/about">About</a></li>
                <li><a href="/contact">Contact</a></li>
            </ul>
        </nav>
    </header>

    <main>
        <article>
            <header>
                <h1>Understanding HTML</h1>
                <p>By <address>Alice Example</address>,
                   <time datetime="2026-01-15">January 15, 2026</time></p>
            </header>

            <p>HTML is the conventional document structure language of the Web...</p>

            <section>
                <h2>The document tree</h2>
                <p>...</p>
            </section>

            <section>
                <h2>Semantic elements</h2>
                <p>...</p>
            </section>

            <footer>
                <p>Tagged: <a href="/tag/html">HTML</a>, <a href="/tag/web">Web</a></p>
            </footer>
        </article>

        <aside>
            <h2>Related articles</h2>
            <ul>
                <li><a href="/blog/css">Understanding CSS</a></li>
                <li><a href="/blog/js">Understanding JavaScript</a></li>
            </ul>
        </aside>
    </main>

    <footer>
        <p>&copy; 2026 My Blog. All rights reserved.</p>
    </footer>

    <script src="/app.js" type="module" defer></script>
</body>
</html>

A note on the conventional discipline

The contemporary HTML structure advice:

  • Use <!DOCTYPE html> — admit standards-mode rendering.
  • Set lang on <html> — admit substantial accessibility.
  • Use semantic elements (<header>, <nav>, <main>, etc.) over generic <div>.
  • Use only one <h1> per page; respect heading hierarchy.
  • Always provide alt for images (or empty alt="" for decorative).
  • Set width and height on images — admit substantial layout stability.
  • Use loading="lazy" for off-screen images.
  • Use defer or async on scripts — admit substantial parallel parsing.
  • Use rel="noopener noreferrer" with target="_blank".
  • Validate with validator.w3.org — admit substantial standards conformance.

The combination — declarative markup, the document tree as DOM basis, the substantial semantic-element vocabulary, the metadata-rich <head>, the conventional separation from CSS and JavaScript — is the substance of HTML’s structural surface. The discipline produces accessible, well-organised documents with substantial substrate for styling and scripting.