Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No bottom padding when using display: grid and scroll

I have a container div which has some padding, display: grid and overflow: auto set. When a child div's height is bigger than the parent's one and a scroll bar appears, it scrolls so that there is no bottom padding.

Here is a Fiddler.

.container {
    background: red;
    display: grid;
    height: 300px;
    padding: 3em;
    overflow: auto;
    width: 300px;
}

.child {
    height: 500px;
    background: #000;
}
<div class="container">
    <div class="child"></div>
</div>

However, if the container is made any other than display: grid, the bottom padding is there when scrolled down.

Is this an expected behavior of display: grid element? If so, why? What is a proper way of recovering the bottom padding, preferably, with CSS only?

like image 235
Alexander Abakumov Avatar asked Feb 03 '20 23:02

Alexander Abakumov


2 Answers

Not sure if it's the intended result or a bug but a workaround is to consider an extra element (using pseudo element) to recover the padding:

.container {
    background: red;
    display: grid;
    height: 300px;
    padding: 3em;
    overflow: auto;
    width: 300px;
}

.container:after {
  content:"";
  height:3em;
}

.child {
    height: 500px;
    background: #000;
}
<div class="container">
    <div class="child"></div>
</div>
like image 197
Temani Afif Avatar answered Sep 30 '22 14:09

Temani Afif


@temani-afif's great answer put me on the right track. But I found it doesn't work when you have columns - the extra :after element might get pushed to be the last item in a grid row and not do anything, like this:

.container {
    background: red;
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto;
    grid-gap: 1em;
    height: 300px;
    padding: 3em;
    overflow: auto;
    width: 300px;
}

.container:after {
  content:"";
  height:3em;
}

.child {
    height: 500px;
    background: #000;
}
<div class="container">
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
</div>

The first part of my solution was to mark the :after element as grid-column: span 2; (adjust as needed for your layout)... but then it gave me too much bottom padding because we were seeing the grid-gap setting plus the height of the item added. Final solution was to set the height of the psudo element to the padding value minus the grid-gap value:

.container {
    background: red;
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto;
    grid-gap: 1em;
    height: 300px;
    /* remove the bottom padding so it looks normal if your
       overflow: auto does not end up overflowing/scrolling */
    padding: 3em 3em 0;
    overflow: auto;
    width: 300px;
}

.container:after {
    grid-column: span 2;
    height: 2em; /* 3em (desired padding effect) minus 1em (grid-gap setting) */
    content: "";
}

.child {
    height: 500px;
    background: #000;
}
<div class="container">
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
</div>

But watch out - if your grid-gap and container padding are the same - try something like height: 0.01em instead of 0, which does not seem to work.

like image 32
squarecandy Avatar answered Sep 30 '22 14:09

squarecandy