Module: HTML
HTML·004·9 MIN READ

004: Links and Navigation

TOPICS COVERED: Links and Navigation

Learning outcomes

By the end of this lesson, you can create useful hyperlinks with a and href, resolve relative paths from the current file, distinguish absolute URLs and fragments, use mailto: and tel: appropriately, and build consistent list-based navigation for a three-page website.

Prerequisites and retrieval

Bring the valid profile article from 003. Explain the roles of a URL's scheme, host, path, query, and fragment. Draw your portfolio folder as a tree; relative links are easiest when file location is visible.

Terminology

  • Hyperlink: A link created by an anchor with href that navigates users to another resource. — Source: WHATWG: Links
  • Anchor: “The a element … if it has an href attribute, then it represents a hyperlink.” — Source: WHATWG: The a element
  • Destination: The URL resolved from a link’s href attribute — where navigation goes. — Source: WHATWG: Links
  • Absolute URL: A complete URL including scheme and host, such as https://example.com/about. — Source: WHATWG URL Living Standard: URLs
  • Relative URL: A URL without scheme/host that is resolved against a base URL. — Source: WHATWG URL: Relative URL
  • Fragment: The part of a URL beginning with # identifying a section within the resource. — Source: WHATWG URL: Fragment
  • Root-relative URL: A path starting with “/” resolved from the site origin; formally a path-absolute URL string. — Source: WHATWG URL: Path-absolute
  • Navigation: A major group of links for moving through the site, typically wrapped in nav. — Source: WHATWG: The nav element
  • Link text: The visible words of a link describing destination or purpose; also its accessible name. — Source: WCAG 2.2: Link Purpose (In Context)
  • URL: "A URL is a string that identifies a resource and the mechanism to access it, composed of scheme, host, port, path, query, and fragment." — Source: WHATWG URL Living Standard
  • Origin: "An origin is the tuple (scheme, host, port) that identifies the trust boundary for a document." — Source: WHATWG URL: Origin
  • Base URL: "The URL against which a relative URL is resolved." — Source: WHATWG URL: Base URL
  • Percent-encoding: "Encoding of reserved characters as % followed by two hex digits." — Source: WHATWG URL: Percent-encode

Mental model: directions from where you stand

An absolute URL is a full postal address. A relative URL is a direction from the current document: “the file beside me,” “enter this folder,” or “go up one folder.” The same direction can lead elsewhere when the starting file changes.

Given:

text
portfolio/
├─ index.html
├─ about.html
├─ contact.html
└─ projects/
   └─ weather.html

From index.html, about.html points to its sibling. From projects/weather.html, about.html incorrectly means projects/about.html; use ../about.html to go up first. Forward slashes are URL separators, including on Windows.

html
<a href="about.html">About Asha</a>

The content is the link's accessible name. It should identify purpose in context. “Read Asha's biography” is more useful than “click here,” and it still makes sense in a list of links. Do not paste a long URL as text unless knowing the exact URL is itself useful.

Links navigate somewhere. Buttons perform an action on the current page, such as submitting a form. Do not use an anchor without href as a button, and do not use a button to navigate to another document.

Destination forms

html
<a href="https://developer.mozilla.org/">MDN Web Docs</a>
<a href="projects/weather.html">Weather project</a>
<a href="../index.html">Home</a>
<a href="#contact">Jump to contact details</a>
<a href="about.html#skills">Asha's skills</a>
<a href="mailto:asha@example.com">Email Asha</a>
<a href="tel:+15550123456">Call +1 555 012 3456</a>

mailto: and tel: invoke a configured application; they do not guarantee that email is sent or a call is made. Exposing an email address can attract spam. Display a human-readable phone number while using an international machine-friendly value where appropriate.

Fragments require a unique matching id:

html
<h2 id="skills">Skills</h2>

IDs must be unique in the document and should be stable, concise, and free of spaces. The browser can scroll and move focus behavior according to the target and user agent. Never create an empty link solely to fake spacing.

