HTML Links & Anchors
Hyperlinks are the foundation of the web. The <a> element creates a clickable link to another resource — a web page, file, email address, phone number, or a specific location within the same document. The href attribute defines the destination, while target, rel, and download control how the link behaves.
Links are also critical for accessibility and SEO. Screen readers announce links and their destinations, search engines follow links to discover and rank content, and users rely on visual cues like link states to navigate confidently. Understanding every aspect of the anchor element is essential for building connected, navigable web experiences.
info
The <a> element requires an href attribute to function as a link. Without it, the element renders as plain text (or a placeholder if styled). The target attribute controls where the linked page opens, and rel defines the relationship between the current page and the linked resource.
| Attribute | Required | Values | Description |
|---|---|---|---|
| href | Yes | URL, fragment, protocol | Link destination |
| target | No | _self | _blank | _parent | _top | Browsing context for navigation |
| rel | No | noopener | noreferrer | nofollow | sponsored | ugc | Relationship to linked resource |
| download | No | filename | Prompts download instead of navigation |
| hreflang | No | BCP 47 language tag | Language of the linked resource |
| type | No | MIME type | Hint for the linked resource type |
| 1 | <!-- Basic link --> |
| 2 | <a href="https://example.com"> |
| 3 | Visit Example |
| 4 | </a> |
| 5 | |
| 6 | <!-- Link opening in new tab with security attributes --> |
| 7 | <a |
| 8 | href="https://example.com" |
| 9 | target="_blank" |
| 10 | rel="noopener noreferrer" |
| 11 | > |
| 12 | Open in new tab (secure) |
| 13 | </a> |
| 14 | |
| 15 | <!-- Styled as a button --> |
| 16 | <a href="/signup" class="btn"> |
| 17 | Sign Up |
| 18 | </a> |
| 19 | |
| 20 | <!-- Link with title tooltip --> |
| 21 | <a |
| 22 | href="https://developer.mozilla.org" |
| 23 | title="MDN Web Docs — comprehensive web development documentation" |
| 24 | > |
| 25 | MDN Web Docs |
| 26 | </a> |
| 27 | |
| 28 | <!-- Language hint --> |
| 29 | <a |
| 30 | href="https://es.example.com" |
| 31 | hreflang="es" |
| 32 | lang="es" |
| 33 | > |
| 34 | Documentación en Español |
| 35 | </a> |
Live preview of basic link examples:
The href attribute accepts multiple URL types. Understanding the difference between absolute, relative, and protocol-based URLs is essential for building links that work correctly in all contexts.
| Type | Example | Resolves To |
|---|---|---|
| Absolute URL | https://example.com/page | A specific resource on the web |
| Relative (same directory) | page.html | Relative to current page directory |
| Relative (subdirectory) | docs/page.html | Descendant path |
| Relative (parent) | ../page.html | Parent directory traversal |
| Root-relative | /docs/page.html | Relative to site root |
| Fragment | #section-id | Same-page anchor |
| Mailto | mailto:user@example.com | Opens email client |
| Telephone | tel:+1234567890 | Dials phone number (mobile) |
| SMS | sms:+1234567890 | Opens SMS app (mobile) |
| JavaScript (avoid) | javascript:void(0) | Anti-pattern — use event handlers |
| 1 | <!-- Absolute URL --> |
| 2 | <a href="https://www.w3.org/TR/html52/"> |
| 3 | HTML 5.2 Specification |
| 4 | </a> |
| 5 | |
| 6 | <!-- Relative URL (same directory) --> |
| 7 | <a href="about.html">About Us</a> |
| 8 | |
| 9 | <!-- Relative URL (subdirectory) --> |
| 10 | <a href="docs/installation.html">Installation Guide</a> |
| 11 | |
| 12 | <!-- Relative URL (parent directory) --> |
| 13 | <a href="../index.html">Back to Home</a> |
| 14 | |
| 15 | <!-- Root-relative URL --> |
| 16 | <a href="/docs/html/links">Links Documentation</a> |
| 17 | |
| 18 | <!-- Fragment identifier (same page) --> |
| 19 | <a href="#introduction">Jump to Introduction</a> |
| 20 | |
| 21 | <!-- Fragment identifier (different page) --> |
| 22 | <a href="docs/installation.html#prerequisites"> |
| 23 | Installation Prerequisites |
| 24 | </a> |
| 25 | |
| 26 | <!-- Mailto link --> |
| 27 | <a href="mailto:hello@example.com?subject=Inquiry&body=Hello,%20I%20have%20a%20question."> |
| 28 | Send Email |
| 29 | </a> |
| 30 | |
| 31 | <!-- Telephone link --> |
| 32 | <a href="tel:+1234567890">Call (123) 456-7890</a> |
| 33 | |
| 34 | <!-- SMS link --> |
| 35 | <a href="sms:+1234567890?body=Hello">Send Text</a> |
best practice
The target attribute controls where the linked resource opens. If omitted, _self is the default — the link opens in the same browsing context. The most commonly used alternative is _blank, which opens in a new tab or window.
| Value | Behavior | Use Case |
|---|---|---|
| _self | Opens in current browsing context | Default — most internal links |
| _blank | Opens in a new tab or window | External links, downloadable files |
| _parent | Opens in the parent frame | Frameset / iframe navigation |
| _top | Opens in the full window body | Breaking out of a frameset |
| framename | Opens in a named frame or iframe | Legacy — avoid in modern sites |
| 1 | <!-- Default behavior (_self) — same tab --> |
| 2 | <a href="/about">About Us (same tab)</a> |
| 3 | |
| 4 | <!-- New tab/window (_blank) — requires security attributes --> |
| 5 | <a |
| 6 | href="https://external-site.com" |
| 7 | target="_blank" |
| 8 | rel="noopener noreferrer" |
| 9 | > |
| 10 | External Resource (new tab) |
| 11 | </a> |
| 12 | |
| 13 | <!-- Parent frame navigation --> |
| 14 | <a href="/full-page" target="_parent"> |
| 15 | Load in parent frame |
| 16 | </a> |
| 17 | |
| 18 | <!-- Top-level navigation (break out of frames) --> |
| 19 | <a href="/home" target="_top"> |
| 20 | Back to full site |
| 21 | </a> |
| 22 | |
| 23 | <!-- Named iframe target --> |
| 24 | <iframe name="content-frame" src="default.html"></iframe> |
| 25 | <a href="page.html" target="content-frame"> |
| 26 | Load in iframe |
| 27 | </a> |
warning
The rel attribute defines the relationship between the current page and the linked resource. It serves dual purposes: security (preventing tabnapping) and SEO (communicating link intent to search engines). Multiple values can be space-separated.
| Value | Purpose | Required With _blank |
|---|---|---|
| noopener | Prevents access to window.opener | Yes |
| noreferrer | Hides the Referer header + implies noopener | Yes |
| nofollow | Tells search engines not to pass ranking credit | No |
| sponsored | Links created as part of advertisements or sponsorships | No |
| ugc | User-generated content links (comments, forum posts) | No |
| external | Indicates the linked page is external | No |
| prev / next | Pagination — previous and next page in a series | No |
| canonical | Declares the canonical/preferred URL for a page | No |
| 1 | <!-- External link with full security attributes --> |
| 2 | <a |
| 3 | href="https://partner-site.com" |
| 4 | target="_blank" |
| 5 | rel="noopener noreferrer" |
| 6 | > |
| 7 | Partner Website |
| 8 | </a> |
| 9 | |
| 10 | <!-- User-generated content link --> |
| 11 | <a |
| 12 | href="https://spammy-site.com" |
| 13 | rel="nofollow ugc noopener" |
| 14 | target="_blank" |
| 15 | > |
| 16 | Commenter's Link |
| 17 | </a> |
| 18 | |
| 19 | <!-- Sponsored/advertorial link --> |
| 20 | <a |
| 21 | href="https://sponsor.com" |
| 22 | rel="sponsored noopener noreferrer" |
| 23 | target="_blank" |
| 24 | > |
| 25 | Sponsored Content |
| 26 | </a> |
| 27 | |
| 28 | <!-- Pagination links --> |
| 29 | <a href="/page/2" rel="prev">Previous Page</a> |
| 30 | <a href="/page/4" rel="next">Next Page</a> |
| 31 | |
| 32 | <!-- External link icon indicator --> |
| 33 | <a |
| 34 | href="https://external-site.com" |
| 35 | target="_blank" |
| 36 | rel="noopener noreferrer" |
| 37 | class="external-link" |
| 38 | > |
| 39 | Visit External Site |
| 40 | <span class="external-icon" aria-hidden="true">↗</span> |
| 41 | </a> |
best practice
The download attribute turns a link into a file download prompt instead of navigating to the resource. The attribute optionally accepts a filename that becomes the suggested filename in the download dialog. This works for same-origin URLs and blob/data URLs.
| 1 | <!-- Basic download link --> |
| 2 | <a href="/files/report-2026.pdf" download> |
| 3 | Download Annual Report (PDF) |
| 4 | </a> |
| 5 | |
| 6 | <!-- Download with suggested filename --> |
| 7 | <a |
| 8 | href="/files/report-2026.pdf" |
| 9 | download="Annual-Report-2026.pdf" |
| 10 | > |
| 11 | Download as "Annual-Report-2026.pdf" |
| 12 | </a> |
| 13 | |
| 14 | <!-- Downloading generated content (blob URL) --> |
| 15 | <a |
| 16 | id="exportCSV" |
| 17 | href="#" |
| 18 | download="export.csv" |
| 19 | onclick="generateCSV(event)" |
| 20 | > |
| 21 | Export to CSV |
| 22 | </a> |
| 23 | |
| 24 | <script> |
| 25 | function generateCSV(event) { |
| 26 | event.preventDefault(); |
| 27 | const csv = "Name,Email,Role\nJane,jane@example.com,Engineer\n"; |
| 28 | const blob = new Blob([csv], { type: "text/csv" }); |
| 29 | const url = URL.createObjectURL(blob); |
| 30 | const link = document.getElementById("exportCSV"); |
| 31 | link.href = url; |
| 32 | link.click(); |
| 33 | URL.revokeObjectURL(url); |
| 34 | } |
| 35 | </script> |
| 36 | |
| 37 | <!-- Download multiple file types --> |
| 38 | <ul> |
| 39 | <li><a href="/files/report.pdf" download>PDF (2.4 MB)</a></li> |
| 40 | <li><a href="/files/report.docx" download>Word (1.1 MB)</a></li> |
| 41 | <li><a href="/files/report.txt" download>Plain Text (340 KB)</a></li> |
| 42 | </ul> |
info
Fragment identifiers (also called anchor links or hash links) link to a specific section within a page. The fragment is the part of the URL after the # symbol and corresponds to the id attribute of the target element. When clicked, the browser scrolls the target element into view.
| 1 | <!-- Same-page fragment links --> |
| 2 | <nav aria-label="Table of Contents"> |
| 3 | <ul> |
| 4 | <li><a href="#introduction">Introduction</a></li> |
| 5 | <li><a href="#features">Features</a></li> |
| 6 | <li><a href="#pricing">Pricing</a></li> |
| 7 | <li><a href="#contact">Contact</a></li> |
| 8 | </ul> |
| 9 | </nav> |
| 10 | |
| 11 | <!-- Target sections with matching IDs --> |
| 12 | <section id="introduction"> |
| 13 | <h2>Introduction</h2> |
| 14 | <p>Content here...</p> |
| 15 | </section> |
| 16 | |
| 17 | <section id="features"> |
| 18 | <h2>Features</h2> |
| 19 | <p>Content here...</p> |
| 20 | </section> |
| 21 | |
| 22 | <section id="pricing"> |
| 23 | <h2>Pricing</h2> |
| 24 | <p>Content here...</p> |
| 25 | </section> |
| 26 | |
| 27 | <section id="contact"> |
| 28 | <h2>Contact</h2> |
| 29 | <p>Content here...</p> |
| 30 | </section> |
| 31 | |
| 32 | <!-- Fragment link to another page --> |
| 33 | <a href="/docs/html/links#fragment-identifiers"> |
| 34 | Learn about fragment identifiers |
| 35 | </a> |
| 36 | |
| 37 | <!-- Fragment with smooth scrolling --> |
| 38 | <style> |
| 39 | html { |
| 40 | scroll-behavior: smooth; |
| 41 | } |
| 42 | |
| 43 | /* Offset for fixed headers */ |
| 44 | section[id] { |
| 45 | scroll-margin-top: 80px; |
| 46 | } |
| 47 | </style> |
| 48 | |
| 49 | <!-- Back to top link --> |
| 50 | <a href="#">Back to Top</a> |
| 51 | |
| 52 | <!-- Breadcrumb with fragment --> |
| 53 | <nav aria-label="Breadcrumb"> |
| 54 | <ol> |
| 55 | <li><a href="/docs">Docs</a></li> |
| 56 | <li><a href="/docs/html">HTML</a></li> |
| 57 | <li><a href="/docs/html/links#introduction">Links</a></li> |
| 58 | </ol> |
| 59 | </nav> |
pro tip
Links have four primary interactive states, each styled with a CSS pseudo-class: :link (unvisited), :visited (visited), :hover (mouse over), :focus (keyboard focused), and :active (being clicked). Styling these states provides critical visual feedback.
| Pseudo-class | When Applied | Typical Style |
|---|---|---|
| :link | Unvisited link | Default color (blue) |
| :visited | Link has been visited by the user | Different color (purple) |
| :hover | Mouse cursor is over the link | Underline, color change |
| :focus | Element has keyboard focus (Tab) | Outline or ring |
| :active | Link is being clicked/activated | Brief color flash |
| :focus-visible | Focus when user-agent determines it should be visible | Outline (keyboard only) |
| 1 | /* LVHFA order: Link, Visited, Hover, Focus, Active */ |
| 2 | /* This order is important for proper cascade */ |
| 3 | |
| 4 | a:link { |
| 5 | color: #0066cc; |
| 6 | text-decoration: none; |
| 7 | } |
| 8 | |
| 9 | a:visited { |
| 10 | color: #551a8b; |
| 11 | } |
| 12 | |
| 13 | a:hover { |
| 14 | color: #004499; |
| 15 | text-decoration: underline; |
| 16 | text-underline-offset: 3px; |
| 17 | } |
| 18 | |
| 19 | a:focus { |
| 20 | outline: 2px solid #0066cc; |
| 21 | outline-offset: 2px; |
| 22 | border-radius: 2px; |
| 23 | } |
| 24 | |
| 25 | a:focus-visible { |
| 26 | outline: 2px solid #0066cc; |
| 27 | outline-offset: 2px; |
| 28 | } |
| 29 | |
| 30 | /* Remove focus outline for mouse clicks only */ |
| 31 | a:focus:not(:focus-visible) { |
| 32 | outline: none; |
| 33 | } |
| 34 | |
| 35 | a:active { |
| 36 | color: #003366; |
| 37 | } |
| 38 | |
| 39 | /* Button-style link */ |
| 40 | a.btn { |
| 41 | display: inline-block; |
| 42 | padding: 10px 24px; |
| 43 | background: #0066cc; |
| 44 | color: white !important; |
| 45 | border-radius: 6px; |
| 46 | font-weight: 500; |
| 47 | transition: all 0.2s ease; |
| 48 | text-decoration: none !important; |
| 49 | } |
| 50 | |
| 51 | a.btn:hover { |
| 52 | background: #004499; |
| 53 | transform: translateY(-1px); |
| 54 | } |
| 55 | |
| 56 | a.btn:focus { |
| 57 | outline: 2px solid #0066cc; |
| 58 | outline-offset: 2px; |
| 59 | } |
| 60 | |
| 61 | a.btn:active { |
| 62 | background: #003366; |
| 63 | transform: translateY(0); |
| 64 | } |
Live preview of all link states:
best practice
Wrapping an <img> in an <a> creates a clickable image link. This is common for product thumbnails, banner ads, profile photos, and gallery images. The alt attribute on the image becomes the link text for screen readers — so it must describe the link destination, not just the image.
| 1 | <!-- Basic image link --> |
| 2 | <a href="/products/item-123"> |
| 3 | <img |
| 4 | src="product-thumbnail.jpg" |
| 5 | alt="View product: Wireless Headphones Pro — $199" |
| 6 | width="300" |
| 7 | height="300" |
| 8 | loading="lazy" |
| 9 | /> |
| 10 | </a> |
| 11 | |
| 12 | <!-- Logo linking to homepage --> |
| 13 | <a href="/" aria-label="Return to homepage"> |
| 14 | <img |
| 15 | src="logo.svg" |
| 16 | alt="Company Name" |
| 17 | width="180" |
| 18 | height="40" |
| 19 | /> |
| 20 | </a> |
| 21 | |
| 22 | <!-- Image gallery item --> |
| 23 | <a |
| 24 | href="/gallery/photo-001-full.jpg" |
| 25 | class="gallery-item" |
| 26 | aria-label="View full-size: Mountain Sunrise" |
| 27 | > |
| 28 | <img |
| 29 | src="photo-001-thumb.jpg" |
| 30 | alt="Mountain Sunrise" |
| 31 | width="400" |
| 32 | height="300" |
| 33 | loading="lazy" |
| 34 | /> |
| 35 | </a> |
| 36 | |
| 37 | <!-- Banner ad --> |
| 38 | <a |
| 39 | href="https://sponsor.com/offer" |
| 40 | rel="sponsored noopener noreferrer" |
| 41 | target="_blank" |
| 42 | > |
| 43 | <img |
| 44 | src="banner-ad.jpg" |
| 45 | alt="Special offer: 20% off all plans — limited time" |
| 46 | width="728" |
| 47 | height="90" |
| 48 | /> |
| 49 | </a> |
info
Accessible links are critical for keyboard and screen reader users. Link text must be descriptive, focus indicators must be visible, and navigation patterns like skip links must be available. The Web Content Accessibility Guidelines (WCAG) specify several success criteria for links.
| Technique | WCAG Criterion | Implementation |
|---|---|---|
| Descriptive link text | 2.4.4 Link Purpose (In Context) | Never use "click here" — describe the destination |
| Focus indicator | 2.4.7 Focus Visible | Always provide visible focus styles |
| Skip link | 2.4.1 Bypass Blocks | First focusable element on the page |
| New window warning | 3.2.5 Change on Request | Indicate when links open in a new window |
| ARIA labels | 4.1.2 Name, Role, Value | Use aria-label when link text alone is insufficient |
| Adjacent links | 2.4.4 Link Purpose | Combine identical adjacent links into one |
| 1 | <!-- Skip link: first focusable element --> |
| 2 | <a href="#main-content" class="skip-link"> |
| 3 | Skip to main content |
| 4 | </a> |
| 5 | |
| 6 | <style> |
| 7 | .skip-link { |
| 8 | position: absolute; |
| 9 | top: -100%; |
| 10 | left: 8px; |
| 11 | background: #000; |
| 12 | color: #fff; |
| 13 | padding: 8px 16px; |
| 14 | z-index: 10000; |
| 15 | } |
| 16 | |
| 17 | .skip-link:focus { |
| 18 | top: 8px; |
| 19 | } |
| 20 | </style> |
| 21 | |
| 22 | <!-- Descriptive link text — good --> |
| 23 | <a href="/docs/installation"> |
| 24 | Read the installation guide for Linux systems |
| 25 | </a> |
| 26 | |
| 27 | <!-- Descriptive link text — bad --> |
| 28 | <a href="/docs/installation">Click here</a> |
| 29 | to read the installation guide. |
| 30 | |
| 31 | <!-- Screen reader only text for additional context --> |
| 32 | <a href="/reports/q1-2026.pdf"> |
| 33 | Q1 2026 Financial Report |
| 34 | <span class="sr-only">(PDF, 2.4 MB)</span> |
| 35 | </a> |
| 36 | |
| 37 | <!-- External link with new window warning --> |
| 38 | <a |
| 39 | href="https://external-site.com" |
| 40 | target="_blank" |
| 41 | rel="noopener noreferrer" |
| 42 | > |
| 43 | Visit Partner Site |
| 44 | <span class="sr-only">(opens in new tab)</span> |
| 45 | <span aria-hidden="true">↗</span> |
| 46 | </a> |
| 47 | |
| 48 | <!-- Icon-only link with aria-label --> |
| 49 | <a |
| 50 | href="/profile" |
| 51 | aria-label="View your profile" |
| 52 | > |
| 53 | <svg aria-hidden="true" width="24" height="24">...</svg> |
| 54 | </a> |
| 55 | |
| 56 | <!-- Multiple identical links combined --> |
| 57 | <!-- Instead of: --> |
| 58 | <div class="card"> |
| 59 | <a href="/product/123">Product Name</a> |
| 60 | <p>Description...</p> |
| 61 | <a href="/product/123">View Details</a> |
| 62 | </div> |
| 63 | |
| 64 | <!-- Do this: --> |
| 65 | <article> |
| 66 | <a href="/product/123"> |
| 67 | <h3>Product Name</h3> |
| 68 | <p>Description...</p> |
| 69 | <span>View Details →</span> |
| 70 | </a> |
| 71 | </article> |
Live preview of accessible link patterns:
best practice
Security: The _blank Rule
The most important security rule for links is: always pair target="_blank" with rel="noopener noreferrer". Without this, the opened page gains partial access to the original page via window.opener and can redirect it to a phishing site (a technique called tabnapping). Modern browsers default <a> with _blank to rel="noopener", but explicitly including it ensures protection everywhere.
Link Text Guidelines
SEO & Rel Values
Live preview of a production-ready link implementation with all best practices: