Der Schepp

Fixing Smooth Scrolling & Page Search (updated!)

Yesterday, as I was browsing my Twitter timeline, a tweet from Chris Coyier popped up, in which he mentioned feedback he got for one of his CSS Tricks experiments. It went as follows:

Anecdotal thing: when I had this on @CSS, I had SO MANY reports of people annoyed that when they did "find on page" and ⬆️⬇️ through the results, the smooth scrolling was slow and annoying. Unfortunately, you can't control the speed or when it happens. https://t.co/HAio46bYQt

— Chris Coyier (@chriscoyier) January 5, 2021

Apparently Chris had once switched out JavaScript-based smooth anchor scrolling in favor of a more modern, purely CSS-based solution. All you need to do is slap a scroll-behavior: smooth on html and all of a sudden scrolls to different places on the page happen smoothly. And that's great!

Sadly, as Chris points out in his tweet, native smooth scrolling negatively affects the UX of page search when cycling through its search results:

Smooth scrolling is consequently applied to everything. Always. Even when cycling through the browser's page search results. At least that's the case for Chromium. So for the page search it would be desirable for the browser to make an exception to that rule and to deactivate smooth scrolling.

Until the Chromium team fixes it, here is a trick how to solve the problem on your own with a little bit of extra CSS --and HTML--.

The Solution #

First you need to move your assignment of scroll-behavior from html selector to html:focus-within. This will ensure that smooth scrolling is only active while the focus is within the page. Sadly Chrome and Firefox, upon clicking an on-page anchor link, both first assign and then remove focus from the document. Therefore you need to flank the above with two (identical) time-limited animations that force smooth scrolling onto the document for a certain period of time after the click.

@keyframes smoothscroll1 {
from, to { scroll-behavior: smooth; }
}

@keyframes smoothscroll2 {
from, to { scroll-behavior: smooth; }
}

html {
animation: smoothscroll1 1s;
}

html:focus-within {
animation-name: smoothscroll2;
scroll-behavior: smooth;
}

Link to Codepen

Now everytime the user interacts with the surrounding browser interface, as is the case with the page search, smooth scrolling will be disabled and jumping to the results will be instantaneous.

And that's it. Problem solved!

2021/01/17 Update: My initial solution broke smooth scrolling on a perfectly working Firefox (due to this long standing bug). So I reworked the code. The CSS got more complex, but on the winning side you don't need to add tabindexes to your HTML any more.

Thanks go out to Matthias Ott and Stefan Judis for pushing me to publish this post ❤

The cover image of this post is Graceful Ballet Dancer by Master1305

Webmentions

+9
  1. I kind of like having the smooth scroll while searching. Can we make it a user preference? 😅
  2. Andy Bell Andy Bell
    It is a good idea to add tabindex to the main so it receives programmatic focus on target though. It can help reduce the risk that keyboard tabbing doesn’t force the user back to the top, post skip-link. I always see smooth scrolling as a nice to have, rather than must-have too.
  3. Andy Bell Andy Bell
    It’s smart! I’ll probably keep the reset version as a progressive enhancement though 🙂
  4. Before you settle on your decision I'd like to point out that not only would you bring smooth scrolling back to life in Firefox, but the new code also wouldn't rely on `tabindex` being added to all anchor targets anymore. So it would also be a net dev-UX-win to switch.

← Home