Accessible Links
How to handle external links and file downloads with clear accessibility indicators.
The Bad (Inaccessible)
<a href="report.pdf" target="_blank">Download Report</a>
Accessibility-Ready Code
<!-- 1. Download Link (PDF) -->
<a href="report.pdf" download target="_blank" rel="noopener noreferrer" class="accessible-link">
Download Annual Report
<span class="sr-only">(PDF, 2.4MB, opens in new window)</span>
<svg class="icon" aria-hidden="true" viewBox="0 0 24 24" width="16" height="16">
<path d="M14,3V5H17.59L7.76,14.83L9.17,16.24L19,6.41V10H21V3M19,19H5V5H12V3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V12H19V19Z" />
</svg>
</a>
<!-- 2. External Link (opens in new window) -->
<a href="https://example.com" target="_blank" rel="noopener noreferrer" class="accessible-link">
Visit Partner Site
<span class="sr-only">(opens in new window)</span>
<svg class="icon" aria-hidden="true" viewBox="0 0 24 24" width="16" height="16">
<path d="M14,3V5H17.59L7.76,14.83L9.17,16.24L19,6.41V10H21V3M19,19H5V5H12V3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V12H19V19Z" />
</svg>
</a>
<!-- 3. Internal Link (Standard) -->
<a href="/about" class="accessible-link">
About Us
</a>
// 1. Download Link (PDF)
a(href="report.pdf" download target="_blank" rel="noopener noreferrer" class="accessible-link")
| Download Annual Report
span.sr-only (PDF, 2.4MB, opens in new window)
svg.icon(aria-hidden="true" viewBox="0 0 24 24" width="16" height="16")
path(d="M14,3V5H17.59L7.76,14.83L9.17,16.24L19,6.41V10H21V3M19,19H5V5H12V3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V12H19V19Z")
// 2. External Link (opens in new window)
a(href="https://example.com" target="_blank" rel="noopener noreferrer" class="accessible-link")
| Visit Partner Site
span.sr-only (opens in new window)
svg.icon(aria-hidden="true" viewBox="0 0 24 24" width="16" height="16")
path(d="M14,3V5H17.59L7.76,14.83L9.17,16.24L19,6.41V10H21V3M19,19H5V5H12V3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V12H19V19Z")
// 3. Internal Link (Standard)
a(href="/about" class="accessible-link") About Us
<>
{/* 1. Download/External with Warnings */}
<a href="report.pdf" target="_blank" rel="noopener noreferrer" className="accessible-link">
Download Annual Report
<span className="sr-only">(PDF, 2.4MB, opens in new window)</span>
<ExternalIcon aria-hidden="true" />
</a>
{/* 2. Standard Internal */}
<a href="/about" className="accessible-link">
About Us
</a>
</>
<!-- Use props to switch between styles -->
<a :href="url" :target="isExternal ? '_blank' : null" :rel="isExternal ? 'noopener' : null">
<slot />
<template v-if="isExternal">
<span class="sr-only">(opens in new window)</span>
<ExternalIcon aria-hidden="true" />
</template>
</a>
<div class="flex flex-col gap-4">
<!-- External -->
<a href="#" target="_blank" class="inline-flex items-center gap-1 text-blue-600 hover:underline">
Visit Partner Site <span class="sr-only">(opens in new window)</span>
<svg class="w-4 h-4" aria-hidden="true" fill="currentColor"><path d="M14,3V5H17.59L7.76,14.83L9.17,16.24L19,6.41V10H21V3M19,19H5V5H12V3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V12H19V19Z" /></svg>
</a>
<!-- Internal -->
<a href="/about" class="text-blue-600 hover:underline">About Us</a>
</div>
The Standard
When a link opens in a new window or leads to a file download (like a PDF), itโs critical to inform the user before they click. Unexpected context changes can be disorienting, especially for users with cognitive disabilities or those using screen readers.
WCAG Criteria
- 2.4.4 Link Purpose: The purpose of each link can be determined from the link text alone.
- 4.1.2 Name, Role, Value: States and properties are programmatically determinable.
โ The Bad (Inaccessible)
Whatโs Wrong?
- Unexpected Behavior: Users arenโt warned that a new tab will open.
- Missing File Info: No indication that the link downloads a large file.
- Security Risk: Missing
rel="noopener"can lead to performance and security issues in older browsers.
โ The Good (Accessibility-Ready Code)
Why This Works
- Clear Context: Hidden text (
.sr-only) provides specific details to screen reader users without cluttering the UI. - Visual Cues: An icon indicates an external or new-window link for sighted users.
- Best Practices: Includes
rel="noopener noreferrer"for security and follows modern link standards.
Accessibility Checklist
- Use
target="_blank"only when necessary (e.g., to avoid breaking a flow). - Provide a visual icon indicating an external link or new window.
- Incorporate hidden text for screen readers describing the file type or window behavior.
- Always include
rel="noopener noreferrer"for new-window links. - Ensure link text is descriptive (e.g., โDownload 2023 Reportโ instead of โClick Hereโ).
<a href="stats.pdf" target="_blank" rel="noopener">
Quarterly Stats
<span class="sr-only">(PDF, opens in new window)</span>
<svg>...</svg>
</a>
Technical Deep Dive
Screen Reader Announcements
- VoiceOver: โDownload Annual Report, PDF, 2.4 megabytes, opens in new window, linkโ
- NVDA: โDownload Annual Report PDF 2.4 megabytes opens in new window linkโ
CSS Technique
The .sr-only class is essential for providing descriptions that donโt appear visually but are perfectly readable by assistive technology.
Interactive Behavioral Lab
Interactive Sandbox
๐ฌ Technical Internals
Understand how this component is processed by the browser and Assistive Technology (AT). This section bridges the gap between visual code and the hidden logic that powers accessibility.
๐ฒ Accessibility Tree
The data structure used by screen readers to "see" your page. It translates HTML roles and attributes into standardized objects.
โ๏ธ Event Logic
Expected behavioral standards for keyboard navigation and state transitions. Crucial for users who don't use a mouse.
- Focus: Highlights via
:focus-visible - Activation: Responds to
EnterandSpace - Role: Identified as
Link