"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 withrel="noopener noreferrer"when linking externally, or the new tab can readwindow.openerand 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:
<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
<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.