Improving Anchor Links

3 min read
1 tags

This post outlines a few tricks that I’ve been re-discovering over and over again. To save time, I thought I would do a quick write-up documenting them so I know where to look next time I need them.

Let’s start off by defining what an “anchor link” is. I would define an anchor link as a fundamental browser feature, that requires a few things to work:

  • an HTML element with a unique id: <h2 id="go-to-website-stack">Go To Website Stack</h2>
  • a URL that references that unique id:

When someone navigates to that URL, it will scroll to the position of the corresponding HTML element on the page.

I’m sure you’ve seen these used in a table of contents for an extensive blog post, or to jump to a specific section on a restaurant’s menu page. This post is going to summarize some of the cool things you can do with those anchor links. I use them in my coffee post for a table of contents.

Alternate names

these anchor links go by a bunch of other names as well, you may know them as:

  • ID-based links
  • Tagged links
  • Jump links
  • Inline links
  • On-Page links

Shoutout to the d-d-d-discord for this list.

Scroll margin on top of the element

If you want to use these links on a site that has a sticky header element at the top of the viewport, you’ll probably notice things won’t go to plan. Typically these links are hidden underneath the sticky header.

See the Pen Anchor Link: Margin Example (Broken) by Mykal Machon (@mykalmachon) on CodePen.

Do you see how the heading with the unique ID is below the sticky header?

There are a few CSS rules we can throw in to add some space between the top of the viewport, and the associated element. See an example of this fixed here:

See the Pen Anchor Link: Margin Example (Broken) by Mykal Machon (@mykalmachon) on CodePen.

Temporary animations on arrival at element

Another thing you can do to improve the user experience of these anchor links is adding an animation/style to emphasize the part of the document you’ve linked to.

I tend to do this by adding a quick “blink” animation to the heading in question:

@import '';

:target {
  animation: var(--animation-blink);
  animation-timing-function: var(--ease-3);
  animation-duration: 0.5s;
  animation-iteration-count: 5;

But you can also add a background to the element, a border, or anything else you can think of doing in CSS.

@import '';

:target {
  background: var(--yellow-6);
  border-bottom: 2px solid var(--yellow-9);