skip to Main Content

I am new to web coding, and met a strange behavior when using flexbox.

When a parent is using flex-grow: 1, the child element height: 100% doesn’t work.

I saw several solutions but doesn’t work for me. Does anyone could explain the reason and share some solutions? Thanks!

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

html,
body {
  min-height: 100vh;
}

body {
  display: flex;
  flex-direction: column;
}

header {
  flex: 0 0 auto;
  background-color: aqua;
}

main {
  flex: 1 0 auto;
  /* Enable flex grow */
  background-color: blanchedalmond;
}

footer {
  flex: 0 0 auto;
  background-color: brown;
}

div#this_should_fill_main {
  height: 100%;
  /*This doesn't work!*/
  background-color: cornflowerblue;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <header>This is a header</header>
  <main>
    <div id="this_should_fill_main">This is main content</div>
  </main>
  <footer>This is a footer</footer>
</body>

</html>

I tried to add height: 0 to <main>, but when the content is overflow, the footer will not be sticky.

I also tried other solutions mentioned in this queestion How can I make Flexbox children 100% height of their parent?, but make no sense for me.

  • add align-items: stretch to <main>; no change at all
  • add align-self: stretch to <div id="this_should_fill_main">; no change at all
  • use display: flex again in <div id="this_should_fill_main">; it works, but why doesn’t only height: 100% work?

Could you please help me to solve:

  1. Why height: 100% doesn’t work in this case?
  2. How to solve this without using flexbox again?

Thanks for all your answers!

2

Answers


  1. Add height: 0; or min-height: 0; to main, and it works.

    As for the reason why height: 100% doesn’t work, you can check this Github issue.

    (Code was updated for sticky footer)

    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    
    html,
    body {
      height: 100vh;
    }
    
    body {
      display: flex;
      flex-direction: column;
    }
    
    header {
      flex: 0 0 auto;
      background-color: aqua;
    }
    
    main {
      flex: 1 0 auto; /* Enable flex grow */
      height: 0;
      background-color: blanchedalmond;
    }
    
    footer {
      flex: 0 0 auto;
      background-color: brown;
    }
    
    div#this_should_fill_main {
      width: 100%;
      height: 100%; /*This doesn't work!*/
      background-color: cornflowerblue;
      overflow: scroll;
    }
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body>
        <header>This is a header</header>
        <main>
          <div id="this_should_fill_main">
            This is main content
            <!-- when the main content is larger than main -->
            <div style="height: 1000px"></div>
          </div>
        </main>
        <footer>This is a footer</footer>
      </body>
    </html>
    Login or Signup to reply.
  2. This issue you are facing is because of how flexbox is handling the height of items. When you set height: 100% to the div#this_should_fill_main, it will try to take the 100 percent of its parent which is main. But issue starts here because main does not have a defined height because in a flex container, height of the child elements is defined by their content, except you say otherwise.

    Another solution could be using properties of flexbox;

    • Add display: flex to main
    • You can also add flex-direction: column; to your main if you want your content to displayed vertically.
    • Add flex-grow: 1 to div#this_should_fill_main so that it takes all available place of parent
    main {
      flex: 1 0 auto;
      display: flex; /* Add this to make main flex container */
      flex-direction: column; /* If you want your content to ve displayed vertically */
      background-color: blanchedalmond;
    }
    
    div#this_should_fill_main {
      flex-grow: 1; /* This is for div to grow all available space*/
      background-color: cornflowerblue;
    }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search