Jessica
Jessica

Reputation: 9830

Div's height becomes 0 when I set a percentage

I have li's with the flexlayout. There are 3 li's in every column. (flex-basis is set to a third.) In the li I have a div for a background image, and another div to display text. I want the text to be below the image. The image should take up a majority of the room.

For some reason the image isn't there. I set the image height to 80%, but when I run it and go to "inspect element" (in chrome), the div's height is 0. When I set it to an amount with pixels, (not percentage), then it works.

My question is, how can I set the div to a percentage and still have it shown?

JSFiddle

html, body {
    margin: 0;
    height: 100%;
}
div {
    align-items: center;
    justify-content: center;
    height: 100%;
    display: flex;
    overflow: auto;
    background-color:aqua;
}
ul {
    margin-top: auto;
    margin-bottom: auto;
    height: calc(70% + 0px);
    padding: 0;
    display: inline-flex;
    flex-wrap: wrap;
    flex-direction: column;
    width: 100%;
    align-content: flex-start;
}
li {
    flex-basis: calc(100% / 3 - 2px);
    /* Subtract the border */
    color: firebrick;
    border: 1px solid firebrick;
    background-color: greenYellow;
    margin: 0px;
    list-style-type: none;
    box-sizing: border-box;
    background-size: contain;
    width: 200px;
}
.image {
    background-image: url("http://i.imgur.com/nswXRR4.jpg");
    background-size: contain;
    background-position: 50%, 50%;
    background-repeat: no-repeat;
    margin: 5px;
    height: 90%;
}
<div>
    <ul>
        <li>
            <div class="image"></div>
            <div class="num">1</div>
        </li>
        <li>
            <div class="image"></div>
            <div class="num">2</div>
        </li>
        <li>
            <div class="image"></div>
            <div class="num">3</div>
        </li>
        <li>
            <div class="image"></div>
            <div class="num">4</div>
        </li>
    </ul>
</div>

Upvotes: 1

Views: 93

Answers (2)

Michael Benjamin
Michael Benjamin

Reputation: 371261

Although the li has a height defined by flex-basis: calc(100% / 3 - 2px);, when dealing with percentages, browsers normally interpret the spec to mean height as defined by the height property.

In my experience, min-height, max-height and flex-basis have never worked as a height for a parent element when dealing with percentage heights. Only height works, even though it doesn't explicitly say this must be the way in the spec. (Update: Firefox may be broadening its interpretation.)

You can make this adjustment:

Instead of: flex-basis: calc(100% / 3 - 2px);

Use: height: calc(100%/3 - 2px);

HOWEVER...

Based on what you wrote:

In the li I have a div for a background image, and another div to display text. I want the text to be below the image. The image should take up a majority of the room.

... this doesn't have to be an issue about percentage heights. You can leave the flex-basis on the li, make the li a flex container, and then apply flex properties to the image and text.

Make this adjustment to the li:

li {
    flex-basis: calc(100% / 3 - 2px);
    /* Subtract the border */
    color: firebrick;
    border: 1px solid firebrick;
    background-color: greenYellow;
    margin: 0px;
    list-style-type: none;
    box-sizing: border-box;
    background-size: contain;
    width: 200px;

    display: flex; /* new */
    flex-direction: column; /* new */
}

Then adjust the image and text:

.image {
    background-image: url("http://i.imgur.com/nswXRR4.jpg");
    background-size: contain;
    background-position: 50%, 50%;
    background-repeat: no-repeat;
    margin: 5px;
    /* height: 90%; remove */
    flex: 10 1 auto; /* new */
}

.num {
    flex: 1 1 auto;
}

DEMO

NOTE: flex: 10 1 auto; means flex-grow: 10, flex-shrink: 1, flex-basis: auto. In other words, the flex item can consume up to 10x more available space than siblings with flex-grow: 1, shrink evenly in proportion with siblings having flex-shrink: 1, and its initial main size is based on content size.

Upvotes: 1

Adam Jenkins
Adam Jenkins

Reputation: 55623

Your li doesn't have a defined height property. Your .image div is then trying to become 90% of undefined. You can guess what that is: 0.

Depending on what you want, you can set your li to be display:flex and then allow your .image div to grow more than your .num div as below.

There are more ways to modify the flex: 10 1 0 or flex: 1 0 0 properties, to get exactly what you are looking for, but the below code is an example:

html, body {
    margin: 0;
    height: 100%;
}
div {
    align-items: center;
    justify-content: center;
    height: 100%;
    display: flex;
    overflow: auto;
    background-color:aqua;
}
ul {
    margin-top: auto;
    margin-bottom: auto;
    height: calc(70% + 0px);
    padding: 0;
    display: inline-flex;
    flex-wrap: wrap;
    flex-direction: column;
    width: 100%;
    align-content: flex-start;
}
li {
    flex-basis: calc(100% / 3 - 2px);
    /* Subtract the border */
    color: firebrick;
    border: 1px solid firebrick;
    background-color: greenYellow;
    margin: 0px;
    list-style-type: none;
    box-sizing: border-box;
    background-size: contain;
    width: 200px;
    display:flex;
  flex-direction:column;
}

.image {
     flex: 10 1 0; 
 }

.num {
  flex: 1 0 0;
}

.image {
    background-image: url("http://i.imgur.com/nswXRR4.jpg");
    background-size: contain;
    background-position: 50%, 50%;
    background-repeat: no-repeat;
    margin: 5px;
    height: 90%;
}
<div>
    <ul>
        <li>
            <div class="image"></div>
            <div class="num">1</div>
        </li>
        <li>
            <div class="image"></div>
            <div class="num">2</div>
        </li>
        <li>
            <div class="image"></div>
            <div class="num">3</div>
        </li>
        <li>
            <div class="image"></div>
            <div class="num">4</div>
        </li>
    </ul>
</div>

Upvotes: 1

Related Questions