0

Dear close-voters, please read the question before assuming it's a duplicate. It is not the same as the one you linked to.

I am not asking how to expand a flex-item to fill a flex container. I am asking how to expand a block element to fill a flex-item.


I am using flexbox for a typical 'sticky footer' layout (header, content, footer) where the content region expands so the footer is always stuck to the bottom. Try running this code snippet:

html,
body {
  margin: 0;
}

.layout {
  background: pink;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

header {
  background: red;
  height: 40px;
}

main {
  background: blue;
  flex: 1;
  position: relative;
}

  .content {
    background: yellow;
    height: 100%;
  }

footer {
  min-height: 60px;
  background: pink;
}
<!doctype html>
<html>
<body>
  <div class="layout">
    <header>
      HEADER
    </header>
    
    <main>
      <div class="content">
        CONTENT
      </div>
    </main>
    
    <footer>
      FOOTER
    </footer>
  </div>
</body>
</html>

The blue area (main) is a flex item with flex: 1, and it correctly expands to ensure the footer stays at the bottom of the viewport.

I want the nested yellow block div (.content) to fill 100% of the height of its parent - so there should be no blue visible in the final result, as it should all be obscured by yellow.

What am I doing wrong here?

callum
  • 34,206
  • 35
  • 106
  • 163

2 Answers2

0

Percentage-based heights need a point of reference. main has no defined height, and the height of your .layout is also not defined. (min-height does not count).

Change min-height: 100vh to height: 100vh on your .layout, and add height: 100% to main.

html,
body {
  margin: 0;
}

.layout {
  background: pink;
  display: flex;
  flex-direction: column;
  height: 100vh;
}

header {
  background: red;
  height: 40px;
}

main {
  background: blue;
  flex: 1;
  position: relative;
  height: 100%;
}

.content {
  background: yellow;
  height: 100%;
}

footer {
  min-height: 60px;
  background: pink;
}
<!doctype html>
<html>

<body>
  <div class="layout">
    <header>
      HEADER
    </header>

    <main>
      <div class="content">
        CONTENT
      </div>
    </main>

    <footer>
      FOOTER
    </footer>
  </div>
</body>

</html>
Liftoff
  • 24,717
  • 13
  • 66
  • 119
  • 1
    Realized your `.layout` was using `min-height` instead of `height`, which is not enough for percentage calculations to work. You need to define `height` instead. Updated my answer. – Liftoff Jun 11 '23 at 10:54
0
  1. .main { display: flex; flex-direction: column; } + .content { flex: 1 }
  2. or just .main { display: grid; }

html,
body {
  margin: 0;
}

.layout {
  background: pink;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

header {
  background: red;
  height: 40px;
}

main {
  background: blue;
  flex: 1;
  position: relative;
  /*  */
  display: flex;
  flex-direction: column;
  /* or */
  /* display: grid; */
}

.content {
  background: yellow;
  flex: 1; /*  */
  /* not need */
  /* height: 100%; */
}

footer {
  min-height: 60px;
  background: pink;
}
<!doctype html>
<html>
<body>
  <div class="layout">
    <header>
      HEADER
    </header>
    
    <main>
      <div class="content">
        CONTENT
      </div>
    </main>
    
    <footer>
      FOOTER
    </footer>
  </div>
</body>
</html>
imhvost
  • 4,750
  • 2
  • 8
  • 10
  • Thanks, but I asked how to make a **block** element fill a flex-item. I need it to be a block. I do not want `main` to become a flex container. – callum Jun 11 '23 at 12:20
  • In my example, `.content` has `display:block;` because there is no `display:flex-item;` or `display:grid-item;`. Please ask the question more correctly next time so that people don't waste their time on your nonsense. I'll just give you another option. But you will probably say again that `.layout` should be exclusively `display: flex;` without explaining why )) [codepen](https://codepen.io/imhvost/pen/ZEmbbVR) – imhvost Jun 12 '23 at 20:47