1

I want a layout with a header, body, and footer. I do not want to use display: fixed, so I'm only scrolling the body. I use flex-grow: 1 to force the body section to fill the height.

The body has 4 columns. The columns are taller than the height of the body, so the body scrolls. However, the columns do not scroll, only their content.

In this codepen, scroll the middle section with the 4 columns. Note the gold background of the columns does not scroll. Instead, you see the orange background of the body.

How do I get the body content area to fill the screen if there's less content but also have the content background expand with the content when it scrolls? I've tried adding clearing div's and setting the column height to 100%.

Video illustration of the problem: http://recordit.co/eGpT87EmPp

* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}

html,
body {
  height: 100vh;
}

.App {
  background: red;
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.App .Header {
  background: violet;
  display: flex;
  min-height: 2rem;
}

.App .Header .Player {
  background: pink;
  flex: 1 1;
  text-align: center;
}

.App .Body {
  background: orange;
  display: flex;
  flex-grow: 1;
  overflow-y: scroll;
}

.App .Body .Column {
  background: gold;
  box-shadow: inset -1px 0 0 0 black;
  display: flex;
  flex-direction: column;
  flex: 1 1;
  padding-top: 1rem;
}

.App .Tile {
  background: #111;
  color: white;
  margin: 0 auto 1rem;
  padding: 5rem 0;
  text-align: center;
  width: 4rem;
}

.App .Footer {
  background: deepskyblue;
  min-height: 2rem;
}
<div class="App">
  <div class="Header">
    <div class="Player">Player</div>
    <div class="Player">Player</div>
    <div class="Player">Player</div>
    <div class="Player">Player</div>
  </div>
  <div class="Body">
    <div class="Column">
      <div class="Tile">0</div>
      <div class="Tile">1</div>
      <div class="Tile">2</div>
      <div class="Tile">3</div>
      <div class="Tile">4</div>
      <div class="Tile">5</div>
      <div class="Tile">6</div>
      <div class="Tile">7</div>
      <div class="Tile">8</div>
      <div class="Tile">9</div>
      <div class="Tile">10</div>
      <div class="Tile">11</div>
      <div class="Tile">12</div>
      <div class="Tile">13</div>
      <div class="Tile">14</div>
      <div class="Tile">15</div>
      <div class="Tile">16</div>
      <div class="Tile">17</div>
      <div class="Tile">18</div>
      <div class="Tile">19</div>
    </div>
    <div class="Column">
      <div class="Tile">0</div>
      <div class="Tile">1</div>
      <div class="Tile">2</div>
      <div class="Tile">3</div>
      <div class="Tile">4</div>
      <div class="Tile">5</div>
      <div class="Tile">6</div>
      <div class="Tile">7</div>
      <div class="Tile">8</div>
      <div class="Tile">9</div>
      <div class="Tile">10</div>
      <div class="Tile">11</div>
      <div class="Tile">12</div>
      <div class="Tile">13</div>
      <div class="Tile">14</div>
      <div class="Tile">15</div>
      <div class="Tile">16</div>
      <div class="Tile">17</div>
      <div class="Tile">18</div>
      <div class="Tile">19</div>
    </div>
    <div class="Column">
      <div class="Tile">0</div>
      <div class="Tile">1</div>
      <div class="Tile">2</div>
      <div class="Tile">3</div>
      <div class="Tile">4</div>
      <div class="Tile">5</div>
      <div class="Tile">6</div>
      <div class="Tile">7</div>
      <div class="Tile">8</div>
      <div class="Tile">9</div>
      <div class="Tile">10</div>
      <div class="Tile">11</div>
      <div class="Tile">12</div>
      <div class="Tile">13</div>
      <div class="Tile">14</div>
      <div class="Tile">15</div>
      <div class="Tile">16</div>
      <div class="Tile">17</div>
      <div class="Tile">18</div>
      <div class="Tile">19</div>
    </div>
    <div class="Column">
      <div class="Tile">0</div>
      <div class="Tile">1</div>
      <div class="Tile">2</div>
      <div class="Tile">3</div>
      <div class="Tile">4</div>
      <div class="Tile">5</div>
      <div class="Tile">6</div>
      <div class="Tile">7</div>
      <div class="Tile">8</div>
      <div class="Tile">9</div>
      <div class="Tile">10</div>
      <div class="Tile">11</div>
      <div class="Tile">12</div>
      <div class="Tile">13</div>
      <div class="Tile">14</div>
      <div class="Tile">15</div>
      <div class="Tile">16</div>
      <div class="Tile">17</div>
      <div class="Tile">18</div>
      <div class="Tile">19</div>
    </div>
  </div>
  <div class="Footer">Footer</div>
</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Corey
  • 1,977
  • 4
  • 28
  • 42

1 Answers1

1

So it doesn't look like you want the individual columns to scroll. If I've misinterpreted that requirement, then the solution is simple.

Make these adjustments to your code:

.Body {
   background: orange;
   display: flex;
   flex-grow: 1;
   /* overflow-y: scroll; */
   min-height: 0; /* new */
}
    
.Column {
   overflow: auto;  /* new */
   background: gold;
   box-shadow: inset -1px 0 0 0 black;
   display: flex;
   flex-direction: column;
   flex: 1 1;
   padding-top: 1rem;
}

codepen

Here's an explanation for the modifications above: Why don't flex items shrink past content size?


If you just want the .Body element to scroll, add a wrapper:

<div class="Body">
   <section><!---- NEW ----->
     <div class="Column">
        <div class="Tile">0</div>
        <div class="Tile">1</div>
        <div class="Tile">2</div>
        <div class="Tile">3</div>
                . . .

.Body {
   background: orange;
   flex-grow: 1;
   overflow: auto;
}
        
section {
  display: flex;
}

codepen

Here's an explanation for the modifications above: Make background color extend into overflow area

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 1
    Thanks! I did not want the columns to scroll individually, so your second solution is what I needed. – Corey Jul 02 '20 at 10:09