Navbar w/ Smooth Scrolling Same Page Links & Accessibility

Glyn Lewington
Apr 9, 2018 · 2 min read

Not as simple as it sounds…

Image for post
Image for post
Photo by Faye Cornish on Unsplash

There’s a few unexpected steps involved which left me scouring the internet for solutions. All the full solutions I found were bloated with ugly and long Javascript or using jQuery, etc which is really unnecessary.

Step 1 — HTML

1.1 — Create a Navbar

Here’s a simple example with links to sections on the same page with #id’s.

<nav class='navbar'>
<ul class='navbar__list'>
<li class='navbar__list__item><a href='#intro'>Intro</a></li>
<li class='navbar__list__item><a href='#meatnpotatoes'>Meat 'n' Potatoes</a></li>
<li class='navbar__list__item><a href='#stuff'>Stuff</a></li>
</ul>
</nav>

1.2 — Add Tab Index to html Sections

If you don’t set the tabindex you won’t be able to set focus when writing your Javascript (next step). By default, <section>’s are not focusable.

<section id='intro' tabindex='0'></section>
<section id='meatnpotatoes' tabindex='0'></section>
<section id='stuff' tabindex='0'></section>

Step 2 — Javascript

2.1 — Add Event Listener

In your Javascript file create an event listener for clicks on the navbar links.

  • Select your links.
const navbarItems = document.querySelectorAll('.navbar__list__item');
  • Loop over links & add listeners for clicks.
navbarItems.forEach(item => {
item.addEventListener('click', () => {
  • Prevent the default behaviour.
    Without this your links will jump instantly down the page ( :O no smooth, sexy scrolling! ).
event.preventDefault();
  • Select section of page related to the navbar item.
let section = document.querySelector(item.childNodes[1].getAttribute('href'));
  • Set scroll behaviour for section .

behaviour: ‘smooth’ will set it to smoothly scroll to the section.
block: ‘start’ will set it to scroll to the beginning of the section, rather than the center.

section.scrollIntoView({
behaviour: 'smooth',
block: 'start'
});
  • Set webpage focus to the clicked section .

The scrolled-to section will receive focus, essential for accessibility & keyboard navigation.

setTimeout(() => section.focus(), 500);

Full code and if you want to see it in action I implemented it in my portfolionot a shameless plug, I swear it just happens to be where I needed it!

const navbarItems = document.querySelectorAll('.navbar__list__item');navbarItems.forEach(item => {
item.addEventListener('click', () => {
event.preventDefault();
let section = document.querySelector(item.childNodes[1].getAttribute('href'));
section.scrollIntoView({
behaviour: 'smooth',
block: 'start'
});
setTimeout(() => section.focus(), 500);
}
}

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store