percentage height with display flex breaks layout

I want to implement this layout:

layout

  • where the body takes full view height,
  • it has a fixed height app-bar
  • and a main section that takes the rest available space using flex-grow: 1.

Inside the main section,

  • there is a card that I want to have 80% of the height of the main section
  • and the card to be scrollable (to have content that exceeds its height)

The problem appears to be when I set the card height to 80%. There is no problem when i set it to fixed 800px

body {
  background: #f1f1f1;
  margin: 0;
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
}

body main {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

/* HERE IS THE ISSUE */
/* (uncomment height: 80%) */
body main #main-card {
  height: 400px;
/* height: 80%; */  
  overflow-y: auto;
  background: green;
  padding: 20px;
  width: 400px;  
}

body main #main-card #main-card-content {
  background: #bf8040;
  height: 150vh;
}

body header {
  width: 100%;
  height: 50px;
  background: red;
}
<body>
  <header></header>
  <main>
    <div id="main-card">
      <div id="main-card-content"></div>
    </div>
  </main>
</body>

I can fix it by setting main height to be 100vh minus the height of the header, but I would like to keep the flex-grow property

Here is the codepen that replicates the problem

Any suggestions?

>Solution :

When using percentage heights, you need a defined height on the parent.

Otherwise, the percentage you set has no reference ("80% of what?").

The parent does have flex-grow: 1, but that isn’t a defined height, it’s just a command to consume available space.

Since the app-bar has a fixed height (50px), the solution is actually simple:

Replace flex-grow: 1 with height: calc(100vh - 50px).

The height: 80% on #main-card will work now.

Leave a Reply