# Part 3: Links, Images, and Media

## Introduction

Links are what make HTML "hyper" — the ability to connect documents together is the foundation of the entire web. Images and media are often half the information on a page. These elements look simple on the surface, but getting them right — accessible alt text, correct URL strategies, responsive images, lazy loading — makes a material difference in usability and performance.

This part covers everything I know from writing links and embedding media in real pages.

***

## The Anchor Element (`<a>`)

The `<a>` tag creates a hyperlink. It can link to other pages, external sites, sections of the same page, email addresses, phone numbers, or trigger file downloads.

### Basic Link

```html
<a href="https://github.com/Htunn/simple-waf-scanner">View on GitHub</a>
```

The `href` attribute (Hypertext REFerence) contains the destination URL. The link text should describe where the link goes — not "click here" or "read more".

***

## Absolute vs. Relative URLs

### Absolute URLs

Include the full protocol, domain, and path. Required for external links.

```html
<a href="https://crates.io/crates/simple-waf-scanner">View on crates.io</a>
```

### Relative URLs

Relative to the current document's location.

```html
<!-- Same directory -->
<a href="html-101-part-2.md">Part 2</a>

<!-- Up one directory level -->
<a href="../README.md">Back to Index</a>

<!-- Absolute path from root of the site -->
<a href="/programming/html-101/html-101-part-2.md">Part 2</a>
```

| Pattern           | Best use                                                 |
| ----------------- | -------------------------------------------------------- |
| `https://...`     | External links always                                    |
| `./page.html`     | Same directory (explicit)                                |
| `../page.html`    | Parent directory                                         |
| `/path/page.html` | Root-relative, consistent regardless of current location |

For internal links within a project or site, root-relative paths (`/path/to/page`) are the most reliable. They do not break when files are moved between directories.

***

## Linking to Page Sections (Fragment Identifiers)

Any element with an `id` attribute can be linked to directly:

```html
<!-- Target -->
<h2 id="installation">Installation</h2>

<!-- Link to it -->
<a href="#installation">Jump to Installation</a>

<!-- From another page -->
<a href="/docs/getting-started.html#installation">Installation instructions</a>
```

This is how table-of-contents links in documentation work.

***

## Opening Links in a New Tab

```html
<a href="https://github.com" target="_blank" rel="noopener noreferrer">
  GitHub
</a>
```

`target="_blank"` opens the link in a new tab or window.

`rel="noopener noreferrer"` is required for security. Without `noopener`, the opened page can access and manipulate the original page via `window.opener`. `noreferrer` additionally suppresses the `Referer` HTTP header.

**When to use new tabs:** External links where users are expected to reference while staying on the current page. Do not use it for internal navigation — it is disorienting and breaks the back button.

***

## Email and Phone Links

```html
<a href="mailto:name@example.com">Send an email</a>
<a href="tel:+1234567890">Call us</a>
```

`mailto:` opens the user's default email client. `tel:` triggers the phone dialler on mobile.

***

## Download Links

```html
<a href="/reports/scan-results.pdf" download>Download scan results (PDF)</a>
<a href="/reports/scan-results.pdf" download="waf-scan-2024.pdf">Download with custom name</a>
```

The `download` attribute tells the browser to download the file rather than navigate to it. Optionally provide a suggested filename.

***

## The Image Element (`<img>`)

```html
<img src="architecture.png" alt="Microservice architecture diagram showing the WAF scanner components" />
```

`<img>` is a void element. The two essential attributes are:

* `src` — the path to the image file
* `alt` — alternative text

### Writing Good Alt Text

Alt text is read by screen readers and displayed when the image fails to load. Writing it well is not optional.

**Informative images** — describe what the image shows and why it matters:

```html
<img src="scan-results.png" alt="WAF scanner output showing Cloudflare detected with 3 bypass techniques succeeding" />
```

**Decorative images** — provide an empty alt attribute so screen readers skip them:

```html
<img src="divider.png" alt="" />
```

**Never**: leave alt text out entirely (inaccessible), use "image of..." (the screen reader already announces it is an image), or just write the filename.

***

## Image Width and Height

Always specify `width` and `height`:

```html
<img src="diagram.png" alt="Architecture diagram" width="800" height="450" />
```

This reserves the correct space in the layout before the image loads, preventing **layout shift** — the page jumping around as images load. This directly affects Core Web Vitals scores (CLS — Cumulative Layout Shift).

***

## Responsive Images

For images that should adapt to different screen sizes, use `srcset` and `sizes`:

```html
<img
  src="hero-800.jpg"
  srcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1200.jpg 1200w"
  sizes="(max-width: 600px) 400px, (max-width: 900px) 800px, 1200px"
  alt="Dashboard screenshot"
  width="1200"
  height="675"
/>
```

