skip to Main Content

Example HTML and CSS:

.root {
  background-color: green;
}

.outer {
    display: grid;
    grid-template-rows: 100vh;
    grid-template-columns: 100px;
    padding: 5rem;
    overflow-y: auto;
}

.nav {
  background-color: red;
  height: 150vh;
}
 
* {
  box-sizing: border-box;
}
<div class="root">
  <div class="outer">
    <div class="nav"></div>
  </div>
</div>

Fiddle example: https://jsfiddle.net/dr18cbet/

In this contrived example, scrolling to the bottom of the grid container doesn’t include the grid container’s bottom padding.

There are definitely better ways to organize this code to work, for example, moving the padding and overflow settings to the grid item (in this case, nav). I also noticed that if I set grid-template-rows to it’s default auto the padding also appears as expected. However, this combo of overflow + padding settings on the grid container and the grid item getting an extrinsic height (in the example it is 100vh) results in the container’s bottom padding not being applied. Why is that? I dug through the css specs, but couldn’t find an explanation.

2

Answers


  1. The trick is that you have to consider the grid area which is a kind of "extra wrapper" between the grid container and the grid item.

    Your overflow is applied to the grid container and the grid area is not overflowing but the grid item is overflowing the grid area (not the grid container).

    Here is another code to better understand. The first div is not overflowing (the grid area) but the nested div (the grid item) is overflowing and in such configuration the bottom padding is not visible but still present and the nested div is overlapping it.

    .box {
      border: 2px solid;
      height: 200px;
      aspect-ratio: 1;
      padding: 20px;
      box-sizing: border-box;
      overflow: auto;
    }
    
    .box > div {
      height: 100%;
    }
    
    .box > div > div {
      height: 220px;
      background: blue;
    }
    <div class="box">
      <div>
        <div></div>
      </div>
    </div>

    It’s a bit tricky but it’s not something related to CSS Grid. This is how overflow behaves.

    Somewhere in the specification you can read:

    NOTE: This padding represents, within the scrollable overflow rectangle, the box’s own padding so that when its content is scrolled to the end, there is padding between the end-edge of its in-flow (or floated) content and the border edge of the box. It typically ends up being exactly the same size as the box’s own padding, except in a few cases—such as when an out-of-flow positioned element, or the visible overflow of a descendant, has already increased the size of the scrollable overflow rectangle outside the conceptual “content edge” of the scroll container’s content.

    The "visible overflow of a descendant" is the key here

    Login or Signup to reply.
  2. As a supplement to @temani-afif’s answer, according to the spec:

    The max-content size (min-content size) of a grid container is the sum of the grid container’s track sizes (including gutters) in the appropriate axis, when the grid is sized under a max-content constraint (min-content constraint).

    Here, the grid container’s max-content size is determined based on the size of the track, not the height of the items that are placed. The scrolling area height of your scroll container computed based on the padding box 100vh + your padding, not the grid item’s height 150vh.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search