Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flex box fill parent, but don't stretch parent on overflow

Tags:

html

css

flexbox

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/

like image 456
Red Riding Hood Avatar asked Jan 29 '17 15:01

Red Riding Hood


People also ask

How do I make my flex elements not stretch?

By default, the child elements of a flexbox container will stretch vertically to fill the height of the container. This can be prevented by using the align-self property on the child element that you do not want to stretch.

Does overflow work with Flex?

The initial value of the flex-wrap property is nowrap . This means that if you have a set of flex items that are too wide for their container, they will overflow it.


1 Answers

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>
like image 169
Michael Benjamin Avatar answered Oct 26 '22 19:10

Michael Benjamin