* `srcset` lists available image files with their intrinsic widths
* `sizes` tells the browser which size to expect at different viewport widths
* The browser picks the most appropriate file, saving bandwidth on smaller screens

***

## Lazy Loading

Defer loading off-screen images until the user scrolls to them:

```html
<img src="below-fold.jpg" alt="Chart" loading="lazy" width="600" height="400" />
```

Do **not** lazy-load images that are visible in the initial viewport (above the fold) — that delays the most visible content.

***

## The `<picture>` Element

`<picture>` allows serving different image formats or completely different images based on conditions:

```html
<picture>
  <!-- Modern format for browsers that support it -->
  <source srcset="diagram.avif" type="image/avif" />
  <source srcset="diagram.webp" type="image/webp" />
  <!-- Fallback for all browsers -->
  <img src="diagram.png" alt="Architecture diagram" width="800" height="450" />
</picture>
```

The browser uses the first `<source>` it can handle and ignores the rest. The `<img>` is the fallback and carries the `alt` text.

***

## Figures with Captions

```html
<figure>
  <img src="scan-output.png" alt="Terminal output from waf-scanner showing detection results" width="900" height="400" />
  <figcaption>WAF scanner detecting Cloudflare on a target URL</figcaption>
</figure>
```

`<figure>` wraps self-contained content (images, diagrams, code examples) and `<figcaption>` provides a visible caption. The caption and alt text serve different purposes: alt is for when the image cannot be seen; caption is supplementary information for everyone.

***

## Tables

Tables are for tabular data — information that has a natural row/column structure. Do not use tables for layout.

```html
<table>
  <caption>WAF Detection Results</caption>
  <thead>
    <tr>
      <th scope="col">Target</th>
      <th scope="col">WAF Detected</th>
      <th scope="col">Bypasses Tested</th>
      <th scope="col">Bypasses Succeeded</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>example.com</td>
      <td>Cloudflare</td>
      <td>7</td>
      <td>2</td>
    </tr>
    <tr>
      <td>test.org</td>
      <td>AWS WAF</td>
      <td>7</td>
      <td>0</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td colspan="2">Total</td>
      <td>14</td>
      <td>2</td>
    </tr>
  </tfoot>
</table>
```

Key elements:

* `<caption>` — visible table title, announced by screen readers
* `<thead>` / `<tbody>` / `<tfoot>` — semantic grouping of rows
* `<th scope="col|row">` — header cells with `scope` for accessibility
* `<td>` — data cells
* `colspan` / `rowspan` — span across columns or rows

***

## Video

```html
<video
  src="demo.mp4"
  controls
  width="800"
  height="450"
  poster="demo-thumbnail.jpg"
  preload="metadata"
>
  Your browser does not support the video element.
</video>
```

With multiple source formats for browser compatibility:

```html
<video controls width="800" height="450" poster="thumbnail.jpg">
  <source src="demo.mp4" type="video/mp4" />
  <source src="demo.webm" type="video/webm" />
  <p>Your browser does not support video. <a href="demo.mp4">Download the video</a>.</p>
</video>
```

* `controls` — shows play/pause/volume controls
* `poster` — image displayed before playback starts
* `preload="metadata"` — loads only metadata (duration, dimensions), not the full video

***

## Audio

```html
<audio controls preload="metadata">
  <source src="recording.mp3" type="audio/mpeg" />
  <source src="recording.ogg" type="audio/ogg" />
  <p>Your browser does not support audio. <a href="recording.mp3">Download the recording</a>.</p>
</audio>
```

***

## Summary

| Element                                     | Purpose                                                |
| ------------------------------------------- | ------------------------------------------------------ |
| `<a href="">`                               | Hyperlinks — internal, external, fragments, email, tel |
| `target="_blank" rel="noopener noreferrer"` | Open in new tab safely                                 |
| `download` attribute                        | Trigger file download                                  |
| `<img src="" alt="">`                       | Embed images with meaningful alt text                  |
| `width` / `height` on `<img>`               | Prevent layout shift                                   |
| `loading="lazy"`                            | Defer off-screen images                                |
| `srcset` / `sizes`                          | Serve appropriately sized images                       |
| `<picture>`                                 | Serve different formats or art-directed images         |
| `<figure>` / `<figcaption>`                 | Self-contained media with visible caption              |
| `<table>`                                   | Tabular data (not layout)                              |
| `<video>` / `<audio>`                       | Native media embedding with controls                   |

***

## Up Next

[Part 4](https://blog.htunnthuthu.com/getting-started/programming/html-101/html-101-part-4) covers forms and user input — the HTML elements that collect data from users.
