42

My issue is probably best explained by example. This following jsfiddle will work in Chrome:

http://jsfiddle.net/ga6g4/

.lhs {
    position: absolute;
    top: 8px;
    left: 8px;
    width: 250px;
    height: 100px;
    border: 1px solid red;
    
    display: flex;
    flex-direction: column;
}

.panel-container {
    flex: 1;
    overflow: auto;
}
<div class="lhs">
    <header>Header</header>
    <div class="panel-container">
        <ul>
            <li>Item 1</li>
            <li>Item 2</li>
            <li>Item 3</li>
            <li>Item 4</li>
            <li>Item 5</li>
        </ul>
    </div>
</div>

As you can see, I've got a fixed-height flexbox with a fixed header and a scrollable body. So far so good. However, if you change the 'height' CSS of the '.lhs' container to max-height:

max-height: 100px;

.lhs {
    position: absolute;
    top: 8px;
    left: 8px;
    width: 250px;
    max-height: 100px;
    border: 1px solid red;
    
    display: flex;
    flex-direction: column;
}

.panel-container {
    flex: 1;
    overflow: auto;
}
<div class="lhs">
    <header>Header</header>
    <div class="panel-container">
        <ul>
            <li>Item 1</li>
            <li>Item 2</li>
            <li>Item 3</li>
            <li>Item 4</li>
            <li>Item 5</li>
        </ul>
    </div>
</div>

http://jsfiddle.net/ga6g4/1/

It breaks. It seems to now think that my list is now zero-height! Any idea why this is doing what it is doing, and how I can fix it?

EDIT: I wasn't descriptive enough in my original post in how I want this to behave. Basically the outer should use only the minimum height it requires, but only up to a maximum (defined by max-height). At this point, I want the content to begin scrolling.

Dai
  • 141,631
  • 28
  • 261
  • 374
Barguast
  • 5,926
  • 9
  • 43
  • 73
  • What is it you are actually trying to do? – Paulie_D Apr 07 '14 at 14:03
  • Basically I want the outer container to use as much height as it needs, but only up to a limit. You'll see the panel is floating 8px from the top-left, I also want to tell it to max-out 8px from the bottom and begin to scroll the content. To do this, I want to set max-height to the window height minus 16px. – Barguast Apr 07 '14 at 14:27

4 Answers4

43

OK, here's the solution I ended up with if anyone is interested:

http://jsfiddle.net/vN65r/

Basically, I had to apply the following to the fixed-height header:

flex: 0 0 auto;

And the following to the variable-height, scrolling body:

flex: 0 1 auto;

I hope it helps somebody

Barguast
  • 5,926
  • 9
  • 43
  • 73
7

Giving it both max-height:100px; and height:100%; should work. http://jsfiddle.net/ga6g4/2/

vaskort
  • 2,591
  • 2
  • 20
  • 29
  • 1
    Sorry, I should have been more descriptive. I want the outer
    to use as little space as possible and only be allowed to grow to a certain height (defined by max-height). See my comment above too. The solution you gave works, but it also forces the height to equal the maximum which I don't want. Thanks all the same.
    – Barguast Apr 07 '14 at 14:29
  • Allright no problems, will come again with an updated answer. – vaskort Apr 07 '14 at 14:39
  • Sorry, dont want to sound like pushing to my solution but if you experiment with height percentage and find the one that suits for you. Like height:10%; ? – vaskort Apr 07 '14 at 14:45
5

I think the answer is that you are using flex-direction:column.

Although it's still not entirely clear to me what you are trying to achieve switching to flex-direction:row seems to have the right effect.

JSfiddle Demo

CSS

.lhs {
    position: absolute;
    top: 8px;
    left: 8px;
    width: 250px;
    max-height: 100px;
    border: 1px solid red;
    display: flex;
    flex-direction: row;
}

.panel-container {
    flex: 1;
    overflow: auto;
}
Paulie_D
  • 107,962
  • 13
  • 142
  • 161
  • I added some clarification. I'm after a vertically-stacked flexbox which'll use as much space as it needs, but will also allow me to cap the height (using max-height). I've solved the issue in all browsers but IE10 so far (see my answer). I only need to add IE10 support. – Barguast Apr 08 '14 at 10:25
1

Barguast's answer is a good one. Here is a simplified version using Bootstrap:

<div class="h-50 border border-danger">
    <div class="d-flex flex-column h-100">
        <header>Header</header>
        <div class="flex-shrink-1" style="overflow-y: auto;">
            <ul>
                <li>Item</li>
                <li>Item</li>
                <li>Item</li>
                <li>Item</li>
                <li>Item</li>
                <li>Item</li>
                <li>Item</li>
                <li>Item</li>
                <li>Item</li>
                <li>Item</li>
                <li>Item</li>
                <li>Item</li>
                <li>Item</li>
                <li>Item</li>
                <li>Item</li>
            </ul>
        </div>
        <footer>Footer</footer>
    </div>
</div>

The trick to it is the flex-shrink-1, paired with overflow-y: auto.

ccleve
  • 15,239
  • 27
  • 91
  • 157