Search code examples
htmlcssbootstrap-4css-grid

Maintaining header/footer position when using grid layout + bootstrap + table overflow


Given the following page layout I need to make sure that the page itself is not scrollable (page height == 100vh), but the table within, if needed is provides the scrolling. The header and the footer should be placed at the top and bottom of the page, not effected by the table's content. Meaning, if the table content exceeds the available vertical space, it can not push the footer downward and instead provide scrolling in place.

The current layout is a root div that starts with a Bootstrap4 navbar following it a page_container that sets up a grid layout for its internal header, content, footer divs.

JSFiddle with a layout containing a table that does not exceeds page height: https://jsfiddle.net/kvdyg4q5/

JSFiddle with a layout containing a table that exceeds page height: https://jsfiddle.net/1nv7hqg6/

AS you can see, the table is pushing the footer down.. that is the issue.

The css in use

<style type="text/css">
    #root {
      height: 100%;
      min-height: 100vh;
      max-height: 100vh;
    }

    .page_container {
      max-height: calc(100vh - 70px);
      height: calc(100vh - 70px);
      min-height: calc(100vh - 70px);
    }

    .table_container {
      display: grid;
      height: 100%;
      grid-template-rows: auto 1fr auto;
    }

    .table_body {
      display: block;
      height: 100%;
      overflow-y: scroll;
    }
</style>

The HTML layout

<body>
<div id="root">
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark"><a class="navbar-brand" href="#">Company</a>
        <div class="collapse navbar-collapse" id="navbarNav">
            <ul class="navbar-nav mr-auto">
                <li class="nav-item"><a id="vehicles_navbar" class="nav-link" href="#">navbar1</a></li>
                <li class="nav-item"><a id="vehicles_navbar" class="nav-link" href="#">navbar2</a></li>
                <li class="nav-item"><a id="vehicles_navbar" class="nav-link" href="#">navbar3</a></li>
                <li class="nav-item"><a id="vehicles_navbar" class="nav-link" href="#">navbar4</a></li>
                <li class="nav-item"><a id="vehicles_navbar" class="nav-link" href="#">navbar5</a></li>
                <li class="nav-item"><a id="vehicles_navbar" class="nav-link" href="#">navbar6</a></li>
                <li class="nav-item"><a id="vehicles_navbar" class="nav-link" href="#">navbar7</a></li>
                <li class="nav-item"><a id="vehicles_navbar" class="nav-link" href="#">navbar8</a></li>

            </ul>
        </div>
    </nav>
    <div style="padding: 6px;">
        <div class="page_container">
            <div class="table_container">
                <div>
                    <h1>HEADER</h1>
                </div>
                <div>
                    <div>
                        <table class="table">
                            <thead>
                                <tr>
                                    <th scope="col">Column 1</th>
                                    <th scope="col">Column 2</th>
                                    <th scope="col">Column 3</th>
                                    <th scope="col"> Column 4 </th>
                                    <th scope="col">Column 5</th>
                                </tr>
                            </thead>
                            <tbody class="table_body">
                                <tr>
                                    <td colspan="5">
                                        <h3>Row</h3>
                                    </td>
                                </tr>
                                <tr>
                                    <td colspan="5">
                                        <h3>Row</h3>
                                    </td>
                                </tr>
                                <tr>
                                    <td colspan="5">
                                        <h3>Row</h3>
                                    </td>
                                </tr>
                                <tr>
                                    <td colspan="5">
                                        <h3>Row</h3>
                                    </td>
                                </tr>
                                <!-- more rows...-->

                            </tbody>
                        </table>
                    </div>
                </div>
                <div>
                    <h2>Footer</h2>
                </div>
            </div>
        </div>
    </div>
</div>

Solution

  • You don't need CSS grid for this, You can simply use flexbox and make content flex:1 0 0 with overflow:auto

    [root] {
      height: 100vh;
      display: flex;
      flex-direction: column;
    }
    
    [page] {
      flex: 1;
      display: flex;
      flex-direction: column;
    }
    
    [content] {
      flex: 1 0 0;
      overflow: auto;
    }
    
    
    /* Sticky Header */
    table {
      position: relative;
    }
    
    th {
      position: sticky;
      top: 0;
      background: black;
      color: white;
    }
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
    <div root>
      <div navbar>
        <nav class="navbar navbar-expand-lg navbar-dark bg-dark"><a class="navbar-brand" href="#">Company</a><button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button>
          <div class="collapse navbar-collapse" id="navbarNav">
            <ul class="navbar-nav mr-auto">
              <li class="nav-item"><a id="vehicles_navbar" class="nav-link" href="#">navbar1</a></li>
              <li class="nav-item"><a id="vehicles_navbar" class="nav-link" href="#">navbar2</a></li>
              <li class="nav-item"><a id="vehicles_navbar" class="nav-link" href="#">navbar3</a></li>
              <li class="nav-item"><a id="vehicles_navbar" class="nav-link" href="#">navbar4</a></li>
              <li class="nav-item"><a id="vehicles_navbar" class="nav-link" href="#">navbar5</a></li>
              <li class="nav-item"><a id="vehicles_navbar" class="nav-link" href="#">navbar6</a></li>
              <li class="nav-item"><a id="vehicles_navbar" class="nav-link" href="#">navbar7</a></li>
              <li class="nav-item"><a id="vehicles_navbar" class="nav-link" href="#">navbar8</a></li>
    
            </ul>
          </div>
        </nav>
      </div>
      <div page>
        <div header>
          <h1>HEADER</h1>
        </div>
        <div content>
          <div>
            <table class="table">
              <thead>
                <tr>
                  <th scope="col">Column 1</th>
                  <th scope="col">Column 2</th>
                  <th scope="col">Column 3</th>
                  <th scope="col"> Column 4 </th>
                  <th scope="col">Column 5</th>
                </tr>
              </thead>
              <tbody class="table_body">
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
                <tr>
                  <td colspan="5">
                    <h3>Row</h3>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
        <div footer>
          <h2>Footer</h2>
        </div>
      </div>
    </div>