C.W.K.
Stream
Lesson 04 of 05 · published

Anchors and Images: The Web's Connective Tissue

~12 min · anchors, links, images, alt-text, responsive-images, picture

Level 0Markup Novice
0 XP0/34 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"A page without links is a document. The links are what make it the web."

<a>: More Than href

Every clickable link is an <a>. The four attributes you'll touch most:

  • href — the destination. Relative (/quests), absolute (https://...), in-page (#section-id), or special (mailto:, tel:, javascript: — avoid the last).
  • target="_blank" — open in a new tab. Always pair with rel="noopener noreferrer" when linking externally, or the new tab can read window.opener and pull tricks.
  • rel — relationship metadata. noopener, noreferrer, nofollow, external, prefetch, canonical, license. Browsers and search engines read these.
  • download — instead of navigating, save the resource as a file. Optionally rename: download="report.pdf".

Link Text Has To Mean Something

"Click here" and "learn more" are accessibility violations. Screen readers can pull a list of all links on a page; out of context, your "click here" links sound like: "Link: click here. Link: click here. Link: click here." Useless.

Write link text that describes the destination: "Read the MDN HTML reference" not "click here". The link text IS the accessibility label.

Anchors Inside The Page

<a href="#section-id"> scrolls to the element with that ID. Combine with semantic headings that have IDs (<h2 id="the-mantra">) for table-of-contents links and shareable deep links. CSS's scroll-behavior: smooth on <html> makes the scroll itself smooth.

<img>: The Spec Requires alt

The alt attribute isn't optional. The W3C spec is unambiguous: every <img> must have alt. The rules:

  • Meaningful image — alt describes what the image conveys. Not "image of a cat"; just "sleeping calico kitten." (The screen reader prefixes "Image:".)
  • Decorative image — alt="" (empty string). This tells screen readers to skip it. Different from omitting alt entirely.
  • Functional image (a logo that's also a home link) — alt describes the destination/function ("Pippa home"), not the visual.
  • Image with text inside — alt contains the text. Never make a screen reader miss the words because they were baked into a PNG.

Responsive Images: srcset, sizes,

One image file at full size on every screen wastes bandwidth on mobile and ships blurry images on retina desktops. Modern responsive images use srcset + sizes to let the browser pick the right file:

srcset says "here are versions of this image at different resolutions"; sizes says "here's how big the image will be at each viewport width." The browser then downloads the smallest file that's still sharp at the device's pixel density.

For different images at different sizes (art direction — wide hero on desktop, tall hero on mobile), use <picture> with <source> children that have media queries.

Modern Formats: AVIF, WebP, with Fallback

JPEG and PNG are still everywhere but AVIF and WebP compress better at the same visual quality. <picture> lets you offer them with a JPEG fallback:

Lazy-load below-the-fold images. <img loading="lazy" decoding="async">. The browser delays loading until the image is near the viewport. Free performance, one attribute. Don't lazy-load the LCP (largest contentful paint) image at the top of the page — that hurts perceived load time.

<figure> + <figcaption> For Captioned Media

When an image (or chart, or code block, or quote) has an accompanying caption, wrap them in <figure> with the caption in <figcaption>. The screen reader announces "figure" and reads the caption — the association is explicit, not just visual proximity.

Pippa's Note

Cwk-site renders Pippa's quest illustrations through Next's <Image> component, which generates srcset, sizes, and modern formats automatically. The underlying HTML is still <img> with all the attributes — Next is doing what you'd do by hand, just faster. Knowing the HTML is what lets you debug Next when its magic misfires.

Code

Anchor patterns + anti-patterns·html
<!-- Anchors, the right way -->
<a href="/quests">View all quests</a>          <!-- internal, relative -->
<a href="https://html.spec.whatwg.org/"
   target="_blank"
   rel="noopener noreferrer">
  Read the HTML Living Standard
</a>                                          <!-- external, new tab, safely -->
<a href="#the-mantra">Jump to The Mantra</a>  <!-- in-page -->
<a href="mailto:hello@example.com">Email</a>  <!-- mailto -->
<a href="/report.pdf" download="q2-report.pdf">Download Q2 report</a>

<!-- DON'T -->
<a href="#">click here</a>
<a href="#" onclick="doStuff()">link</a>      <!-- this is what <button> is for -->
<a href="https://evil.com" target="_blank">link</a>  <!-- missing rel=noopener -->
srcset, sizes, picture·html
<!-- Responsive images, modern -->
<img
  src="hero-800.jpg"
  srcset="hero-400.jpg 400w,
          hero-800.jpg 800w,
          hero-1200.jpg 1200w,
          hero-1600.jpg 1600w"
  sizes="(min-width: 1024px) 60vw, 100vw"
  alt="Pippa with red hair and blue anime eyes, sitting at a glowing terminal"
  width="800"
  height="450"
  loading="lazy"
  decoding="async"
/>

<!-- Art direction with <picture> -->
<picture>
  <source media="(min-width: 768px)"
          srcset="hero-wide.avif" type="image/avif" />
  <source media="(min-width: 768px)"
          srcset="hero-wide.webp" type="image/webp" />
  <source srcset="hero-tall.avif" type="image/avif" />
  <source srcset="hero-tall.webp" type="image/webp" />
  <img src="hero-tall.jpg"
       alt="Pippa at a terminal"
       width="800" height="600" />
</picture>
Captioned media·html
<!-- Figure with caption -->
<figure>
  <img src="cascade-diagram.svg"
       alt="Diagram: origin → specificity → source order, resolving to a single winning declaration"
       width="600" height="300" />
  <figcaption>
    The cascade resolves competing CSS rules in three passes:
    origin, specificity, source order.
  </figcaption>
</figure>

External links

Exercise

Make a page with three images: (1) a decorative divider line (alt=""), (2) a meaningful photo with descriptive alt, (3) a responsive hero image with <picture>, srcset, sizes, AVIF + WebP fallback. Then add three links: an internal page link, an external link in a new tab (with rel=noopener), and a download link. Audit with Lighthouse and confirm zero accessibility warnings.
Hint
Lighthouse will flag missing alt and missing rel on external links. If you get a warning, re-read the relevant section above — the fix is usually one attribute.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.