The preamble and the problem
(You can skip my opening context and jump to the workaround.)
I recently ran into a problem with padding in scrolling elements while working on an exercise in Josh Comeau's fantastic CSS for JavaScript Developers course.
More specifically, I was trying to implement this scrolling container of buttons:
The row of buttons is allowed to occupy the full width of the container, but there is some padding on the left when scrolled to the left edge and some padding on the right when scrolled to the right edge. How do we get this padding?
You might guess that adding padding-left
and padding-right
properties to the scrolling container would solve this problem, something like this:
This would fix it...almost. The padding on the scrolling container behaves nicely in WebKit browsers, but we run into a problem when we try this in Firefox.
If we use Dev Tools to inspect the scrolling container, we can see that, yup, there is definitely padding-right
. But, unlike other browsers, Firefox does not consider this padding to be part of the scrollable space.
Ah, don't you just love browser compatibility issues?
(ℹ For the curious, the W3C discussion went back-and-forth on the desired behaviour here. Ultimately they have decided that the WebKit implementation is correct. The bug tracker for Firefox has an open issue logged where you can view the latest updates on the eventual fix.)
Workaround for overflow:scroll padding in Firefox
As is often the case with CSS, there are a few workaround solutions. I chose to remove the padding-right
from the scrolling container and add that space as margin to the last child element inside instead.
.scroll-container > *:last-child {
margin-right: 32px;
}
Breaking this down:
-
.scroll-container
is self-explanatory. This is the scrolling element. -
*
is the universal selector in CSS. It matches all elements. -
:last-child
is a pseudo-class selector. It acts as a modifier, meaning*:last-child
selects all elements that are the last child of their parent element. -
>
is the child combinator. My rule only applies to*:last-child
if it is a direct child of.scroll-container
. This ensures we don't accidentally apply unwanted margin to grandchildren elements or beyond.
(⚠ The universal *
selector can be unweildy. If you know what the last child in your scrolling container is, I recommend replacing this with a more specific selector.)
You can see this in action in the Codepen demo below.
Top comments (0)