Tags: scrolling



Sticky headers

I made a little tweak to The Session today. The navigation bar across the top is “sticky” now—it doesn’t scroll with the rest of the content.

I made sure that the stickiness only kicks in if the screen is both wide and tall enough to warrant it. Vertical media queries are your friend!

But it’s not enough to just put some position: fixed CSS inside a media query. There are some knock-on effects that I needed to mitigate.

I use the space bar to paginate through long pages. It drives me nuts when sites with sticky headers don’t accommodate this. I made use of Tim Murtaugh’s sticky pagination fixer. It makes sure that page-jumping with the keyboard (using the space bar or page down) still works. I remember when I linked to this script two years ago, thinking “I bet this will come in handy one day.” Past me was right!

The other “gotcha!” with having a sticky header is making sure that in-page anchors still work. Nicolas Gallagher covers the options for this in a post called Jump links and viewport positioning. Here’s the CSS I ended up using:

:target:before {
    content: '';
    display: block;
    height: 3em;
    margin: -3em 0 0;

I also needed to check any of my existing JavaScript to see if I was using scrollTo anywhere, and adjust the calculations to account for the newly-sticky header.

Anyway, just a few things to consider if you’re going to make a navigational element “sticky”:

  1. Use min-height in your media query,
  2. Take care of keyboard-initiated page scrolling,
  3. Adjust the positioning of in-page links.

Scrollin’, scrollin’, scrollin’

A few weeks ago, when I changed how the front page of this site works, I wrote about “streams”, infinite scrolling, and the back button:

Anyway, you’ll notice that the new home page of adactio.com is still using pagination. That’s related to another issue and I suspect that this is the same reason that we haven’t seen search engines like Google introduce stream-like behaviour instead of pagination for search results: what happens when you’ve left a stream but you use the browser’s back button to return to it?

In all likelihood you won’t be returned to the same spot in the stream that were in before. Instead you’re more likely to be dumped back at the default list view (the first ten or twenty items).

That’s exactly what Kyle Kneath is trying to solve with this nifty experiment with infinite scroll and the HTML5 History API. I should investigate this further. Although, like I said in my post, I would probably replace automatic infinite scrolling with an explicit user-initiated action:

Interpreting one action by a user—scrolling down the screen—as implicit permission to carry out another action—load more items—is a dangerous assumption.

Kyle’s code is available from GitHub (of course). As written, it relies on some library support—like jQuery—but with a little bit of tweaking, I’m sure it could be rewritten to remove any dependencies (hint, hint, lazy web).

Continuous partial annoyance

Twitter have been rolling out a new redesign. Thanks to Dustin, I got to try it out when the switch was flipped.

As with any redesign, the initial reaction tends to be It’s different! I fear change! Therefore I dislike this. See also: redesigns of The Guardian, Last.fm, Flickr, BBC…

With Twitter, that initial knee-jerk fades pretty quickly because the new site is undeniably beautiful. The visual design is top-notch.

There’s a nice little addition in the markup, too. The body element has a class name that you can hook into for user stylesheets. This is a very, very, very good thing. For example, my class name is .user-style-adactio so I can add some declarations to my user stylesheet.

The first rule simply hides the egregious Trending Topics and Who To Follow features (and I love that Who To Follow abbreviates to WTF):

.user-style-adactio .trends-inner,
.user-style-adactio .wtf-inner {
 display: none !important;

By the way, a user stylesheet is the only time it’s acceptable use important! in your CSS.

My other rules adjust the layout a bit when the viewport gets smaller. It’s just a quick little hack and it’s not great but it’s handy if, like me and Norm!, you don’t like a site dictating how wide your browser window should be. Thanks to user stylesheets, you can fix this:

@media screen and (max-width: 995px) {
 .user-style-adactio #page-container,
 .user-style-adactio #page-outer {
  min-width: 590px !important;
 .user-style-adactio .dashboard {
  float: none !important;
  clear: both !important;
  max-width: 0 !important;

Handy tip: if you use Dropbox, store your user stylesheet there. That way, you can point multiple machines to the same stylesheet. I’ve got my laptop at home and my iMac at work pointing to the same CSS file.

There’s one aspect of the new Twitter redesign that I really don’t like, and I can’t fix it with a user stylesheet: infinite scrolling. As I said (on Twitter, of course):

I’m allergic to infinite scrolling

Notice that I didn’t say that infinite scrolling is wrong, it’s just wrong for me. There’s nothing wrong with peanuts unless you have a nut allergy.

The reason that I don’t like infinite scrolling is that I actually use the scrollbar to scroll. That is, I move my cursor over the scrollbar, click and drag. Infinite scrolling makes this unworkable: the scrollbar under my cursor jumps around as new content is loaded.

I figured that in this day of mouse wheels and trackpads, I must be in the minority with my old-fashioned scrollbar usage. I asked for data on Twitter, and sure enough, most people who responded said they used the mouse wheel, the trackpad, the space bar or arrow keys. Though some people still found the scrollbar useful as a visual indicator of how long the page is …which is also negated by infinite scrolling.

Interestingly, while most of the people who responded to my query on Twitter said they hardly ever use the scrollbar, the Firefox heatmap shows that it’s one of the most used interface features. That was a much larger sampling: 117,000 users.

Still, I can understand why Twitter have decided to go with infinite scrolling. If I’m in the minority in thinking it’s horrible, that’s my problem. I can’t even claim that it’s an accessibility problem: it requires more manual dexterity to use the scrollbar than to use other methods of scrolling.

Twitter could add a user setting to switch off infinite scrolling—perhaps replacing it with the old style “more” button, which I liked—but that’s a cop-out. Whenever something gets shunted off into a preference, it’s generally a sign of indecision in the design. The Twitter redesign isn’t indecisive: it has a very clear and consistent visual and interactive design vocabulary. It just happens that one aspect of the UI vocabulary doesn’t mesh well with my own usage pattern.

So, in this case, the solution may well be for me to change the way I use the site. It still irks me, though. I’m generally against any interactions that happen without an explicit request from the user, such as revealing data and functionality on hover, for example. Twitter avoids that particular anti-pattern but with infinite scrolling, the act of moving down the page is interpreted as a request to load more data. I would much prefer to request that data explicitly with a button or link. Of course, that requires that the user do more, so it could be argued that infinite scrolling actually reduces the number of interactions that the user is required to do …assuming that the inferred interaction is in fact the desired interaction. That’s a big assumption.

On the face of it, it would seem that Twitter are being somewhat dismissive of the scrollbar as a UI element. But that’s not true. While they are reducing the usefulness of browser-native scrollbars by using infinite scrolling, they are, at the same time, replicating the functionality of scrollbars but non-natively. If you reveal a side panel—by clicking on someone’s Twitter username, for example—and if the content doesn’t fit within the viewport, then a non-native scrollbar is generated.


As I said, the new redesign is wonderful. I’m just nit-picking ..but it’s a big nit.