A link can do more than navigate in the current tab, but every extra behavior should have a reason.

html
<a href="report.pdf" download>Download the report</a>
<a href="https://external.example/guide" target="_blank" rel="noopener">Open external guide in a new tab</a>
  • download suggests that the target should be downloaded rather than navigated to. Browser and cross-origin restrictions can limit whether the suggestion is honored.
  • target="_blank" opens a new browsing context. Do not use it automatically: unexpected new tabs can disorient users. If you do use it, make the behavior understandable from context.
  • rel describes the relationship between the current document and the linked resource. Common values include noopener, noreferrer, nofollow, prev, and next, but each has a specific purpose.

Modern browsers treat many _blank links as if noopener were present, but writing the relationship explicitly can make security intent clear in maintained code. noreferrer additionally suppresses referrer information and therefore changes analytics and server behavior; do not add it casually.

A URL in href is data. If a destination is generated from untrusted input, validate it before placing it into markup. Avoid javascript: URLs: use real links for navigation and buttons for actions.

Guided example: create three pages

Create index.html, about.html, and contact.html as siblings. Each gets the 002 skeleton, a unique title, one h1, and identical navigation:

html
<header>
  <p>Asha Rao</p>
  <nav aria-label="Primary">
    <ul>
      <li><a href="index.html">Home</a></li>
      <li><a href="about.html">About</a></li>
      <li><a href="contact.html">Contact</a></li>
    </ul>
  </nav>
</header>

nav marks major navigation and a list groups the set. aria-label="Primary" gives this region a name; it is useful when a page may have multiple navigation regions. This is a restrained ARIA use, not a replacement for nav. If there is only one obvious navigation region, the label can be omitted.

Use this complete home page:

html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Home | Asha Rao</title>
  </head>
  <body>
    <header>
      <p>Asha Rao</p>
      <nav aria-label="Primary">
        <ul>
          <li><a href="index.html">Home</a></li>
          <li><a href="about.html">About</a></li>
          <li><a href="contact.html">Contact</a></li>
        </ul>
      </nav>
    </header>
    <main>
      <h1>Building clear, accessible interfaces — one semantic page at a time</h1>
      <p>I am building a portfolio one semantic page at a time.</p>
      <p><a href="about.html#skills">Explore my current skills</a></p>
    </main>
  </body>
</html>

On about.html, add <h2 id="skills">Current skills</h2>. On contact, add visible email and phone links. Test every link from every page, not only from Home. Use the address bar to observe the fragment.

Current-page links may remain links, which lets users return to the page top. A later accessibility enhancement can expose the current item with aria-current="page"; do not add it to every link, and update it separately on each page.

Intermediate example: add a nested project

Create projects/weather.html. Its navigation differs only in path resolution:

html
<nav aria-label="Primary">
  <ul>
    <li><a href="../index.html">Home</a></li>
    <li><a href="../about.html">About</a></li>
    <li><a href="../contact.html">Contact</a></li>
  </ul>
</nav>

Link to it from the home page using projects/weather.html. Trace both paths on the folder tree. Avoid /projects/weather.html during local learning: leading slash behavior differs under file: and when a site is hosted at https://host.example/my-portfolio/ rather than the origin root.

For an external project repository:

html
<a href="https://github.com/example/weather-project">Weather project source code</a>

Opening in a new tab is not a default requirement. It can disorient users and removes their choice. If a real requirement uses target="_blank", clearly indicate the new context. Modern browsers imply noopener for _blank, but explicit policies may still require rel="noopener"; do not add target casually.

Advanced optional extension: meaningful navigation states

On Home only:

html
<a href="index.html" aria-current="page">Home</a>

The native link still navigates; ARIA communicates current state. On About, move aria-current to About. This is enhancement of correct native HTML. Do not write role="navigation" on nav or role="link" on a; those duplicate native semantics.

Add a footer navigation with an explicit label only if it is genuinely useful:

html
<nav aria-label="Legal">
  <ul>
    <li><a href="privacy.html">Privacy</a></li>
  </ul>
</nav>

Different labels let landmark users distinguish navigation regions.

Common mistakes and debugging

  • Backslashes in URLs: use /, not \.
  • Wrong starting point: resolve each relative URL from the document containing the link.
  • Filename case mismatch: deployed servers may treat About.html and about.html differently.
  • Spaces and unstable names: prefer lowercase names such as weather-project.html.
  • Broken fragment: verify exact, unique target id.
  • href="#" placeholder: it unexpectedly jumps to the top; use a real destination or no unfinished control.
  • “Click here” repeated: rewrite text around destination or action.
  • Confusing link and button: navigation uses a[href]; actions use button.
  • Testing only locally: verify from the deployed base path as well.

Accessibility, security, and performance

Links must be operable by keyboard and have understandable purpose. Native anchors with href supply focus and activation behavior automatically. Keep navigation order and wording consistent across pages, supporting WCAG Consistent Navigation. Do not remove link underlines or focus indicators in HTML/CSS work without an accessible alternative.

External URLs can disclose the current page through referrer information. Avoid putting secrets in URLs. mailto: can expose addresses publicly; use a server-side contact form later if spam/privacy risk warrants it. Broken links waste time and requests, so include link checking in project review. Fragment navigation is fast and requires no new document request.

Tiered exercises

Level 1: paths

From projects/weather.html, write links to root index.html, sibling projects/gallery.html, and the #results section of the current page.

Level 2: site

Build Home/About/Contact pages with consistent list navigation, distinct titles and headings, an About skills fragment, and meaningful email/phone links.

Level 3: audit

Add one nested project page, mark the current navigation item, then keyboard-test and classify every link as internal, external, fragment, email, or telephone.

Level 1: <a href="../index.html">Home</a>, <a href="gallery.html">Gallery project</a>, and <a href="#results">Project results</a>.

Level 2: use the guided Home document on every page with page-specific title, h1, and body. About includes <h2 id="skills">Current skills</h2>. Contact includes <a href="mailto:asha@example.com">asha@example.com</a> and <a href="tel:+15550123456">+1 555 012 3456</a>. Every navigation URL is correct because files are siblings.

Level 3: nested project navigation uses ../. Exactly one primary navigation link per page has aria-current="page". A keyboard test reaches links in source order with visible browser focus and activates them using Enter. External links remain in the same tab unless a documented requirement says otherwise.

Recap and exit questions

Links connect resources; relative destinations depend on the current file. Link text names purpose, fragments target unique IDs, and list-based nav organizes major destinations.

  1. From which location is a relative URL resolved?
  2. Why does ../about.html work from a nested page?
  3. When should you use a button instead of a link?
  4. What is one privacy concern with mailto:?
  5. Why should new-tab behavior be exceptional?

Try it with your own example

Relative paths only click once you have been burned by a wrong one, so deliberately break one on purpose before you rely on this skill professionally.

Give Rina's site this structure:

text
rinas-kitchen/
├─ index.html
├─ menu.html
├─ order.html
└─ menu/
   └─ sourdough.html

From menu/sourdough.html, write a link back to the main menu and a link to place an order. Get it wrong first, on purpose:

html
<a href="menu.html">Back to full menu</a>

Open menu/sourdough.html directly in your browser and click it. It will fail, because from inside menu/, menu.html means menu/menu.html, which does not exist. Now fix it yourself before reading the answer:

html
<a href="../menu.html">Back to full menu</a>
<a href="../order.html">Order this loaf</a>

You just reproduced, in miniature, the single most common bug beginners ship to a live server: a link that worked while every file sat in one folder, then broke the moment a project grew a subfolder. Deliberately causing it once, on a page nobody depends on, is worth more than reading about it three times.

Further reading: MDN — File paths covers the same ../ mechanics with a different folder example if you want a second worked case.

Official references