2.3: Links & Navigation

Create hyperlinks and build navigation systems that connect your web pages together. Learn absolute vs relative URLs, link attributes, and best practices for site navigation.

1. The Anchor Element (<a>)

The <a> (anchor) element creates hyperlinks to other pages, files, locations, or any URL.

<a href="https://www.example.com">Visit Example</a>

Components:

  • <a> - Anchor element
  • href - Hypertext REFerence (the destination)
  • Link text - Visible clickable text

<a href="https://developer.mozilla.org">MDN Web Docs</a>

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

<a href="/documents/guide.pdf">Download Guide (PDF)</a>

<a href="#">Placeholder Link</a>

2. Absolute vs Relative URLs

Absolute URLs

Complete URL including protocol and domain.


<a href="https://www.example.com">Example</a>
<a href="https://www.google.com/search?q=html">Google Search</a>
<a href="https://github.com/your-username/repo">GitHub Repo</a>

When to use:

  • Linking to external websites
  • Linking to resources on different domains
  • API endpoints

Relative URLs

Path relative to current page or site root.


<a href="about.html">About</a>
<a href="contact.html">Contact</a>

<a href="../index.html">Back to Home</a>

<a href="/products/laptops.html">Laptops</a>
<a href="/css/style.css">Stylesheet</a>

Directory structure example:

website/
├── index.html
├── about.html
├── products/
│   ├── index.html
│   ├── laptops.html
│   └── phones.html
└── blog/
    ├── index.html
    └── posts/
        └── article-1.html

From index.html (root):

<a href="about.html">About</a>
<a href="products/laptops.html">Laptops</a>
<a href="blog/posts/article-1.html">Article 1</a>

From products/laptops.html:

<a href="../index.html">Home</a>
<a href="phones.html">Phones</a>
<a href="../blog/index.html">Blog</a>

From blog/posts/article-1.html:

<a href="../../index.html">Home</a>
<a href="../index.html">Blog Home</a>
<a href="../../products/laptops.html">Laptops</a>

Root-relative URLs (start with /):


<a href="/">Home</a>
<a href="/about.html">About</a>
<a href="/products/laptops.html">Laptops</a>

Best practice: Use root-relative URLs (/path) for internal links - they work from any page.


Opening in New Tab/Window


<a href="https://example.com" target="_blank">External Site</a>

<a href="https://example.com" target="_blank" rel="noopener noreferrer">
  External Site
</a>

target attribute values:

ValueDescription
_blankNew tab/window
_selfSame frame (default)
_parentParent frame
_topFull window

Security with target="_blank":

When using target="_blank", always include rel="noopener noreferrer":


<a href="https://external.com" target="_blank">Link</a>

<a href="https://external.com" target="_blank" rel="noopener noreferrer">
  Link
</a>

What rel values mean:

  • noopener - Prevents new page from accessing window.opener
  • noreferrer - Doesn't send referrer information
  • Both together provide best security

When to open in new tab:

  • External websites
  • PDFs and downloadable files
  • Links from modal dialogs or overlays
  • Internal site navigation should stay in same tab

Accessibility note: Inform users when link opens new tab:

<a href="https://example.com" target="_blank" rel="noopener noreferrer">
  External Site <span class="sr-only">(opens in new tab)</span>
</a>

<a href="https://example.com" target="_blank" rel="noopener noreferrer">
  External Site ↗
</a>

Link to specific sections within the same page or another page.

Creating Anchors with IDs


<section id="about">
  <h2>About Us</h2>
  <p>Company information...</p>
</section>

<section id="services">
  <h2>Our Services</h2>
  <p>What we offer...</p>
</section>

<section id="contact">
  <h2>Contact</h2>
  <p>Get in touch...</p>
</section>

Linking to Anchors


<nav>
  <a href="#about">About</a>
  <a href="#services">Services</a>
  <a href="#contact">Contact</a>
</nav>

<a href="/team.html#leadership">Leadership Team</a>
<a href="/docs.html#installation">Installation Guide</a>

<a href="#top">Back to Top</a>

<a href="#">Back to Top</a>

Table of Contents Example

<article>
  <h1>Complete HTML Guide</h1>

  
  <nav aria-label="Table of contents">
    <h2>Contents</h2>
    <ol>
      <li><a href="#introduction">Introduction</a></li>
      <li><a href="#elements">HTML Elements</a></li>
      <li><a href="#attributes">Attributes</a></li>
      <li><a href="#best-practices">Best Practices</a></li>
    </ol>
  </nav>

  
  <section id="introduction">
    <h2>Introduction</h2>
    <p>HTML is...</p>
  </section>

  <section id="elements">
    <h2>HTML Elements</h2>
    <p>Elements are...</p>
  </section>

  <section id="attributes">
    <h2>Attributes</h2>
    <p>Attributes provide...</p>
  </section>

  <section id="best-practices">
    <h2>Best Practices</h2>
    <p>Follow these guidelines...</p>
  </section>
