css – Put scrollable table on remaining height (between header and footer)

Attached Img.
Please refer to attached image. I have a Header, content and Footer.

Both Header and Footer are fixed. They should be visible at all times.
And inside the content, I have a <table>. I want to make this <table> take all the remaining height between the header and footer.

The table might contain a lot of data, so I want to make it scrollable as well.

The snippet below shows the closest I got by putting the table into a div with overflow-y: auto; max-height: 200px; (fixed size)

How can I make it take the full / remaining height automatically?

body {
  background: green;
  padding: 10px;
}

.header {
  background: lightblue;
}

.content {
  background: lime;
  overflow-y: auto;
  max-height: 200px;
}

.footer {
  background: orange;
}
<div class="header">
  Some awesome title
</div>
<div class="content">
  <table>
    <thead>
      <tr>
        <th>Lorem.</th>
        <th>Numquam.</th>
        <th>Id.</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Lorem.</td>
        <td>Eos.</td>
        <td>Vel.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Quod.</td>
        <td>Quaerat?</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Explicabo!</td>
        <td>Esse.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Quo.</td>
        <td>Praesentium!</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Perferendis!</td>
        <td>Necessitatibus.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Facere.</td>
        <td>Ex.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Ducimus.</td>
        <td>Architecto.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Porro!</td>
        <td>Voluptatum.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Culpa?</td>
        <td>Dignissimos?</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Alias.</td>
        <td>Deserunt!</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Mollitia!</td>
        <td>Doloribus?</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Quia.</td>
        <td>Aspernatur.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Est!</td>
        <td>Nihil.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Neque.</td>
        <td>Asperiores!</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Cupiditate.</td>
        <td>Rerum.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Eligendi.</td>
        <td>Qui?</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Libero.</td>
        <td>Molestiae!</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Suscipit.</td>
        <td>Nostrum.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Minima.</td>
        <td>Voluptatem.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Quam.</td>
        <td>Mollitia.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Minus!</td>
        <td>Corporis.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Perferendis.</td>
        <td>Deleniti.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Asperiores!</td>
        <td>Rem.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Molestiae.</td>
        <td>Dignissimos?</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Doloribus.</td>
        <td>Ipsam.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Aperiam.</td>
        <td>Obcaecati.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Suscipit.</td>
        <td>Harum?</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Cupiditate.</td>
        <td>Tenetur.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Ea!</td>
        <td>Ipsam.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Officia!</td>
        <td>Velit.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Mollitia!</td>
        <td>Voluptatibus.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Rerum.</td>
        <td>Accusamus?</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Distinctio.</td>
        <td>Ducimus.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Iure.</td>
        <td>Recusandae.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Quibusdam.</td>
        <td>Veritatis.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Optio!</td>
        <td>Voluptatum.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>At.</td>
        <td>Facere.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Illum?</td>
        <td>Placeat!</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Unde?</td>
        <td>Explicabo.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Reiciendis.</td>
        <td>Architecto.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Quasi?</td>
        <td>Praesentium!</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Odit!</td>
        <td>Ratione.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Expedita?</td>
        <td>Incidunt!</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Nemo.</td>
        <td>Reprehenderit?</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Blanditiis.</td>
        <td>A.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Iusto.</td>
        <td>Similique.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Sint?</td>
        <td>Corrupti.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Consequatur.</td>
        <td>Nihil!</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Magni.</td>
        <td>Deleniti.</td>
      </tr>
      <tr>
        <td>Lorem.</td>
        <td>Nobis!</td>
        <td>Eius.</td>
      </tr>
    </tbody>
  </table>
</div>
<div class="footer">
  Pagination stuff
</div>

Suppose you have this HTML:

<div class="header"></div>
<div class="content">table</div>
<div class="footer"></div>

You were searching for this CSS solution (as flexbox is not supported in IE9):

body {margin: 0;}
.header {height: 50px;}
.content {height: calc(100vh - 100px); overflow-y: scroll;}
.footer {height: 50px;}

But I would use/prefer this one:

body {margin: 0;}
.header {height: 50px; position: fixed; top: 0;}
.content {padding: 50px 0;}
.footer {height: 50px; position: fixed; bottom: 0;}

The latter one uses the normal page scroll, instead of a div overflow, which causes less cross browser issues and better performance on (older) mobiles.

You will need to find screen display height using jQuery and use it to set height of table. Scrolling will happen automatically.

Solved with flexbox following this snippet: https://codepen.io/anthonyLukes/pen/DLBeE

Previous attempts on using it failed, because I also had a “Navbar” which I thought didn’t matter, as it was all wrapped inside a <router-outlet> like so:

<div class="container">
  <app-sidebar></app-sidebar>
  <div class="main">
    <app-navbar></app-navbar>
    <router-outlet></router-outlet>
  </div>
</div>

When I tried using flexbox, my footer wasn’t visible.. the content area was “taking all remaining areas”.. that’s what I thought..

So what I did to fix was:
1. put a margin-top with the height of the navbar on the .header

.header {
  flex: 0 0 auto;
  margin-top: 2.5em;
}

2. make the div that’s wrapping the header, content, and footer “move up”:

.page {
  display: flex;
  flex-flow: column;
  margin-top: -2.5em;
}

There’s probably a better and correct way of doing this, I don’t have a good understanding of how flexbox works.. yet, but what I noticed, is that flex: 1 1 auto; will “grow/expand to the remaining height”, the height of the entire page, not the height of its parent’s div.

So adding a margint-top: 2.5em; to the header, is basically forcing it to take into account the “navbar’s height” when calculating how much it can grow.

Once that’s done, I shift the entire thing up again by the same margin.

Here’s the end result: img