# Part 2: Semantic HTML — Headings, text content, section elements

## Introduction

When I first started writing HTML, I used `<div>` for everything. Navigation? `<div>`. Article content? `<div>`. Page footer? `<div>`. It worked visually — browsers rendered it — but the page was structurally meaningless. Screen readers had no idea what was navigation versus main content. Search engines had no signal about what text mattered most. CSS ended up full of context-dependent class names just to compensate for the lack of structure.

Semantic HTML solves this. Using elements that describe what content *is*, not just how it looks, makes pages accessible, maintainable, and honestly easier to write CSS for.

***

## What "Semantic" Means

A semantic element clearly describes its meaning to both the browser and the developer. Compare:

```html
<!-- Non-semantic -->
<div class="nav-container">
  <div class="nav-item"><a href="/">Home</a></div>
</div>

<!-- Semantic -->
<nav>
  <a href="/">Home</a>
</nav>
```

Both render identically by default. The difference is in what the markup communicates:

* The browser knows `<nav>` is navigation — it can be listed by accessibility tools
* Search engines understand `<nav>` is navigational, not primary content
* Other developers reading the code understand the intent immediately

***

## Headings

Headings create the document outline. The browser, screen readers, and search engines all use heading levels to understand document hierarchy.

```html
<h1>Main Page Title</h1>

<h2>Section Title</h2>
<p>Content under this section.</p>

<h3>Subsection Title</h3>
<p>Content under this subsection.</p>
```

### Rules I Follow

**One `<h1>` per page.** It identifies the primary topic of the page. On a blog post, it is the post title. On a dashboard, it is the dashboard name.

**Do not skip levels.** If you have a `<h2>`, the next level down should be `<h3>`, not `<h5>`. Skipped levels confuse the document outline and trip up screen readers.

**Do not use headings for visual size.** If you want large bold text that is not a heading, use CSS. Do not use `<h2>` just because it looks the right size.

```html
<!-- Wrong: heading used for visual styling only -->
<h3>Created on 2024-01-15</h3>

<!-- Right: paragraph styled with CSS -->
<p class="date">Created on 2024-01-15</p>
```

***

## Text Content Elements

### Paragraphs

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

`<p>` is for prose — sentences and paragraphs. Do not use it for single labels or non-prose text.

### Strong and Emphasis

```html
<p>This is <strong>critically important</strong>.</p>
<p>The term <em>idempotent</em> means applying it multiple times gives the same result.</p>
```

* `<strong>` — serious importance, urgency, or warning. Screen readers may emphasise this.
* `<em>` — stress emphasis, i.e., spoken emphasis that would change meaning. Screen readers may inflect this.

These are semantic elements. For purely visual bold/italic without semantic meaning:

```html
<p>This is <b>visually bold</b> but carries no special importance.</p>
<p>This is <i>visually italic</i> for style or a technical term.</p>
```

### Code

```html
<p>Run <code>cargo build --release</code> to compile.</p>

<pre><code>
fn main() {
    println!("Hello, world!");
}
</code></pre>
```

* `<code>` — inline code, filenames, command names
* `<pre>` — preserves whitespace and line breaks, for code blocks
* `<pre><code>` together — the correct pattern for multi-line code blocks

### Quotations

```html
<!-- Inline quote -->
<p>According to the spec, <q>the document must be well-formed</q>.</p>

<!-- Block quote -->
<blockquote cite="https://source-url.com">
  <p>If it's stupid but it works, it's not stupid.</p>
</blockquote>
```

### Abbreviations

```html
<p><abbr title="HyperText Markup Language">HTML</abbr> is not a programming language.</p>
```

The `title` attribute provides the expansion on hover/screen reader.

***

## Lists

### Unordered List

```html
<ul>
  <li>First item</li>
  <li>Second item</li>
  <li>Third item</li>
</ul>
```

Use when the order does not matter (feature lists, navigation items, bullet points).

### Ordered List

```html
<ol>
  <li>Clone the repository</li>
  <li>Install dependencies</li>
  <li>Run the server</li>
</ol>
```

Use when sequence matters (installation steps, ranked items, table of contents).

### Description List

```html
<dl>
  <dt>Idempotent</dt>
  <dd>An operation that produces the same result regardless of how many times it is applied.</dd>

  <dt>Atomic</dt>
  <dd>An operation that either completes fully or has no effect at all.</dd>
</dl>
```

`<dl>` (description list) is the correct element for glossaries, metadata pairs, or term–definition structures. I use it in documentation pages where I'm presenting key-value pairs.

### Nesting Lists

```html
<ul>
  <li>Backend
    <ul>
      <li>Python</li>
      <li>Rust</li>
    </ul>
  </li>
  <li>Frontend
    <ul>
      <li>HTML</li>
      <li>CSS</li>
    </ul>
  </li>
</ul>
```

***

## Structural Sectioning Elements

HTML5 introduced elements that describe the role of sections in the page layout.

### `<header>`

```html
<header>
  <h1>Site Name</h1>
  <nav>...</nav>
</header>
```