</article>

Smooth Scrolling (CSS)

/* Smooth scroll to anchors */
html {
  scroll-behavior: smooth;
}


<a href="mailto:info@example.com">Email Us</a>

<a href="mailto:support@example.com?subject=Help Request">
  Contact Support
</a>

<a href="mailto:sales@example.com?subject=Product Inquiry&body=I'm interested in...">
  Sales Inquiry
</a>

<a href="mailto:info@example.com,support@example.com">
  Email Both
</a>

<a href="mailto:info@example.com?cc=manager@example.com&bcc=archive@example.com">
  Email with CC/BCC
</a>

URL encoding for special characters:


<a href="mailto:info@example.com?subject=Product%20Inquiry">Email</a>

<a href="mailto:info@example.com?body=Hello%0D%0AThank you">Email</a>

<a href="tel:+1234567890">Call Us: (123) 456-7890</a>

<a href="tel:+1-555-123-4567">+1 (555) 123-4567</a>

<a href="tel:+18005551234">1-800-555-1234</a>

Best practices:

  • Use international format: +[country code][number]
  • Remove spaces, dashes, parentheses from href
  • Display formatted number in link text

<a href="tel:+14155551234">+1 (415) 555-1234</a>

<a href="tel:(415) 555-1234">(415) 555-1234</a>

<a href="sms:+1234567890">Text Us</a>

<a href="sms:+1234567890?body=I'm interested in your services">
  Send SMS
</a>

Forcing File Download


<a href="/files/report.pdf" download>Download Report</a>

<a href="/files/doc_v2.pdf" download="Annual_Report_2024.pdf">
  Download Annual Report
</a>

<a href="/images/photo.jpg" download="vacation-photo.jpg">
  Download Photo
</a>

Note: download attribute only works for same-origin files.

File Type Indicators


<a href="/docs/manual.pdf" download>
  User Manual (PDF, 2.5 MB)
</a>

<a href="/data/export.csv" download>
  Export Data (CSV, 145 KB)
</a>

<a href="/media/presentation.pptx" download>
  Presentation (PPTX, 8.3 MB)
</a>

7. Navigation Menus

Basic Navigation

<nav aria-label="Main navigation">
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
    <li><a href="/services">Services</a></li>
    <li><a href="/portfolio">Portfolio</a></li>
    <li><a href="/contact">Contact</a></li>
  </ul>
</nav>

Multi-level Navigation

<nav aria-label="Main navigation">
  <ul>
    <li><a href="/">Home</a></li>

    <li>
      <a href="/products">Products</a>
      <ul>
        <li><a href="/products/laptops">Laptops</a></li>
        <li><a href="/products/phones">Phones</a></li>
        <li><a href="/products/tablets">Tablets</a></li>
      </ul>
    </li>

    <li>
      <a href="/support">Support</a>
      <ul>
        <li><a href="/support/faq">FAQ</a></li>
        <li><a href="/support/contact">Contact</a></li>
        <li><a href="/support/documentation">Docs</a></li>
      </ul>
    </li>

    <li><a href="/about">About</a></li>
  </ul>
</nav>

Horizontal Navigation (with CSS)

<nav class="main-nav">
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
    <li><a href="/services">Services</a></li>
    <li><a href="/contact">Contact</a></li>
  </ul>
</nav>

<style>
.main-nav ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  gap: 2rem;
}

.main-nav a {
  text-decoration: none;
  color: #333;
  padding: 0.5rem 1rem;
}

.main-nav a:hover {
  background: #f0f0f0;
  border-radius: 4px;
}

/* Active page indicator */
.main-nav a[aria-current="page"] {
  font-weight: bold;
  color: #0066cc;
}
</style>

Current Page Indicator

<nav>
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/about" aria-current="page">About</a></li>
    <li><a href="/contact">Contact</a></li>
  </ul>
</nav>

Accessibility: Use aria-current="page" to indicate current page


8. Breadcrumb Navigation

Breadcrumbs show the user's location in site hierarchy.

Basic Breadcrumbs

<nav aria-label="Breadcrumb">
  <ol>
    <li><a href="/">Home</a></li>
    <li><a href="/products">Products</a></li>
    <li><a href="/products/electronics">Electronics</a></li>
    <li aria-current="page">Laptops</li>
  </ol>
</nav>

Styled Breadcrumbs

