cssbootstrap-4flexboxviewport-units

How do I best use CSS to make a page with tall nested elements to be limited to the height of the viewport?


How do I best enforce a page to be limited to the height of the viewport? I would like to manage the overflow-y on children elements, but it seems I cannot get the height to constrain--I can only manage a max-height in pixels or a percentage. I think I need to constrain the height of certain elements to the remaining portion (not a percentage) of the viewport height, but I can't find a way to do that.

(I am using bootstrap, but I suspect the answer isn't bootstrap-centric.)

I thought maybe I could use flex with flex-grow, but that doesn't constrain the height either. What am I missing?

<div class="container d-flex flex-column ">
 <div>
 My full-width page title goes here 
 </div>
  <div class="row flex-grow-1">
    <div class="col col-4">
      potentially long content here
    </div>
    <div class="col-8">
     main content 
    </div>
  </div>
</div>

With CSS

body {
  height: 100vh;
}

.row {
  margin-top: 20px;
}

.col {
  border: solid 1px black;
  padding: 10px;
  overflow-y: scroll;
}

(Fiddle)

Actual: Page is unlimited height; inner scroll bar is moot; viewport scroll bar is on

Desired: Page uses the whole height of the viewport and no more; inner scroll bar effective; no viewport scroll bar


Solution

  • If you aren't married to using bootstrap/flexbox, css grid makes this pretty easy.

    HTML

    <div class="wrapper">
       <div class="header">
         My full-width page title goes here 
       </div>
       <div class="sidebar">
          sidebar content
        </div>
        <div class="main">
         main content 
        </div>
    </div>
    

    CSS

    html, body, .wrapper {
      height: 100%;
    }
    
    .wrapper {
      display: grid;
      grid-template-columns: 1fr 2fr;
      grid-auto-rows: min-content auto;
      grid-template-areas: 
        "header header"
        "sidebar main";
    }
    
    .header {
      grid-area: header;
      background: red;
    }
    
    .sidebar {
      grid-area: sidebar;
      overflow: auto;
    }
    
    .main {
      grid-area: main;
    }
    

    fiddle