Barguast
Barguast

Reputation: 6186

flexbox misbehaving with max-height

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.

Upvotes: 43

Views: 108046

Answers (4)

ccleve
ccleve

Reputation: 15799

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.

Upvotes: 2

Barguast
Barguast

Reputation: 6186

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

Upvotes: 48

Paulie_D
Paulie_D

Reputation: 115066

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;
}

Upvotes: 5

vaskort
vaskort

Reputation: 2861

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

Upvotes: 7

Related Questions