<nav aria-label="Breadcrumb" class="breadcrumb">
  <ol>
    <li><a href="/">Home</a></li>
    <li><a href="/docs">Documentation</a></li>
    <li><a href="/docs/html">HTML</a></li>
    <li aria-current="page">Links</li>
  </ol>
</nav>

<style>
.breadcrumb ol {
  list-style: none;
  display: flex;
  gap: 0.5rem;
  padding: 0;
}

.breadcrumb li:not(:last-child)::after {
  content: "›";
  margin-left: 0.5rem;
  color: #666;
}

.breadcrumb a {
  text-decoration: none;
  color: #0066cc;
}

.breadcrumb a:hover {
  text-decoration: underline;
}

.breadcrumb li[aria-current="page"] {
  color: #666;
}
</style>
<nav aria-label="Breadcrumb">
  <ol itemscope itemtype="https://schema.org/BreadcrumbList">
    <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
      <a itemprop="item" href="/">
        <span itemprop="name">Home</span>
      </a>
      <meta itemprop="position" content="1" />
    </li>

    <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
      <a itemprop="item" href="/products">
        <span itemprop="name">Products</span>
      </a>
      <meta itemprop="position" content="2" />
    </li>

    <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
      <span itemprop="name">Laptops</span>
      <meta itemprop="position" content="3" />
    </li>
  </ol>
</nav>

Benefit: Rich snippets in search results



<a href="/report.pdf">Click here</a>
<a href="/about">Read more</a>
<a href="/products">Learn more</a>

<a href="/report.pdf">Download 2024 Annual Report (PDF)</a>
<a href="/about">Read about our company history</a>
<a href="/products">View our product catalog</a>

Why descriptive text matters:

  • Screen reader users navigate by links
  • Out-of-context links should be meaningful
  • Better SEO

Allow keyboard users to skip navigation:

<a href="#main-content" class="skip-link">Skip to main content</a>

<style>
.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  background: #000;
  color: #fff;
  padding: 8px;
}

.skip-link:focus {
  top: 0;
}
</style>

How it works:

  1. Hidden by default (positioned off-screen using CSS)
  2. Appears when focused (Tab key)
  3. Jumps to main content when clicked

ARIA Labels for Context


<article>
  <h2>Article Title 1</h2>
  <p>Article excerpt...</p>
  <a href="/article-1" aria-label="Read more about Article Title 1">
    Read more
  </a>
</article>

<article>
  <h2>Article Title 2</h2>
  <p>Article excerpt...</p>
  <a href="/article-2" aria-label="Read more about Article Title 2">
    Read more
  </a>
</article>

<a href="https://external.com" target="_blank" rel="noopener noreferrer">
  External Resource
  <span aria-label="(opens in new tab)">↗</span>
</a>

<a href="https://external.com" target="_blank" rel="noopener noreferrer">
  External Resource
  <svg aria-hidden="true" width="12" height="12">
    <use href="#icon-external"></use>
  </svg>
  <span class="sr-only">(opens in new tab)</span>
</a>

Focus Styles

Always provide visible focus indicators:

/* ❌ Bad: Removing focus outline */
a:focus {
  outline: none;
}

/* ✅ Good: Custom focus style */
a:focus {
  outline: 2px solid #0066cc;
  outline-offset: 2px;
}

/* Or custom style */
a:focus {
  box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.4);
  outline: none;
}

CSS Pseudo-classes

/* Default link state */
a {
  color: #0066cc;
  text-decoration: underline;
}

/* Visited links */
a:visited {
  color: #551a8b;
}

/* Hover state */
a:hover {
  color: #003d80;
  text-decoration: none;
}

/* Focus state (keyboard navigation) */
a:focus {
  outline: 2px solid #0066cc;
  outline-offset: 2px;
}

/* Active state (being clicked) */
a:active {
  color: #ff0000;
}

Order matters! Remember "LoVe HAte":

  1. Link (default)
  2. Visited
  3. Hover
  4. Active
<a href="/signup" class="btn btn-primary">Sign Up</a>
<a href="/learn-more" class="btn btn-secondary">Learn More</a>

<style>
.btn {
  display: inline-block;
  padding: 0.75rem 1.5rem;
  text-decoration: none;
  border-radius: 6px;
  font-weight: bold;
  text-align: center;
  transition: background 0.2s;
}

.btn-primary {
  background: #0066cc;
  color: white;
}

.btn-primary:hover {
  background: #0052a3;
}

.btn-secondary {
  background: #6c757d;
  color: white;
}

.btn-secondary:hover {
  background: #545b62;
}
</style>

11. Complete Navigation Example

