HTML Tutorial 0/139 lessons ~6 min read Lesson 15

    HTML Links

    html links anchor elements connect the web — crawlers, users, and assistive technology all anchor elements (<a href>) are

    Course progress0%
    Focus
    18 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction

    Anchor elements (<a href>) are the web's native navigation primitive — crawlers, assistive tech, and browsers all depend on real links for discoverability and operability. Staff engineers distinguish links from button-styled divs: Airbnb room cards use <a href="/rooms/123"> in SSR HTML so Google indexes deep links; Stripe docs link externally with rel="noopener noreferrer" on target=_blank.

    Business problem

    Fake links (onclick on spans) break open-in-new-tab, copy-link, prefetch, and SEO. JavaScript-only navigation without href leaves orphan routes invisible to crawlers — a marketplace lost 30% organic traffic after SPA migration without link prerender.

    • Conversion: Broken checkout deep links in email — missing https, wrong query params.
    • A11y: "Click here" links fail WCAG 2.4.4 — BBC style guide mandates descriptive link text.
    • Security: target=_blank without noopener — tab-nabbing on partner referral pages.

    Why this feature exists

    Tim Berners-Lee's core insight: hypertext links unify documents. href provides a universal affordance — activate with Enter, context menu, assistive tech link lists, and browser prefetch heuristics.

    • History: name anchors deprecated for id fragments; download attribute added for file hints.
    • Rejected: Java-only applets for navigation — failed accessibility and crawl.
    • Modern: rel=noopener, prefetch, ping — HTML extends without breaking href contract.

    Browser internals

    HTMLAnchorElement exposes href, relList, and download. Click with unmodified primary button triggers navigation; modified clicks (ctrl, middle) delegate to browser UI. Parser tokenizes href early — invalid URLs may still resolve relative to document base.

    • Prefetch: Speculation Rules and link rel=prefetch compete — respect data-saver.
    • Fragment: #section scrolls after load — scroll-margin-top CSS affects anchor landing.
    • Download: Cross-origin download attribute often ignored — Content-Disposition server-side.
    text
    Click <a href="/p"> → navigation decision (same-origin policy)
    relList.contains('noopener') → window.opener null on target=_blank
    href="#" → scroll to top; avoid for buttons

    Rendering workflow

    Links are inline in layout — :hover/:focus styles trigger repaint. Underline via text-decoration-skip-ink reduces paint area. Prefetched href resources warm HTTP cache before click — Amazon product links prefetch on hover in some builds.

    • LCP: Hero CTA link text is text paint — font loading applies.
    • INP: SPA click handlers preventing default on fake links delay feedback — use real navigation where possible.
    • CLS: Link icons loading without dimensions shift adjacent text.

    Feature deep dive

    Use <a> for navigation, <button> for actions. href must be meaningful URL or fragment. External links: rel="noopener noreferrer" + visual indicator. Email/tel use specialized schemes with validation.

    • Absolute vs relative: Root-relative /path survives staging domains; protocol-relative // deprecated.
    • aria-current: page on active nav link — don't rely on bold class alone.
    • Skip links: First focusable <a href="#main"> — Google a11y baseline.
    html
    <nav aria-label="Primary">
    <a href="/" aria-current="page">Home</a>
    <a href="/pricing">Pricing</a>
    <a href="https://docs.stripe.com" rel="noopener noreferrer">Docs</a>
    </nav>
    <main id="main"></main>

    Accessibility analysis

    Link purpose must be clear from text or aria-label — not "read more" alone. Screen readers browse links rotor; duplicate "Learn more" fifty times is useless. Focus indicator required — outline removal fails 2.4.7.

    • Icon-only: aria-label or visible text — Instagram share icon needs name.
    • New window: Warn when target=_blank — "(opens in new tab)" in visible or aria-label.
    • Redundant: Don't nest interactive elements — no button inside link.

    SEO impact

    Internal linking distributes PageRank and discovery — Amazon footer category links shape crawl graph. href on rendered HTML required; Googlebot may not fire click handlers. rel=nofollow on paid/sponsored per guidelines.

    • Crawlable: href in SSR HTML — not data-href awaiting JS.
    • Canonical: Link to canonical URL in nav — avoid duplicate paths.
    • Sitelinks: Clear nav anchors help Google infer site structure.

    Security considerations

    javascript: URLs in href are XSS vectors — sanitize CMS output. Referrer leakage on external links — use noreferrer on sensitive pages. Phishing sites mimic href display text vs actual URL — teach users to inspect status bar.

    • Tabnabbing: window.opener access without noopener.
    • Open redirect: /out?url= user-controlled href — validate allowlist server-side.
    • CSRF: GET links that mutate state — use POST forms, not destructive href.

    Performance impact

    Prefetch/prerender of in-viewport links trades bandwidth for faster navigation — Shopify admin prefetches likely next routes. Too many prefetch hints compete with LCP image download on mobile.

    • HTTP/2: Multiplexed small HTML navigations — still full document parse cost.
    • SPA: Client routing avoids reload — preserve link semantics with href for SEO prerender.
    • INP: Instant visual feedback on :active — 80ms perceived win on mobile.

    Real production example

    BBC article templates use descriptive link text in body copy, related-story links with full headline as anchor text, and external links marked in copy style guide. Speculation Rules API added in head for top stories only.

    • Analytics: ping attribute or beacon — don't block navigation on sendBeacon fail.
    • International: hreflang alternates as link in head, not body anchors.
    • Broken link CI: linkinator on built HTML weekly.
    html
    <a href="/article/climate-report"
    hreflang="en"
    >UK climate report 2024: full findings</a>

    Enterprise usage

    Enterprise portals enforce link policy: no empty href, no javascript:, descriptive text lint in CMS, automated external link review for partner domains. Design system Link component always renders anchor with href.

    • PDF exports: Absolute URLs in print HTML — relative breaks offline.
    • Email: Full URL visible for trust — not hidden behind shortener only.
    • Legal: Sponsored links need rel=sponsored + disclosure adjacent.

    Common production failures

    Marketplace SPA replaced product card anchors with div onClick — organic listings dropped from index over 8 weeks. Travel site target=_blank on all external links leaked session referrer tokens to analytics partners.

    • Empty href: Keyboard users activate to page reload — support tickets.
    • Hash-only: Marketing used href="#" for modal triggers — broke middle-click.
    • Mobile: tel: link without proper formatting failed on iOS Safari dialer.

    Architecture review questions

    • Does every navigational control use an anchor with a valid href?
    • Is link text descriptive without relying on surrounding context alone?
    • Are external target=_blank links paired with rel=noopener noreferrer?
    • Can crawlers reach this URL from static href in HTML without JavaScript?
    • Are destructive actions avoided via GET links?
    • Do icon-only links have accessible names?

    Hands-on project

    Refactor a card grid from div-click navigation to semantic anchors; add skip link, aria-current on nav, and run linkinator + axe on built page.

    • Deliverable: Middle-click opens product in new tab works.
    • Verify: View crawled HTML — href present in SSR.
    • Stretch: Speculation Rules for top 3 likely next pages.

    Interview questions

    When is a button more correct than an anchor?(Advanced)

    When activation performs an in-page action without URL change: submit, open modal, expand accordion, add to cart via API. Buttons prevent accidental navigation and communicate role to AT. Anchors for href navigation — even in SPAs use href + enhance.

    Follow-up: How do SPAs keep SEO with client routing?

    Explain tabnabbing and the noopener fix.(Advanced)

    target=_blank gives new page window.opener reference to your page. Attacker can redirect opener via location. rel=noopener severs opener; noreferrer also strips Referer header. Always on third-party untrusted targets.

    Follow-up: Doesnoopener affect window.name?

    How do prefetch and prerender differ in impact on Core Web Vitals?(Advanced)

    prefetch loads resource low priority for likely next navigation; prerender builds full page — expensive. Over-prerender hurts LCP bandwidth on current page. Use Speculation Rules with eagerness conservative on mobile data.

    Follow-up: Same-origin prerender constraints?

    Try it yourself

    Edit the HTML, CSS, or JS panels — the preview updates as you type.

    Try it yourself

    Preview

    Summary

    Anchor elements connect the web — crawlers, users, and assistive technology all require valid href semantics. Staff patterns from BBC and Airbnb keep links in SSR HTML, descriptive, and secured with rel attributes on external targets.

    Ready to mark this lesson complete?Track your journey across the entire course.