Scroll Snap Challenges

Though JS-free fixed table row and column headers have been possible for quite some time, Safari’s and Chrome’s recent fixes got some people pretty excited. Enough that folks are copying code samples in whole, without always paying attention to necessary considerations.

That same excited demo included other CSS properties that can bring some unintended usability and accessibility challenges: CSS Scroll Snap (that links to the Editor’s Draft, but you can also read MDN’s coverage of scroll snap properties)

My post Fixed Table Headers does not use CSS scroll snap. That is intentional. Two reasons why I did not implement it:

  1. A Chrome bug from 2018, Issue 835301: [css-scroll-snap][position-sticky] scroll-snapping “stickily” positioned elements can cause inaccurate snap positions, which was not fixed with the Chrome 91 table fixes;
  2. In testing, users often wanted to straddle a cell to compare with others, and on smaller screens, higher zooms, or fuller cells, this became particularly difficult.

Once you factor in users who resize text or zoom, things can get problematic. Test your scroll snap solution against WCAG SCs 1.4.4 Resize Text, 1.4.10 Reflow, and 1.4.12 Text Spacing. Then try it with just the keyboard.

Videos

I forked the pen from my fixed headers post, added scroll-snap-align: start to the <th>s and <td>s, and added scroll-snap-type: both mandatory to the wrapper.

See the Pen Fixed Table Header Demo: Responsive with Scroll Snap by Adrian Roselli (@aardrian) on CodePen.

Then I ran the demo through Safari on iOS and macOS, Chrome on Windows and Android, and Firefox.

Using Safari 14.1.1 on macOS 11.4, the <caption> is hidden, the first line of the data cell is hidden by the fixed column header, the header row is offset from the top of the table, scroll snap does not work on the horizontal axis, and row headers are hidden and then clipped while scrolling.
In Chrome 91 on Windows with a keyboard, the <caption> is hidden, and it’s not possible to use the arrow keys to scroll for only part of a cell or get the <caption> into view.
In Firefox 89 on Windows, the <caption> is visible (yay!). Otherwise it behaves as Chrome does with a keyboard (which is expected) with the added bug of not letting arrow keys scroll the first cell into view in a row with a row header.
Safari on iPadOS 14.5 (and also iPadOS 14.6) behaves as Safari on macOS. The <caption> is hidden, the first line of the data cell is hidden by the fixed column header, the header row is offset from the top of the table, scroll snap does not work on the horizontal axis, and row headers are hidden and then clipped while scrolling.
Chrome 90 on Android 11 behaves as Chrome on desktop. I did not test it with keyboard on mobile, but you can pretend this represents how it might work with a mouse on desktop.

Another Demo

I made this demo after I recorded the other videos. This one would have been a better example, but considering what I get paid to run this site it seemed fair to not redo them.

I added a button to toggle text spacing (WCAG SC 1.4.12 Text Spacing) and text size (WCAG SC 1.4.4 Resize Text). You can visit the example directly and try it yourself. Visit the debug version to try it on mobile (not really WCAG SC 1.4.10 Reflow).

See the Pen Scroll Snap Challenges by Adrian Roselli (@aardrian) on CodePen.

I made a video to demonstrate the hassle of trying to compare two columns or to select text that is clipped or outside the snap area. Obviously, your content and use cases will differ, and obviously this is a contrived example.

Content that may snap into place reasonably well could be a problem if the user resizes or re-spaces it. Here we can no longer compare the two ISBNs as easily, and selecting the book title gets a bit trickier.

Wrap-up

If you want to use scroll snap properties, test the heck out of them both with users and in browsers. And probably across the more extreme cases of your content.

Update: 30 September 2021

The release notes for Safari Technology Preview 133 suggest some fixes to sticky positioning in cells and padded boxes. This could help with some of the scroll snap weirdness.

  1. Fixed position: sticky used within table cells (r282201)
  2. Fixed incorrectly calculated position: sticky constraints when the scrolling container has padding and borders (r282138)

One Comment

Reply

Cheers Adrian, great post, very insightful!

I’m surprised by the sloppiness of the rollout of this feature. The table headings blocking the content when scroll snapping shocked me.

Leave a Reply to Ian Cancel response

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>