Skip links are little internal navigation links that help users move around a page. It’s possible you’ve never actually seen one before because they’re often hidden from view and used as an accessibility enhancement that lets keyboard users and screen readers jump from the top of the page to the content without have to go through other elements on the page first.
In fact, you can find one right here on CSS-Tricks if you crack DevTools open.
In my opinion, the best way to implement a skip link is to hide it and then bring it into view when it is focused. So, let’s say we have a link in the HTML:
<a class="skip-to-content-link" href="#main">
Skip to content
</a>
…we can give it an absolute position and translate it off the screen:
.skip-to-content-link {
left: 50%;
position: absolute;
transform: translateY(-100%);
}
Then we can bring it back into view when it’s in focus and style it up a bit in the process:
.skip-to-content-link {
background: #e77e23;
height: 30px;
left: 50%;
padding: 8px;
position: absolute;
transform: translateY(-100%);
transition: transform 0.3s;
}
.skip-to-content-link:focus {
transform: translateY(0%);
}
This will hide our link until it is focused and then put it into view when it becomes focused.
Now, allow me to elaborate, starting with this quote from Miles Davis:
Time isn’t the main thing. It’s the only thing.
As I sit down to write this article in a rainy Ireland, I think of the challenge that many users face as they use the web that I take for granted. We put so much thought into creating a great user experience without thinking of all our users and how to meet their needs. Admittedly, a skip link was something I had never heard of until completing a course on Frontend Masters by Marcy Sutton. Since learning the power and simplicity of using a skip link, I decided to make it my mission to spread more awareness — and what platform better than CSS-Tricks!
A solution is an answer to a problem, so what’s the solution for helping keyboard users and screen readers find the content of a page quickly? In short, the solution is time. Giving users the ability to navigate to parts of our website that they are most interested in gives them the power to save valuable time.
Take the Sky News website as an example. It offers a “Skip to content” button that allows users to skip all the navigation items and jump straight to the main content.
You can see this button by navigating to the top of the page using your keyboard. This is similar to the implementation shown above. The link is always in the document but only becomes visible when it’s in focus.
This is the type of skip link we are going to create together in this post.
Our sample website
I built a sample website that we will use to demonstrate a skip link.
The website has a number of navigation links but, in the interest of time, there are only two pages: the home page and the blog page. This is all we need to see how things work.
Identifying the problem
Here’s the navigation we’re working with:
In total, we have eight navigation items that a keyboard user and screen reader must tab through before reaching the main content below the navigation.
That’s the problem. The navigation may be irrelevant for the user. Perhaps the user was given a direct link to an article and they simply want to get to the content.
This is a perfect use case for a skip link.
Creating the link
There are a couple of approaches to creating a Skip to content link. What I like to do is similar to the Sky News example, which is hiding the link until it is focused. That means we can drop the link at or near the top of the page, like inside the <header>
element.
<header>
<a class="skip-link" href='#main'>Skip to content</a>
<!-- Navigation-->
</header>
This link has a .skip-link
class so we can style it. Thehref
attribute points to #main
, which is the ID we will add to the <main>
element that comes further down the page. That’s what the link will jump to when clicked.
<header>
<a class="skip-link" href='#main'>Skip to content</a>
<!-- Navigation-->
</header>
<!-- Maybe some other stuff... -->
<main id="main">
<!-- Content -->
</main>
Here’s what we have if we simply drop the link into the header with no styling.
This does not look great, but the functionality is there. Try navigating to the link with your keyboard and pressing Enter when it’s in focus.
Now it’s time to make it look pretty. We must first fix the positioning and only show our skip link when it is in focus.
.skip-link {
background: #319795;
color: #fff;
font-weight: 700;
left: 50%;
padding: 4px;
position: absolute;
transform: translateY(-100%);
}
.skip-link:focus {
transform: translateY(0%);
}
The magic here is in the transform
property, which is hiding and showing our skip link depending on whether it is focused or not. Let’s make it look a little nicer with a quick transition on the transform
property.
.skip-link {
/* Same as before */
transition: transform 0.3s;
}
It will now transition into view which makes that bit better.
You should now (hopefully) have what I have below:
As you can see, the skip link bypasses the navigation and jumps straight down to the <main>
element when clicked.
It’s OK to use more than one link!
Right now, the link only serves one purpose and that is skip to the content of our website. But we don’t have to stop there.
We can go even further and create a skip link that has more options, such as a way to jump to the footer of the site. As you might imagine, this is quite similar to what we’ve already done.
Let’s make the blog page of the example site a little more usable by using multiple skip links. It’s common for blogs to use AJAX that loads in more posts when reaching the bottom of the page. This can make it very difficult to get to the footer of the website. That’s the problem we want to solve in this case.
So let’s add a second link that bypasses all that auto-loading business and jumps the user straight to a #footer
element on the page.
<div class="skip-link" >
Skip to <a href='#main'>content</a> or <a href='#footer'>footer</a>
</div>
We also need to amend our CSS a little and use the :focus-within
pseudo selector.
.skip-link {
transform: translateY(-100%);
}
.skip-link:focus-within {
transform: translateY(0%);
}
This is saying if anything within our .skip-link element has focus, then we show it. Sadly, neither Internet Explorer nor Opera Mini support focus-within, but its coverage is pretty darn good and there is a polyfill available.
This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.
Desktop
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
60 | 52 | No | 79 | 10.1 |
Mobile / Tablet
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
122 | 123 | 122 | 10.3 |
Last thing we need to do is make sure there’s an ID on our footer element so the link has something to jump to.
<footer id="footer">
Here’s what this gives us:
If we wanted to go one step further (and I’d encourage it), we could style each link a little differently so users can distinguish between the two. Both links in this example are plain white which works great for a single button that does a single thing, but it’d be clearer that we’re dealing with two links if they were presented differently.
Jumping to conclusions
Are you using skip links on your site? Or, if not, does this convince you to use one? I hope it’s clear that skip links are a great value add when it comes to the accessibility of a site. While it’s not a silver bullet that solves every accessibility need, it does solve some use cases that make for a much more polished user experience.
Here are some prominent sites that are using this or a similar technique: