Fixing overflow: scroll padding in Firefox

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:

An animated close-up of a web page element for picking "Clothing Color". 11 options are displayed in a row but only a few are visible. A cursor is shown scrolling horizontally through all the available options. The scrolling element occupies the full width, but there is some padding before the first option and after the last option.

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:

Screenshot of the .scroll-container element scrolled to its leftmost edge. The Dev Tools overlay shows a padding-left is applied and the child elements of the .scroll-container are some distance away from the left edge of the container, respecting the padding.

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.

An animated gif of the .scroll-container element scrolled to its leftmost edge. The padding-left is visible. The cursor is shown scrolling the element to the right, but there is no visible padding-right.

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.

Screenshot of the .scroll-container element scrolled to its rightmost edge. Although the Dev Tools overlay shows a padding-right is applied, the child elements of the .scroll-container do not respect this padding and are flush with the right edge of the container.

Ah, don't you just love browser compatibility issues?

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.

You can see this in action in the Codepen demo below.

See the Pen Overflow-x scroll with padding not working in Firefox by Aileen Rae (@aileen-r) on CodePen.