A complete navigation system combines multiple types:

  1. Skip Link - Hidden link for keyboard users
    <a href="#main" class="skip-link">Skip to content</a>
    
  2. Site Header - Main navigation
    <header>
      <nav aria-label="Main navigation">
        <a href="/" aria-current="page">Home</a>
        <a href="/about">About</a>
      </nav>
    </header>
    
  3. Breadcrumb Navigation - Page hierarchy
    <nav aria-label="Breadcrumb">
      <ol>
        <li><a href="/">Home</a></li>
        <li>Current Page</li>
      </ol>
    </nav>
    
  4. Main Content - With anchor links
    <main id="main">
      <nav aria-label="Table of contents">
        <a href="#section1">Section 1</a>
      </nav>
    </main>
    
  5. Footer Navigation - Secondary links
    <footer>
      <nav aria-label="Footer navigation">
        <a href="/privacy">Privacy</a>
      </nav>
    </footer>
    

Key accessibility features:

  • Use aria-current="page" for current page
  • Provide aria-label for multiple <nav> elements
  • Include skip links for keyboard users

12. Practical Exercises

Create an HTML page with:

  1. Five internal links (relative URLs)
  2. Three external links (absolute URLs) with proper target and rel attributes
  3. An email link with subject and body
  4. A telephone link

Exercise 2.3.2: Anchor Navigation

Create a long-form article with:

  1. Table of contents at the top with links to each section
  2. At least 5 sections with unique IDs
  3. "Back to top" links at the end of each section
  4. Smooth scrolling enabled

Exercise 2.3.3: Multi-level Navigation

Build a navigation menu with:

  1. Main navigation with 5 top-level items
  2. Two items with dropdown/nested menus (2-3 sub-items each)
  3. Current page indicator using aria-current
  4. Proper semantic HTML and accessibility attributes

Exercise 2.3.4: Complete Site Navigation

Create a full page structure including:

  1. Skip link for accessibility
  2. Header with main navigation
  3. Breadcrumb navigation
  4. Main content with internal anchor links
  5. Footer navigation
  6. All with proper ARIA labels

13. Knowledge Check

Question 1: What's the difference between absolute and relative URLs?

Show answer Absolute URLs include the full path with protocol and domain (https://example.com/page), while relative URLs are paths relative to the current page or site root (/page or ../page).

Question 2: Why should you use rel="noopener noreferrer" with target="_blank"?

Show answer For security. Without it, the new page can access the original page via `window.opener`, potentially leading to security vulnerabilities. `noopener` prevents this access, and `noreferrer` prevents sending referrer information.

Question 3: How do you create a link to a specific section on the same page?

Show answer Add an `id` attribute to the target element, then use `Link text`. The `#` followed by the ID creates an anchor link.

Question 4: What makes link text accessible?

Show answer Descriptive link text that makes sense out of context. Avoid generic text like "click here" or "read more". Instead, describe what the link leads to: "Download 2024 Annual Report" or "Read our privacy policy".

Question 5: What is the purpose of a skip link?

Show answer Skip links allow keyboard users (especially screen reader users) to bypass repetitive navigation and jump directly to main content, improving accessibility and efficiency.

Question 6: What's the correct CSS order for link pseudo-classes?

Show answer LoVe HAte: :link, :visited, :hover, :active. This order matters because of CSS specificity - later rules override earlier ones if you don't follow this sequence.

14. Common Mistakes


<a href="/report.pdf">Click here</a>
<a href="/products">More</a>

<a href="/report.pdf">Download 2024 Annual Report (PDF)</a>
<a href="/products">View all products</a>

Missing Security Attributes


<a href="https://external.com" target="_blank">External</a>

<a href="https://external.com" target="_blank" rel="noopener noreferrer">
  External
</a>

Using <a> Without href


<a onclick="doSomething()">Click me</a>

<button onclick="doSomething()">Click me</button>

Removing Focus Outline

/* Bad (hurts accessibility) */
a:focus {
  outline: none;
}

/* Good (custom but visible) */
a:focus {
  outline: 2px solid #0066cc;
  outline-offset: 2px;
}

15. Key Takeaways

  • Use <a href="url"> for links - href attribute is required
  • Absolute URLs for external sites, relative URLs for internal pages
  • Root-relative URLs (/path) work from any page location
  • target="_blank" needs rel="noopener noreferrer" for security
  • Anchor links use #id to link to page sections
  • Descriptive link text is crucial for accessibility
  • Skip links improve keyboard navigation
  • aria-current="page" indicates current page in navigation
  • Focus styles must be visible for keyboard users
  • Use <nav> and ARIA labels for different navigation types

16. Further Resources

Official Documentation:

Accessibility:

Best Practices:


Next Steps

Great job! You now understand how to create effective, accessible navigation with HTML links.

In Lesson 2.4: Images & Media, you'll learn how to add images, optimize them for the web, and implement responsive images with modern techniques.