HTML Internal Links
Open any good book and you will find two kinds of help for moving around. There is the table of contents, which sends you to a chapter, and the page numbers that tell you where you are. Websites have the same needs. Visitors want to move between your pages, and on a long page they want to jump straight to the part they care about.
Both are done with internal links: links that stay inside your own website. In this lesson, you will learn the three kinds, from simple page-to-page links to a smooth table of contents and a "skip to content" link that makes your site friendlier for keyboard users.
What You Will Learnβ
- What makes a link internal
- How to link from one page of your site to another
- How to give a section an
idand jump to it - How to link to a section on another page
- How to build a table of contents, a back-to-top link, and a skip link
- How to add smooth scrolling and avoid hidden headings under sticky menus
- Accessibility and global tips, plus common mistakes
Three Kinds of Internal Linksβ
| Kind | What it does | Example href |
|---|---|---|
| Page to page | Opens another page on your site | about.html or /about |
| Same-page jump | Scrolls to a section of the current page | #pricing |
| Page and section | Opens another page and scrolls to a section of it | guide.html#install |
You already know how paths work from the Relative URLs lesson. Internal links simply put those paths to work.
1. Linking From Page to Pageβ
Use a relative URL to connect your own pages. The browser keeps the visitor on your site, and keeps the same scheme and host.
- HTML Code
- Browser Output
<nav>
<a href="index.html">Home</a>
<a href="courses.html">Courses</a>
<a href="blog/index.html">Blog</a>
<a href="contact.html">Contact</a>
</nav>
The demo links point to # so they stay on this page. In your own project, each one would open the file named in href.
In a menu, it helps visitors to show which page they are on. Add aria-current="page" to that link, and style it with CSS: a[aria-current="page"] { font-weight: 700; }. Screen readers will announce it as the current page.
2. Jumping Within the Same Pageβ
On a long page, you can let visitors jump to a section in two steps.
- Give the target an
id. This is the name of the spot. - Link to it with
#and that name. The#means "a place on this page."
- HTML Code
- Browser Output
<p><a href="#install">Jump to Installation</a></p>
<h2 id="intro">Introduction</h2>
<p>Welcome to the guide...</p>
<h2 id="install">Installation</h2>
<p>First, download the tools...</p>
Introduction
Welcome to the guide. Scroll down, or click the link above.
Installation
First, download the tools you need.
Clicking the link scrolls the page so that the element with id="install" comes into view. The address in the browser also changes to end with #install, which means a visitor can bookmark or share that exact spot.
Rules for Good id Valuesβ
| Rule | Good | Avoid |
|---|---|---|
| Must be unique on the page | install once only | The same id used twice |
| No spaces | getting-started | getting started |
| Case matters | Install and install are different | Mixing capitals by accident |
| Use simple, meaningful words | pricing, faq | section1, a, x7 |
| Prefer lowercase, numbers, and hyphens | step-2-setup | Symbols such as # and & |
name attribute?Older tutorials create targets with <a name="install"></a>. That is outdated. Put an id on the element itself, such as the heading, as shown above.
3. Linking to a Section on Another Pageβ
Combine a page path with a fragment. The browser loads the page, then scrolls to the id.
<a href="guide.html#install">See the installation steps</a>
<a href="/docs/setup#requirements">Check the requirements</a>
This is very useful for a home page that points to specific parts of longer pages, and for search results that take readers straight to the answer.
Building a Table of Contentsβ
A table of contents is a list of same-page links. It saves readers time on long articles.
- HTML Code
- Browser Output
<nav aria-label="Table of contents">
<h2>On this page</h2>
<ol>
<li><a href="#what">What is HTML?</a></li>
<li><a href="#tags">Tags and elements</a></li>
<li><a href="#first-page">Your first page</a></li>
</ol>
</nav>
<h2 id="what">What is HTML?</h2>
<p>...</p>
<h2 id="tags">Tags and elements</h2>
<p>...</p>
<h2 id="first-page">Your first page</h2>
<p>...</p>
What is HTML?
HTML is the language that describes the structure of a web page.
Tags and elements
Tags are the labels, and elements are the finished pieces.
Your first page
Create a file, add a heading and a paragraph, and open it.
Back-to-Top Linksβ
At the end of a long page, give readers a quick way back up.
<body id="top">
<!-- ...a long page... -->
<p><a href="#top">Back to top</a></p>
</body>
A link to just # or #top also scrolls to the top of the page. Giving the <body> or your main heading an id="top" makes your intention clear.
Skip Links: A Gift for Keyboard Usersβ
Imagine using only the Tab key. On a page with a big menu, you would have to press Tab through every menu item on every page before reaching the content. A skip link solves this. It is the first link on the page, and it jumps straight to the main content.
<body>
<a class="skip-link" href="#main">Skip to main content</a>
<header>
<nav><!-- long menu --></nav>
</header>
<main id="main" tabindex="-1">
<h1>Welcome</h1>
</main>
</body>
.skip-link {
position: absolute;
left: -9999px; /* hidden off-screen */
}
.skip-link:focus {
left: 1rem; /* visible when focused */
top: 1rem;
padding: 0.5rem 1rem;
background: #fff;
border: 2px solid #2563eb;
z-index: 1000;
}
The link stays out of sight for mouse users, then appears when a keyboard user reaches it. The tabindex="-1" on <main> lets the browser move focus there reliably after the jump.
Smooth Scrolling and Sticky Headersβ
Two small CSS rules make same-page links feel polished.
html {
scroll-behavior: smooth;
}
h2[id],
h3[id] {
scroll-margin-top: 80px; /* the height of your sticky header */
}
scroll-behavior: smoothanimates the jump instead of snapping.scroll-margin-topleaves space above the target, so a fixed header does not cover the heading.
Some visitors feel dizzy from animation. Respect them with a media query:
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
}
Highlight the Targetβ
The :target pseudo-class matches the element that the current #fragment points to. It is a lovely way to show readers where they landed.
:target {
background: #fef9c3;
outline: 2px solid #f59e0b;
outline-offset: 4px;
}
Accessibility and Global Readersβ
- Link text should name the destination. "Jump to Installation" is better than "Click here."
- Test with the keyboard. After activating a same-page link, focus should continue from the target. Add
tabindex="-1"to non-interactive targets such as<main>or a<div>when needed. - Keep
idvalues simple. HTML allows non-English letters in anid, but plain lowercase letters, numbers, and hyphens are safest across tools, servers, and sharing apps. - Right-to-left pages work the same. The
#fragmentis not affected by reading direction. - Do not change the meaning of
<a>. Use a link when the visitor goes somewhere, and a button for actions such as opening a menu. - Respect motion preferences with
prefers-reduced-motion, as shown above.
Docusaurus creates an id for every heading automatically, so you can link to any heading in these lessons, such as /html/links-and-navigation/internal-links#skip-links-a-gift-for-keyboard-users. Hover over a heading to see its link.
Choosing the Right Internal Linkβ
| You want to... | Use |
|---|---|
| Open another page of your site | A relative URL, such as contact.html |
| Scroll to a section of this page | #id of that section |
| Open another page at a specific section | page.html#id |
| Help keyboard users skip the menu | A skip link at the top of the page |
| Return to the top of a long page | #top |
| Show the visitor where they are | aria-current="page" and CSS |