~bfiedler/website

c07cbf7c53644c8bf6a45fad5675799c4467ce4b — Ben Fiedler a month ago c21ff89
Add new post
1 files changed, 157 insertions(+), 0 deletions(-)

A content/blog/css-avoid-horizontal-scrolling.md
A content/blog/css-avoid-horizontal-scrolling.md => content/blog/css-avoid-horizontal-scrolling.md +157 -0
@@ 0,0 1,157 @@
---
title: "CSS: Avoid horizontal scrolling"
date: 2021-06-17T14:28:40+02:00
draft: true
---

> This piece is a bit of a rant and a bit of advice. If you are not in the mood
> to read this, you can find a TL;DR at the bottom.

If you had told me last year that I'd write not one, but two blog posts about
web design, I would not have believed you. Alas here we are, and I'm going to
tell you about another pet peeve of mine when it comes to web design, and how to
fix it.

I view about half of the entire content I consume via my mobile phone, which
belongs to the class of phones with a not-super-wide screen. In fact, it's width
as reported by the Firefox and Chrome viewport simulators is 375 pixels wide,
which is on the smaller end of the spectrum but not tiny. And yet many websites
I visit destroy the visitor's mobile viewing experience with a simple issue:
horizontal scrolling.

There I am, happily reading a blog post or article from the front page of
`$AGGREGATOR` and suddenly I'm not scrolling down, but down-right and I
constantly have to scroll back to the left in order to read the sentence. Even
worse is the experience if the site for some reason has a minimum width larger
than my screen is wide. Then reading becomes _really_ cumbersome and more often
than not I decide that it's not worth the hassle to continue reading and move
on to the next article. I find that quite sad, since the author of the article I
skipped invested time and effort to produce it, and the only reason I'm not
reading is because it requires horizontal scrolling.

# Two types of scrolling madness

The smartphone browsers I have used in the past had two scrolling modes
when scrolling is possible in both horizontal and vertical directions.

One of them is to always allow the user to scroll in both directions. This
annoys me in the following way: scrolling downward with my thumb is not a
perfectly vertical motion, and towards the end of it an imperfect motion causes
the site to scroll sideways off into oblivion.

The other one locks a scroll direction at the start of the scroll and restricts
movement to that axis. This seems like a good idea in practice, but it does not
work well for small adjustments, as slight movements during the initial scroll
lock the wrong axis, and there is a small cooldown time until the lock releases.

My conclusion is that both scrolling behaviours suck, so it's best to avoid them
as much as possible. So let's fix it! Here's a bunch of tips that hopefully help
you understand and fix this issue. I will only concern myself with mobile
design, as this issue is not as prevalent on laptops and desktops.

# Use viewport scaling

Some sites do not have [viewport
scaling](https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag)
enabled. This is a browser feature which accounts for pixel density and screen
size differences between low and high resolution screens. For example, even
though my phone actually has a screen that is 750px wide, displaying the site
for a 750px wide screen causes the content to become tiny and unreadable.
Readers then have to use zoom and -- joy -- horizontal scrolling to read the
content.

Using viewport scaling accounts for this discrepancy, and ensures that the page
is rendered at a sane size.

# Vertical design is superior

When designing a site, make sure that the mobile version is designed with
verticality in mind. Smartphone screens are narrow so information rarely, if
ever, fits nicely side-by-side. Instead use the infinite vertical space you have
available and stack it on top of each other.

Sometimes it might be better to outright remove some features of the full-width
site. Is a navbar really necessary when viewing a blog post on a mobile screen?
Probably not. There should still be some navigation which allows you to go back
to the index, for example. It is important to strike the right balance of
feature and layout here, and some experimenting might be required.

# Be conservative about minimum width

When I was still in high school a few years back my best friend used to have an
interesting metric for selecting his mobile phones: the more durable the better.
He was, in fact, quite clumsy[^2] when handling his phone so it made a lot of
sense to him to choose a cheap and durable phone. I do not quite recall what the
actual model was, but it was an LG phone similar to the [Optimus L3
E400](https://www.lg.com/ch_de/smartphones-handys/lg-E400-optimus-l3), with a
whopping 256MB RAM and a 320x240 display. He used it as his daily driver, as it
could do everything he needed: play music and browse the web.

I do not know whether he was as annoyed as I am about this issue, but everytime
I work on mobile web design I think of him and his phone, and that he and others
with really small screens would maybe enjoy my content as well. Thus I try to
design this website to be as usable as possible, even on a 240x360 screen.
Starting as 360px is fine for most purposes as well -- it is definitely an
improvement over doing nothing.

# Dealing with wide content

Paragraphs of prose have the neat property that they are easily compressed
horizontally, and still look nice on small screen sizes. Unfortunately, this is
not possible for very long words, as the default CSS behaviour is to let them
overflow to the side. The CSS property
[`word-break`](https://developer.mozilla.org/de/docs/Web/CSS/word-break) can
help here: setting it to `break-word` allows the browser to break very long
words. It is not a very nice way of breaking words (no hyphen is inserted
to indicate breakage), but it makes the page fit nicely without horizontal
scrolling, which is more important. You can see an example of this happening
here: Donaudampfschifffahrtsgesellschaftskapitän. Try viewing it in 240px or
360px width and note how only the offending word is broken apart.

There are two other content types where I frequently encounter overflow: images
and source code.

Images are easily handled: make sure they are always at most 100% wide.
Sometimes the image loses detail on very small screens, but that is totally
fine. Make sure users can access the raw image, for example by it's URL.

Source code poses a bigger problem: line wrapping for code straight up sucks, so
it has to be presented as is. Here we cannot nicely avoid horizontal scrolling,
but we can ensure that we only scroll the code blocks and not the entire page.
There are 1001 different ways to achieve this, on this blog I fix it by [adding
the `overflow-x` property to the `<pre>`
tag](https://git.sr.ht/~bfiedler/website/tree/2915f7b00f1034e64c1e3f4562bfb4bc3f0df302/item/assets/style.scss#L177).

Interestingly, this is the thing most blogs or articles get wrong: Most of the
content neatly fits into the screen width, but overflow of one code block spills
over and ruins the scrolling experience on the entire page.

# Test it!

Finally, all theoretical discussion is useless if you do not test your design!
All major modern browsers have some responsive design mode which allows you to
set the viewport's dimensions and see how your site behaves. On Firefox and
Chrome it is part of the devtools, which are accessed by the keyboard shortcut
`Ctrl+Shift+I`.

And if you have some ~~unwilling participants~~ friends, ask them to check out
your site on mobile and give feedback! As an added bonus you get a wider browser
coverage this way.

# Conclusion

Hopefully this post explained why I think we should abolish horizontal
scrolling, and give you practical tips on how to avoid it. If you have any
questions or comments feel free to reach out to me [on
Mastodon](https://mastodon.3fx.ch/@bfiedler) or via my [public
inbox](https://lists.sr.ht/~bfiedler/public-inbox).

# TL;DR

 * Horizontal scrolling sucks
 * Vertical composition is superior
 * Be conservative about minimum width, support at least 360px, if not 240px
 * If you need wider content then scroll locally
 * Test your site using the devtools supported by all major modern browsers

[^2]: You know who you are ;)