cssscrolloverflow

Problem with scrollable div that is expending


I'm making a full page website / dashboard using tailwindcss, and I have a problem with overflow scroll. instead of making my div scrollable, it extend the div.

My div with 2 elements inside

My div with 6 elements inside

The whole green dev should remain the same size.

I tried many techniques but i think that the problem comes from how flexbox are handled and i dont get everything yet.

My guess is that setting the height to 100% doesn't fix it for the overflow. If so, how can i change this without fixing the height myself (i dont want to hard code it if possible) ?

<div className="h-screen w-screen bg-black flex flex-col p-5">
    <div className="h-40 min-h-40 bg-red-600 mb-5"></div>
    <div className="h-40 min-h-40 bg-blue-600 mb-5"></div>
    <div className="flex-auto flex gap-5 p-5 bg-green-600">
        <div className="flex flex-col h-full gap-5 p-5 w-96 bg-yellow-400">
            <div className="flex-1 bg-slate-600"></div>
            <div className="flex-1  bg-slate-600"></div>
        </div>
        <div className="h-full flex-auto bg-fuchsia-700 p-5 overflow-hidden overflow-y-scroll max-h-full">
            {[...Array(2)].map((_, index) => (
            <div className="flex w-full h-[75px] bg-yellow-950 mb-5">
            {/* ...content... */}
            </div>            
            ))}
        </div>
    </div>
</div>

Here is a reproduction on codepen: https://codepen.io/AlllexxTh/pen/bNbKgaq?editors=1000

EDIT: As my tailwindcss code was maybe unclear, I'm adding code with standard Html css and another codepen: https://codepen.io/AlllexxTh/pen/EaYRoEj

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Demo</title>
  </head>
  <body>
    <div class="screen">
      <div class="header"></div>
      <div class="header"></div>
      <div class="dashboard">
        <div class="dash-container-1">
          <div class="box"></div>
          <div class="box"></div>
        </div>
        <div class="scroll-container">
          <div class="scroll-element"></div>
          ADD MORE 'scroll-element's
        </div>
      </div>
    </div>
  </body>
</html>
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

.screen {
  height: 100vh;
  width: 100vw;
  padding: 10px;
  background-color: black;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.header {
  height: 150px;
  background-color: blue;
}

.dashboard {
  padding: 10px;
  gap: 10px;
  background-color: blue;
  display: flex;
  flex: 1;
}

.dash-container-1 {
  width: 400px;
  background-color: green;
  display: flex;
  flex-direction: column;
  padding: 10px;
  gap: 10px;
}

.box {
  background-color: gray;
  flex: 1;
}

.scroll-container {
  display: flex;
  flex-direction: column;
  padding: 10px;
  gap: 10px;
  flex: 1;
  background-color: red;
  overflow-y: scroll;
}

.scroll-element {
  width: 100%;
  background-color: yellow;
  height: 100px;
}

Thanks for the help !

function extend() {
  const scroller = document.getElementsByClassName("scroll-container")[0];
  scroller.innerHTML = '<div class="scroll-element"></div>' +
    scroller.innerHTML;
}
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

.screen {
  height: 100vh;
  width: 100vw;
  padding: 10px;
  background-color: black;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.header {
  height: 150px;
  background-color: blue;
}

.dashboard {
  padding: 10px;
  gap: 10px;
  background-color: blue;
  display: flex;
  flex: 1;
}

.dash-container-1 {
  width: 400px;
  background-color: green;
  display: flex;
  flex-direction: column;
  padding: 10px;
  gap: 10px;
}

.box {
  background-color: gray;
  flex: 1;
}

.scroll-container {
  display: flex;
  flex-direction: column;
  padding: 10px;
  gap: 10px;
  flex: 1;
  background-color: red;
  overflow-y: scroll;
}

.scroll-element {
  width: 100%;
  background-color: yellow;
  height: 100px;
}
<div class="screen">
  <div class="header"></div>
  <div class="header"></div>
  <div class="dashboard">
    <div class="dash-container-1">
      <div class="box"></div>
      <div class="box"></div>
    </div>
    <div class="scroll-container">
      <div class="scroll-element"></div>
      <button onclick="extend()">ADD MORE 'scroll-element's</button>
    </div>
  </div>
</div>


Solution

  • As it turns out there's some analysis of this topic on this site: Why don't flex items shrink past content size?

    The key thing from that page is that with nested flex containers you have to do something with the outer one too, otherwise it will just grow.

    function extend() {
      const scroller = document.getElementsByClassName("scroll-container")[0];
      scroller.innerHTML += '<div class="scroll-element"></div>'
    }
    * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }
    
    .screen {
      height: 100vh;
      width: 100vw;
      padding: 10px;
      background-color: black;
      display: flex;
      flex-direction: column;
      gap: 10px;
    }
    
    .header {
      height: 150px;
      background-color: blue;
    }
    
    .dashboard {
      padding: 10px;
      gap: 10px;
      background-color: blue;
      display: flex;
      flex: 1;
      overflow: hidden;  /* <------------------------------------- */
    }
    
    .dash-container-1 {
      width: 400px;
      background-color: green;
      display: flex;
      flex-direction: column;
      padding: 10px;
      gap: 10px;
    }
    
    .box {
      background-color: gray;
      flex: 1;
    }
    
    .scroll-container {
      display: flex;
      flex-direction: column;
      padding: 10px;
      gap: 10px;
      flex: 1;
      background-color: red;
      overflow-y: scroll;
    }
    
    .scroll-element {
      width: 100%;
      background-color: yellow;
      min-height: 100px;  /* <--------------------------------------- */
    }
    <div class="screen">
      <div class="header"></div>
      <div class="header"></div>
      <div class="dashboard">
        <div class="dash-container-1">
          <div class="box"></div>
          <div class="box"></div>
        </div>
        <div class="scroll-container">
          <button onclick="extend()">ADD MORE 'scroll-element's</button>
          <div class="scroll-element"></div>
        </div>
      </div>
    </div>

    (and moved the add button to the top of the scroller)