Well, that title is a mouthful. This post will be short and sweet though.

Imagine you have a scrollable area that displays chronological content like a feed (but not like LinkedIn, Facebook or Twitter which are reverse-chronological), similar to a chat window. You want the region to be scrolled to the bottom to begin with, which is where the relevant content is.

With JavaScript

You could do it with JavaScript, like this:

const region = document.querySelector('.my-region')
region.scrollTop = region.scrollHeight

But you know, using JavaScript means it can fail, or can take a while to happen, potentially at a point where the user has begun scrolling in that region. Not perfect.

With CSS

Another approach is to do it with CSS. The idea is to use a reverse-column flex layout so the scroll begins bottom-anchored. Of course, this reverses the order of elements, so they need to be also reversed in the DOM so they are displayed in the right order (elements near the bottom need to appear first in the DOM order).

See the Pen Untitled by Kitty Giraudel (@KittyGiraudel) on CodePen.

A note on accessibility

One thing worth mentioning is that using column-reverse creates a disconnect between the visual order and the DOM order, which can be confusing for screen-reader users. For someone using a screen-reader, the first element in the DOM is now the “latest” element from the feed, which I would argue is better this way since this is the new and relevant content, but it may not be the expected behavior.

Interestingly enough, there has been some movement in that area very recently (as in within the last month) and Blink is already working on the implementation. Some work is being done on a reading-order CSS property (or perhaps reading-flow, name appears to be pending) that would enable developers to help screen-readers figure out the best reading order.

reading-order: normal | flex-visual | flex-flow | grid-rows | grid-columns | grid-order

In our case, we could use reading-order: flex-visual to align the way sighted users and screen-reader users consume our feed.

About accessible scrollable regions

I feel like this post is a good opportunity to remind everyone that scrollable areas are not accessible by default and need some work.

For starters, they need a tabindex="0" attribute so they can be focused and scrolled with the keyboard. This satisfies 2.1.1: Keyboard (Level A) and 2.1.3: Keyboard (No Exception) (Level AAA).

Additionally, they need an accessible name, either via aria-label or aria-labelledby mapped to a heading element for instance. And for their label to be applied, they need a non-presentational role, such as role="region".

Adrian Roselli has a great article about scrollable regions.