Contains introductory content for a page or section: logos, site titles, navigation, search. There can be a `<header>` inside `<article>` or `<section>` as well — each represents the introductory content for that element.

### `<nav>`

```html
<nav aria-label="Main navigation">
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
    <li><a href="/blog">Blog</a></li>
  </ul>
</nav>
```

For major navigation blocks. Not every group of links needs to be `<nav>` — reserve it for the primary and secondary navigation menus.

### `<main>`

```html
<main>
  <!-- primary content of the page -->
</main>
```

There should be exactly **one `<main>` per page**. It identifies the primary content, distinct from headers, footers, and sidebars. Screen readers use it to skip directly to content.

### `<article>`

```html
<article>
  <h2>Building a WAF Scanner in Rust</h2>
  <p>Published 2024-03-15 by Htunn</p>
  <p>When I decided to build a WAF bypass testing tool...</p>
</article>
```

Self-contained content that makes sense on its own and could be syndicated independently: blog posts, news articles, forum posts, documentation pages.

### `<section>`

```html
<section>
  <h2>Installation</h2>
  <p>...</p>
</section>

<section>
  <h2>Configuration</h2>
  <p>...</p>
</section>
```

A thematic grouping of content. Usually has a heading. Use `<section>` when grouping related content under a heading; use `<div>` when grouping purely for styling with no semantic meaning.

### `<aside>`

```html
<aside>
  <h3>Related Articles</h3>
  <ul>
    <li><a href="/rust-101">Rust 101 Series</a></li>
  </ul>
</aside>
```

Content tangentially related to the primary content: sidebars, pull quotes, related links, advert zones.

### `<footer>`

```html
<footer>
  <p>&copy; 2025 Htunn. All rights reserved.</p>
  <nav aria-label="Footer navigation">
    <a href="/privacy">Privacy</a>
    <a href="/contact">Contact</a>
  </nav>
</footer>
```

Footer content for a page or section: copyright, links, contact information.

***

## `<div>` and `<span>`

`<div>` and `<span>` are non-semantic containers. Use them when no semantic element fits the purpose.

```html
<!-- div: block-level grouping for CSS/JS targeting -->
<div class="card">
  <h2>Title</h2>
  <p>Content</p>
</div>

<!-- span: inline grouping for CSS/JS targeting -->
<p>Status: <span class="badge badge--success">Active</span></p>
```

The rule: reach for a semantic element first. Use `<div>` or `<span>` only when nothing semantic applies.

***

## Page Structure Example

A typical documentation page combining the elements above:

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>simple-waf-scanner — Documentation</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <header>
      <h1>simple-waf-scanner</h1>
      <nav aria-label="Main navigation">
        <ul>
          <li><a href="/">Home</a></li>
          <li><a href="/docs">Docs</a></li>
          <li><a href="https://github.com/Htunn/simple-waf-scanner">GitHub</a></li>
        </ul>
      </nav>
    </header>

    <main>
      <article>
        <header>
          <h2>Getting Started</h2>
          <p>Scan your first target in under 5 minutes.</p>
        </header>

        <section>
          <h3>Installation</h3>
          <pre><code>cargo install simple-waf-scanner</code></pre>
        </section>

        <section>
          <h3>Basic Usage</h3>
          <pre><code>waf-scanner scan --target https://example.com</code></pre>
        </section>
      </article>

      <aside>
        <h2>Quick Reference</h2>
        <dl>
          <dt><code>--target</code></dt>
          <dd>URL to scan</dd>
          <dt><code>--payloads</code></dt>
          <dd>Path to custom payload file</dd>
        </dl>
      </aside>
    </main>

    <footer>
      <p>MIT License — <a href="https://github.com/Htunn/simple-waf-scanner">View on GitHub</a></p>
    </footer>
  </body>
</html>
```

***

## Summary

| Element                  | Purpose                                             |
| ------------------------ | --------------------------------------------------- |
| `<h1>`–`<h6>`            | Document outline and section headings               |
| `<p>`                    | Prose paragraphs                                    |
| `<strong>` / `<em>`      | Semantic importance / emphasis                      |
| `<b>` / `<i>`            | Visual bold / italic without semantic meaning       |
| `<code>` / `<pre>`       | Inline code / code blocks                           |
| `<ul>` / `<ol>` / `<dl>` | Unordered / ordered / description lists             |
| `<header>`               | Introductory content for page or section            |
| `<nav>`                  | Primary navigation blocks                           |
| `<main>`                 | Primary page content (one per page)                 |
| `<article>`              | Self-contained, independently distributable content |
| `<section>`              | Thematic grouping with a heading                    |
| `<aside>`                | Tangentially related content                        |
| `<footer>`               | Footer for page or section                          |
| `<div>` / `<span>`       | Non-semantic containers for styling/scripting       |

***

## Up Next

[Part 3](https://blog.htunnthuthu.com/getting-started/programming/html-101/html-101-part-3) covers links, images, and media — the elements that connect pages and embed content.
