How to prevent Firefox from expanding flex items when they contain a 100% max-width/height image? [duplicate]

I have two divs with a height of 90%, but the display is different.

I have tried to put an outer div around them, but that has not helped. Also, it's the same on Firefox, Chrome, Opera, & Safari.

Can someone explain why I am having this problem?

Below is my code:

<div style="height: 90%">
    <div ng-controller="TabsDataCtrl" style="width: 20%; float: left;">
        <tabset>
            <tab id="tab1" heading="{{tabs[0].title}}" ng-click="getContent(0)" active="tabs[0].active"
               disabled="tabs[0].disabled">
            </tab>


            <tab id="tab2" heading="{{tabs[2].title}}" ng-click="getContent(2)" active="tabs[2].active"
                 disabled="tabs[2].disabled">
            </tab>
        </tabset>
    </div>

    <div id="leaflet_map" ng-controller="iPortMapJobController">
        <leaflet center="center" markers="markers" layers="layers" width="78%"></leaflet>
    </div>
</div>

Solution 1:

Working with the CSS height property and percentage values

The CSS height property, when used with a percentage value, is calculated with respect to the element's containing block.

Let's say your body element has height: 1000px. Then a child with height: 90% would get 900px.

If you have not set an explicit height to the containing block (and the child is not absolutely positioned), then your child element with percentage height will have nothing to go on and height will be determined by content and other properties.

From the spec:

10.5 Content height: the height property

percentage
Specifies a percentage height. The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly and this element is not absolutely positioned, the value computes to 'auto'.

auto
The height depends on the values of other properties.

Hence, if you want to use percentage heights in your divs, specify the height of all parent elements, up to and including the root element (e.g., html, body {height:100%;})

Note that min-height and max-height are not acceptable. It must be the height property.

Here's a little summary:

John: I want to set the height of my div to 100%.
Jane: 100% of what?
John: 100% of its container. So, the parent one-level up.
Jane: Okay. And what's the height of the div's parent?
John: Doesn't have one. Auto, I guess. Content-driven.
Jane: So, you want the div to have a 100% height of an unknown variable?
John: [silence]
Jane: Hey John, can I have 50% of that?
John: 50% of what?
Jane: Exactly!
Jane: Percentages are relative values. You always have to ask "percentage of what?". By declaring an explicit height for each parent all the way up to body and html you establish a frame of reference for each child with percentage height, enabling the height to work.

Examples

Let's say you want a div to have 50% height of its parent.

This won't work:

<article>
    <section>
        <div style="height:50%"></div>
    </section>
</article>

Neither will this:

<article>
    <section style="height:100%">
        <div style="height:50%"></div>
    </section>
</article>

And neither will this:

<article style="height:100%">
    <section style="height:100%">
        <div style="height:50%"></div>
    </section>
</article>

This will fail, too:

<body style="height:100%">
    <article style="height:100%">
        <section style="height:100%">
            <div style="height:50%"></div>
        </section>
    </article>
</body>

NOW, it will finally work:

<html style="height:100%">
    <body style="height:100%">
        <article style="height:100%">
            <section style="height:100%">
                <div style="height:50%"></div>
            </section>
        </article>
    </body>
 </html>

And this would work, as well:

<article>
    <section style="height: 500px">
        <div style="height:50%"></div>
    </section>
</article>

But not this:

<article>
    <section style="min-height: 500px">
        <div style="height:50%"></div>
    </section>
</article>

sample code


Use 100vh

As you can see, percentage heights are a bit tricky. You can avoid the complexity (i.e., never have to consider parent elements) by simply using viewport percentage heights. Whenever you want a box to be the height of the viewport, use height: 100vh instead of height: 100%. Nothing else is needed.

Absolute Positioning Exception

As noted in the spec, an absolutely positioned element is an exception to the rule for percentage heights. More details here: Applying 100% height to nested, non-flex elements.

Solution 2:

Use vh (viewport height) instead of percentage. It will get the height of the browser and size it accordingly, e.g.

height:90vh;

try this code

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<div id ="wrapper">
    <div id="tabs" ng-controller="TabsDataCtrl">
        <tabset>
            <tab id="tab1" heading="{{tabs[0].title}}" ng-click="getContent(0)" active="tabs[0].active"
               disabled="tabs[0].disabled">
            </tab>


            <tab id="tab2" heading="{{tabs[2].title}}" ng-click="getContent(2)" active="tabs[2].active"
                 disabled="tabs[2].disabled">
            </tab>
        </tabset>
    </div>

    <div id="leaflet_map" ng-controller="iPortMapJobController">
        <leaflet center="center" markers="markers" layers="layers"></leaflet>
    </div>
    </div>
</body>
</html>

with css

<style>
    #wrapper{height:60vh;}
    #tabs {width:20% float:left; height:60vh; overflow-y:scroll; overflow-x:hidden;}
    #leaflet-map{width:78%; height:60vh; overflow-y:scroll;  overflow-x:hidden;}
</style>