These days I have been developing a component that would allow the user to scroll horizontally by grabbing it with the mouse and moving it. It was working fine until I noticed that when I added padding to the parent, it was not being applied on the right side, only to the left. What is going on?
When inspecting the element, it is clear that the padding is applied relative to the parent, and will not follow or adjust to the overflowing content:
I created two bars that represent the horizontal padding to show where our padding actually is when scrolling:
So how do we fix it?
Using only CSS
We need to create an element at the end of the parent with the width equal to the padding we want on the right, in this case, an element with 50px of width, and 1px of height. To do this the ::after selector can be utilized, something like this (to make this work with vertical scrolling, switch the height and width values):
.parent::after {
content: "";
display: block;
width: 50px;
height: 1px;
flex-shrink: 0; /* because we have display: flex on the parent */
}
But still, it isn't that good because now if the consumer of my component wants to change the padding of the parent, it isn't straightforward since there are two places where I store the padding. As it is a component, it could be sent through a prop but all the other styles would go somewhere else, weird.
With a container block
We can add an extra div that is a directly child of .parent and will hold the padding property. To make it take all the space necessary to fit all the blocks we can use a little trick: the display: inline-flex property. And now everything works fine, both on horizontal and vertical scrolls:
These days I have been developing a component that would allow the user to scroll horizontally by grabbing it with the mouse and moving it. It was working fine until I noticed that when I added padding to the parent, it was not being applied on the right side, only to the left. What is going on?
After searching about it I found this demo and then it was all clear. I created a reproduction on CodeSandbox: https://codesandbox.io/s/crimson-brook-7jh1m
When inspecting the element, it is clear that the padding is applied relative to the parent, and will not follow or adjust to the overflowing content:
I created two bars that represent the horizontal padding to show where our padding actually is when scrolling:
So how do we fix it?
Using only CSS
We need to create an element at the end of the parent with the width equal to the padding we want on the right, in this case, an element with 50px of width, and 1px of height. To do this the
::after
selector can be utilized, something like this (to make this work with vertical scrolling, switch the height and width values):But still, it isn't that good because now if the consumer of my component wants to change the padding of the parent, it isn't straightforward since there are two places where I store the padding. As it is a component, it could be sent through a prop but all the other styles would go somewhere else, weird.
With a container block
We can add an extra div that is a directly child of
.parent
and will hold thepadding
property. To make it take all the space necessary to fit all the blocks we can use a little trick: thedisplay: inline-flex
property. And now everything works fine, both on horizontal and vertical scrolls:The final code: https://codesandbox.io/s/heuristic-torvalds-nz4ll