⚓️ What is Astro and What is Scroll to Anchor? #
In this post we will see how to build Astro Scroll to Anchor functionality into your static site. Before we get on to that though, we should take a quick peek at what Astro and scroll to anchor are. Astro is a new static site builder which lets you build fast websites. The secret to its speed is something called partial hydration which means you, as a developer, get more control over when JavaScript on a page loads. You can even ship zero JavaScript when none is needed. Scroll to anchor is a nice feature we have come to expect on websites where a little link icon appears if you hover over a heading. You can click the link to scroll smoothly to that heading, as well as even copy and save it for future reference.
🧱 What we’re Building #
Having said that Astro's superpower is partial hydration, we're going to build out the scroll functionality with no hydration at all. Meaning no JavaScript is required for our page; we will add the smooth scrolling and link auto show/hide using CSS. Although you can use Astro with Lit, React, Svelte or Vue, we will create a pure Astro component to add the feature. This will make it easier for you to recycle the code for use in your own Astro project using your preferred framework. Have a look at the post introducing Astro, though if you want to know more about partial hydration and Astro’s islands architecture.
If you are new to Astro, consider this a gentle introduction. If, however, you already have some experience with Astro you will see a new and efficient way to add SVG icons to your Astro app. This will let you pick icons from any icon library you want, just by adding a single dependency.
🚀 Getting Started #
The code we will look at can easily be added to an existing project, though if you are new to Astro, just follow along and you can add it to your next project! If you are starting a new project, let’s get the ball rolling in the Terminal:
Use yarn
or npm
if you prefer those
to pnpm
. Choose Minimal from the list of templates.
We disable telemetry here. Skip that line if you want to keep data collection. The Astro dev server
will normally run on port 4321
but if there is already something running
there, it will find the next available port. The terminal will then tell you which port it settled
for:
This is a great feature, just make sure you only run one server at a time though! You can run multiple servers, but a couple of times I have spun up a new dev server, while I already had one running in preview mode. Of course, the preview one was open in the browser and I couldn't work out why code changes weren't showing up… a fun way to waste ten minutes!
Anyway, if you are following along, starting from scratch, replace the content in src/pages/index.astro
with this:
src/pages/index.astro
— click to expand code.
This is just some placeholder text which will let us explore a few Astro features as we build out the Astro scroll to anchor feature.
Anatomy of an Astro File #
Like Markdown files, Astro files also have a front matter section. This is where you can import packages as well as run any JavaScript you need to for the output. You can also use TypeScript in the front matter.
The next part of the file is essentially a template. You can include JavaScript scripts in script tags, but can't actually run JavaScript code within this section (this is different to the JSX you might use in React, for example). The Astro markup is a superset of HTML meaning making it easy to pick up if you are coming from a HTML/JavaScript only background.
Finally, at the bottom we have some styling. You can include it like this within a script tag in
your Astro file. As an alternative, for a typical project, you can create a global CSS stylesheet
and import that in your Astro frontmatter. In this case you can still include any styles for the
current page in this style tag. If you do want to use global stylesheet, just save it somewhere
within the src
folder of your project and import it as mentioned.
Final Preparation #
Before proceeding, download some self-hosted fonts which we will use on the site. Save raleway-latin-400-normal.woff2 and raleway-latin-700-normal.woff2 together with raleway-latin-900-normal.woff2 to a new, public/fonts
directory within the project.
🧩 Heading Component #
The markup and styling for the Astro scroll to anchor feature will go in a new Astro component
file. You can create Astro components as well as pages. The components are akin to those you would
have in a React or SvelteKit app. Create a src/components
folder and
within that directory make a new Heading.astro
file, adding this content:
You see a few Astro features in here. Firstly, like our home page we have three sections:
frontmatter, markup and styles. In the first line we import the astro-icon
package by Nate Moore , an Astro maintainer. This makes use of Anthony Fu's fantastic icônes library (used with the iconify package). If you haven’t yet heard of it, it is definitely worth exploring.
Go to the icônes site where you can find icons from just about every library that exists. You can pick
the icons you want for your app and under the hood, astro-icon
efficiently
imports just the ones you need.
We use the icon, in line 12
. You just select the icon you want on
the icônes site and it gives you a name to add which you add as an attribute to the <Icon>
component instances. Before that though, we need to install the astro-icon
package and the icon pack(s) for your chosen icon(s):
and add a few lines of config to astro.config.mjs
in the project root
folder:
Here, “link
” in line 9
is the name
of the icon we want to choose from the pack, you can list out all the icons you want to use or, alternatively,
use all icons from the pack.
🗳 Poll #
Astro props #
In line 4
(of the Header.astro
file)
you see how to access props in an Astro component, we will include these in the markup for the home
page in the next step. The two props will be the text of the title together with an id, used to create
the scrolling link. This needs to be unique for each link we create. We actually use the text
prop in the markup, in line 10
.
Moving in line 11
we use an Astro shortcut (this will look familiar
if you know Svelte). We can use this shortcut whenever the name of a variable matches the name of the
attribute we want to assign it to:
is equivalent to:
Finally, in lines 26
– 30
, you see we can style the icon by targetting [astro-icon]
.
Notice the global CSS variables we defined on the home page are available in our component.
🔌 Using the new Component #
Using the new component is a breeze. Let's update src/pages/index.astro
first, importing our new Heading
component:
and then using it in the headings:
Alternative Implementation #
We are passing the text in as a prop. This is so that you have easier access to the title text in the component, so for example, you could add some code to remove widows. This is the pet peeve of typographers where you have a single short word alone on a line. The alternative is to rewrite the component so it accepts the title text sandwiched between the Heading component:
Then in the heading component, in the markup you would need to replace {text}
with <slot/>
. We won't go into details, here, just
want to let you know another way exists.
If you save and hover over one of the headings, you icon should show up.
🛹 Adding Smooth Scrolling #
The final missing piece is to add a touch of CSS to get smooth scrolling. It might seem counter-intuitive but we will switch off the feature for users who prefer reduced motion. This is just because on a long page, scrolling can be quite quick, and might trigger nausea in site visitors with vestibular disorders.
That’s it now! Let’s test it out next.
💯 Astro Scroll to Anchor: Testing it out #
🙌🏽 Astro Scroll to Anchor: Wrapping Up #
In this post, we have had an introduction to Astro and seen:
- how to pass props into an Astro component and access them from within the component;
- a convenient and efficient way to add SVG icons to your Astro app; and
- how to make smooth scrolling more accessible.
The full code for the app is available in the Astro demo repo on Rodney Lab GitHub .
I hope you found this article useful and am keen to hear how you plan to use the Astro code in your own projects.
🏁 Astro Scroll to Anchor: Summary #
Do you have to know React or another framework to use Astro? #
- Although Astro works with Lit, React, Svelte and Vue, you don’t have to use any of these if your app doesn't need it. Astro, itself a superset of HTML, is a templating language used for markup. When you don’t need JavaScript in your app, using Astro alone will work just fine! This makes Astro a nice choice of framework if you are moving on from plain HTML and JavaScript apps.
How can you easily add SVG icons in Astro? #
- astro-icon is a great choice for adding SVG icons to your Astro app. It provides an API for all of the icons in the icônes library. That library includes icons from just about every set of icons you could possibly want to use. astro-icon will efficiently import only the icons you use, helping to keep the shipped bundle size small.
How can you make smooth scrolling more accessible? #
- Smooth scrolling looks good on short pages and might not cause accessibility issues. For long pages, the resulting scroll might be quick enough to trigger nausea in sufferers of vestibular disorders. This does not mean that you shouldn’t use the CSS or JavaScript smooth scrolling functions. Instead, just add a media query, setting smooth scrolling to 'auto' if the user has set 'prefers-reduced-motion' to 'reduce' in their browser. Setting 'auto' results in an instant scroll which should provide a better experience for these users.
🙏🏽 Astro Scroll to Anchor: Feedback #
Have you found the post useful? Would you prefer to see posts on another topic instead? Get in touch with ideas for new posts. Also, if you like my writing style, get in touch if I can write some posts for your company site on a consultancy basis. Read on to find ways to get in touch, further below. If you want to support posts similar to this one and can spare a few dollars, euros or pounds, please consider supporting me through Buy me a Coffee.
Just dropped a new post in which you see how you can use astro-icon to create a CSS-only Scroll to Anchor feature in your Astro app.
— Rodney (@askRodney) March 18, 2022
There’s also a tip on how you can make smooth scrolling more accessible.
Hope you find it useful!
https://t.co/ssZTfjWqM0
Finally, feel free to share the post on your social media accounts for all your followers who will find it useful. As well as leaving a comment below, you can get in touch via @askRodney on Twitter and also askRodney on Telegram . Also, see further ways to get in touch with Rodney Lab. I post regularly on Astro as well as SvelteKit. Also, subscribe to the newsletter to keep up-to-date with our latest projects.