Skip to content

Enhance hashtag links with CSS

Any element in an HTML document with an id attribute can be referenced in the URL using a # symbol followed by the id of the element. The part after the # is officially called fragment of the URL. Unofficially, it is called hashtag.

The browser uses the part before the fragment to load the page, then uses the fragment to bring the target element into the view. When a user inputs a URL https://example.com/#usage into the address bar of a browser, the browser loads the page, then brings the element with id="usage" in to the view. Or, as many say, the browser scrolls to the element.

We can use only the fragment to reference elements within the current page. When a user clicks on a link, <a href="#getting-started">Getting started</a>, the browser scrolls to the element with id=getting-started. You’ll find this pattern used in table of contents, footnotes, and other internal references in the HTML documents.

Even the browsers from the early days of the web supports URL fragments. The URL fragment works without any CSS or JavaScript. We could sprinkle some CSS to improve the experience.

Improve scroll spacing

When the browser scrolls to the target element, it tries to keep the element towards the top of the viewport, or the container element. There might be cases you might want to leave a bit of room between the top edge of the viewport and target element. If you have any fixed elements (like navigation or header) the spacing is a must.

You can use CSS property scroll-margin to set scroll offsets. The most common scenario is to set offset for vertical scrolling. We can use scroll-margin-top to set the top offset.

The navigation is fixed to top and covers the content. The target element is positioned below the navigation using scroll-margin-top when hashtag links are clicked.

Smoothen scroll

The default behaviour by the browser when a user clicks on a fragment URL is to instantaneously scroll to the target element. If you prefer to scroll smoothly to the target element, you can use scroll-behavior: smooth. Usually, this is set on the document, html. If you want to change scroll behaviour within a child container, you can set the scroll-behavior property of that element.

⚠️ scroll-behavior is not yet supported in Safari.

Style the target element

Every so often, you like to highlight the target element. CSS provides the :target pseudo selector, just for that. This comes handy when linking a heading from a table of contents, or linking to a footnote.

I’m available for new projects from October 2021.

Get in touch