8

This is a similar question to Can you make a flexbox child expand to fit parent but not contents?, however, that solution doesn't work for me.

I have a layout such that the whole page should always fit on screen (between header and footer), and if contents is too large, then its container should scroll. (Basically the last example from: https://css-tricks.com/snippets/css/a-guide-to-flexbox/)

I already tried the solution from the question I linked above:

#chat {
    background-color: #ceecf5;
    flex-grow: 1;
    overflow: auto;
}

But the parent is still being stretched off the page.

If I set a manual height to #chat it works correctly, but then it only fits correctly for the screen size I made it on, so I want an automatic height.

#flex-container {
  display: flex;
  flex-flow: column nowrap;
  justify-content: flex-start;
  min-width: 300px;
  flex: 1;
}
#header {
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: red;
}
#column-flex-container {
  display: flex;
  flex-flow: row wrap-reverse;
  justify-content: space-between;
  flex: 1 1 auto;
  align-items: stretch;
}
.column {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  width: 300px;
  overflow: auto;
  background-color: aqua;
}
#chat {
  background-color: #ceecf5;
  flex-grow: 1;
  overflow: auto;
}
#main-column {
  flex: 1 1 auto;
  background-color: azure;
}
#footer {
  height: 50px;
  background-color: red;
}
html,
body {
  margin: 0;
  display: flex;
  min-height: 100vh;
  flex-direction: column;
}
<div id="flex-container">
  <div id="header"></div>
  <div id="column-flex-container">
    <div class="column side-column">
      <div id="chat">
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
      </div>
    </div>
    <div id="main-column" class="column"></div>
    <div class="column side-column"></div>
  </div>
</div>
<div id="footer" />

https://jsfiddle.net/dmn3gLz4/

Community
  • 1
  • 1
Red Riding Hood
  • 1,932
  • 1
  • 17
  • 36

1 Answers1

6

A few problem items to consider:

min-height: 100vh

You wrote:

I have a layout such that the whole page should always fit on screen (between header and footer), and if contents is too large, then its container should scroll.

Then you shouldn't set the height on the body element to min-height: 100vh.

With min-height you're allowing the element to expand from that point on. Use height: 100vh.

html,
body {
  margin: 0;
  display: flex;
  /* min-height: 100vh; */
  flex-direction: column;
  height: 100vh; /* establish fixed height */
}

flex-flow: row wrap-reverse

If you're trying to build a three-column layout, there's no need for horizontal wrapping.

To reverse the order of the columns, use row-reverse not wrap-reverse.

#column-flex-container {
  display: flex;
  /* flex-flow: row wrap-reverse; */
  justify-content: space-between;
  flex: 1 1 auto;
  align-items: stretch;
  flex-flow: row-reverse nowrap; /* OR, just...
  flex-direction: row-reverse; */
}

flex-shrink: 1

Your header and footer each have height: 50px. But because they are flex items, and flex items can shrink by default (flex-shrink: 1), the header and footer are shrinking. To keep the 50px heights, disable shrink (flex-shrink: 0, or just use flex: 0 0 50px). More details...


syntax error

You have an errant closing div. Consider removing it.

        <div id="main-column" class="column"></div>
        <div class="column side-column"></div>
    </div>
<!-- </div> -->  <-- STRAY CLOSING TAG
<div id="footer"></div>

revised fiddle

#flex-container {
  display: flex;
  flex-flow: column nowrap;
  justify-content: flex-start;
  min-width: 300px;
  flex: 1;
}
#header {
  /* height: 50px; */
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: red;
  flex: 0 0 50px; /* new */
}
#column-flex-container {
  display: flex;
  /* flex-flow: row wrap-reverse; */
  justify-content: space-between;
  flex: 1 1 auto;
  align-items: stretch;
  flex-direction: row-reverse;
}
.column {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  width: 300px;
  overflow: auto;
  background-color: aqua;
}
#chat {
  background-color: #ceecf5;
  flex-grow: 1;
  overflow: auto;
}
#main-column {
  flex: 1 1 auto;
  background-color: azure;
}
#footer {
  height: 50px;
  background-color: red;
  flex-shrink: 0; /* new */
}
html,
body {
  margin: 0;
  display: flex;
  height: 100vh; /* adjusted */
  flex-direction: column;
}
<div id="flex-container">
  <div id="header"></div>
  <div id="column-flex-container">
    <div class="column side-column">
      <div id="chat">
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
        <div class="message">Sender: Message</div>
      </div>
    </div>
    <div id="main-column" class="column"></div>
    <div class="column side-column"></div>
  </div>
  <!-- </div> -->
  <div id="footer"></div>
Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701