Search code examples
htmlcsscss-grid

Overflow not triggered with position:absolute


In this layout I'm using CSS grid with position: absolute to show a list of items overlaid on top of a map. My problem is the overflow-x: auto is not getting triggered causing only the first few items to be displayed.

By changing the grid-auto-columns of the list from minmax(auto, 1fr) to minmax(0, 1fr) I do get a scrollbar however the items are then overlapping each other.

CodePen: https://codepen.io/tgel0/pen/ZEbKZvb

.wrapper{
  display: grid;
  grid-template-columns: 0.5fr 0.5fr 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  height: 100vh;
  width: 100vw;
  grid-template-areas:
  "side side main main"
  "side side main main"
}

.side {
  grid-area: side;
  display: grid;
  grid-template-columns: 1fr;
  padding: 20px;
  color: #fff;
  background-color: green;
}


.main {
  grid-area: main;
  display: grid;
  background-color: gray;
  grid-template-columns: 1px 1fr 1px;
  gap: 20px;
  position: relative;
  overflow-y: auto;
  overflow-x: hidden;
}

.main > * {
  grid-column: 1 / -1;
}

.map {
  background-image: url("https://lh3.googleusercontent.com/-bQzIWFMAYus/WXy3WDcphBI/AAAAAAAAAMs/unOi6HiEoi4VWaM0WiP5q32q9zDbIhUvwCLcBGAs/s1600/7-29-2017%2B11-14-59%2BAM.jpg");
  height: 100%;
  overflow: auto;
}

.container-for-items {
  display: grid;
  grid-template-columns: 10px;
  grid-template-rows: 1fr;  
  grid-auto-columns: minmax(0, 1fr); /* minmax(auto, 1fr); */
  grid-auto-flow: column;
  grid-gap: 20px;
  padding: 20px;
  z-index: 99;
  position: absolute;
  bottom: 20px;
  overflow-x: auto;
}

container-for-items:before,
.container-for-items:after {
  content: '';
  width: 10px;
}

.item {
  display: grid; 
  background-color: white;
  border: 2px solid blue;
  padding: 25px;
  width: 300px;
  height: 150px;
}
<div class="wrapper">
  <div class="side">Don't scroll</div>
  <div class="main">
    <div class="map"></div>
    <ul class="container-for-items">
      <li class="item">This is item 1</li>
      <li class="item">This is item 2</li>
      <li class="item">This is item 3</li>
      <li class="item">This is item 4</li>
      <li class="item">This is item 5</li>
      <li class="item">This is item 6</li>
      <li class="item">This is item 7</li>
      <li class="item">This is item 8</li>
      <li class="item">This is item 9</li>
      <li class="item">This is item 10</li>
      <li class="item">This is item 11</li>
    </ul>    
  </div>  
</div>


Solution

  • There's a lot going on this layout—nested grids, absolute positioning, pseudo elements, a background image, and a lot of seemingly unnecessary code—so algorithms may be conflicting (e.g., I keep getting different renderings on Chrome/FF vs Edge).

    I think the simplest solution is to remove all unnecessary code, absolutely position the image (not the container), and simplify the grid structures.

    No changes are necessary in the HTML.

    .wrapper{
      display: grid;
      grid-template-columns: 0.5fr 0.5fr 1fr 1fr;
      grid-template-rows: 1fr 1fr;
      height: 100vh;
      /* width: 100vw; */
      grid-template-areas:
      "side side main main"
      "side side main main"
    }
    
    .side {
      grid-area: side;
      display: grid;
      /* grid-template-columns: 1fr; */
      padding: 20px;
      color: #fff;
      background-color: green;
    }
    
    .main {
      grid-area: main;
      display: grid;
      background-color: gray;
      /* grid-template-columns: 1px 1fr 1px; */
      gap: 20px;
      position: relative;
      /* overflow-y: auto; */
      /* overflow-x: hidden; */
    }
    
    /* .main > * {
      grid-column: 1 / -1;
    } */
    
    .map {
      background-image: url("https://lh3.googleusercontent.com/-bQzIWFMAYus/WXy3WDcphBI/AAAAAAAAAMs/unOi6HiEoi4VWaM0WiP5q32q9zDbIhUvwCLcBGAs/s1600/7-29-2017%2B11-14-59%2BAM.jpg");
      height: 100vh; /* adjustment */
      width: 100%; /* new */
      position: absolute; /* new */
      /* overflow: auto; */
    }
    
    .container-for-items {
      display: grid;
      /* grid-template-columns: 10px; */
      grid-template-rows: 150px; /* adjustment; from grid items */  
      grid-auto-columns: 300px; /*  adjustment; from grid items */
      /* grid-auto-flow: column; */
      grid-gap: 20px;
      padding: 20px;
      z-index: 99;
      /* position: absolute; */
      /* bottom: 20px; */
      align-self: end; /* new */
      overflow-x: auto;
      position: relative; /* for Edge */
    }
    
    /* reverse collapsing margin at container end */
    /* https://stackoverflow.com/q/38993170/3597276 */
    /* .container-for-items:before (unnecessary; remove) */
    .container-for-items:after {
      content: '';
      width: 10px;
      grid-row: 1;
    }
    
    .item {
      grid-row: 1; /* new */
      display: grid; 
      background-color: white;
      border: 2px solid blue;
      padding: 25px;
      /* width: 300px;  */ /* move to grid-template-columns */
      /* height: 150px; */ /* move to grid-template-rows */
    }
    
    /* new */
    body {
      margin: 0;
    }
    
    * {
      box-sizing: border-box;
    }
    <div class="wrapper">
      <div class="side">Don't scroll</div>
      <div class="main">
        <div class="map"></div>
        <ul class="container-for-items">
          <li class="item">This is item 1</li>
          <li class="item">This is item 2</li>
          <li class="item">This is item 3</li>
          <li class="item">This is item 4</li>
          <li class="item">This is item 5</li>
          <li class="item">This is item 6</li>
          <li class="item">This is item 7</li>
          <li class="item">This is item 8</li>
          <li class="item">This is item 9</li>
          <li class="item">This is item 10</li>
          <li class="item">This is item 11</li>
        </ul>
      </div>
    </div>

    revised codepen