Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should I specify height: 0 even if I specified flex-basis: 0 in CSS3 flexbox?

Tags:

html

css

flexbox

I'm trying to make a fixed-size content reader with a title. The title should be shown even if the content scrolls. In this situation, I tried to make a structure like this using CSS3 flexbox:

.flex {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 150px;
    border: 1px solid #ddd;
}

.title {
    height: 50px;
    line-height: 50px;
    background: #eee;
}

.text-wrap {
    flex: 1 0 0;
}

.text {
    height: 100%;
    overflow-y: auto;
}
<div class="flex">
    <div class="title">Title</div>
    <div class="text-wrap">
        <div class="text">
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas faucibus justo vitae urna lacinia pharetra. Quisque nulla lorem, laoreet quis dapibus nec, vehicula vitae lorem. Nunc fringilla justo vel metus rhoncus, at congue leo dictum. Morbi congue tortor lacinia, mollis sapien indsadsadf, rutrum purus. Nam ornare dapibus mi, vitae varius diam tincidunt id. Donec maximus sem nec luctus euismod. Morbi a volutpat diam. In sapien orci, auctor et facilisis eu, finibus ac mauris. Vivamus eu nunc porta, congue libero quis, rutrum nibh. Proin feugiat vel augue mattis cursus.</p>
        </div>
    </div>
</div>

so that the content gets the rest of the height no matter what the flex container's size is. However, as you can see, the content gets out of the container and the overflow-y property is not working.

However, if I specify the height to 0 in the text-wrap, I can see that my code is working, as the following:

.flex {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 150px;
    border: 1px solid #ddd;
}

.title {
    height: 50px;
    line-height: 50px;
    background: #eee;
}

.text-wrap {
    flex: 1 0 0;
    height: 0;
}

.text {
    height: 100%;
    overflow-y: auto;
}
<div class="flex">
    <div class="title">Title</div>
    <div class="text-wrap">
        <div class="text">
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas faucibus justo vitae urna lacinia pharetra. Quisque nulla lorem, laoreet quis dapibus nec, vehicula vitae lorem. Nunc fringilla justo vel metus rhoncus, at congue leo dictum. Morbi congue tortor lacinia, mollis sapien indsadsadf, rutrum purus. Nam ornare dapibus mi, vitae varius diam tincidunt id. Donec maximus sem nec luctus euismod. Morbi a volutpat diam. In sapien orci, auctor et facilisis eu, finibus ac mauris. Vivamus eu nunc porta, congue libero quis, rutrum nibh. Proin feugiat vel augue mattis cursus.</p>
        </div>
    </div>
</div>

I can't understand this behavior. I understand that flex-basis is a property which decides the initial height of the element (since the flex-direction is set to column), and that the flexbox divides the remaining heights to the elements according to the flex-grow property.

Then in this case, since the text-wrap's flex-basis(initial height) is set to 0 and it is the only element that has the property flex-grow, shouldn't the height be fixed to the rest of the flex container? Why is this behavior happening?

In addition, why should I specify the height: 0 property to the text-wrap in order to make my code work?

Thanks very much.

like image 491
Suhjin Park Avatar asked Feb 09 '17 07:02

Suhjin Park


People also ask

What is Flex-basis 0%?

Flex-basis overrules any specified CSS width value, so if you set flex-basis to 0, it doesn't fall back to the CSS "width" value.

Is Flex-basis width or height?

Flex-basis is both width and height in a Flexbox, depending on the flex direction.

How do you set the height of a flex item?

Instead of max-height: 250px you should use flex: 0 0 250px and with flex-direction: column it will set height of element to 250px.


1 Answers

Your code is correct and working properly.

There is just one more flexbox feature you need to factor in:

An initial setting on a flex container is min-height: auto. This means that, by default, a flex item cannot be shorter than its content. Once you override this setting, your layout works as expected.

You could use height: 0, but here's the standard method:

.text-wrap {
    flex: 1 0 0;
    min-height: 0; /* new */   
}

Full explanation here: Why doesn't flex item shrink past content size?

.flex {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 150px;
  border: 1px solid #ddd;
}
.title {
  height: 50px;
  line-height: 50px;
  background: #eee;
}
.text-wrap {
  flex: 1 0 0;
  min-height: 0; /* new */
}
.text {
  height: 100%;
  overflow-y: auto;
}
<div class="flex">
  <div class="title">Title</div>
  <div class="text-wrap">
    <div class="text">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas faucibus justo vitae urna lacinia pharetra. Quisque nulla lorem, laoreet quis dapibus nec, vehicula vitae lorem. Nunc fringilla justo vel metus rhoncus, at congue leo dictum. Morbi
        congue tortor lacinia, mollis sapien indsadsadf, rutrum purus. Nam ornare dapibus mi, vitae varius diam tincidunt id. Donec maximus sem nec luctus euismod. Morbi a volutpat diam. In sapien orci, auctor et facilisis eu, finibus ac mauris. Vivamus
        eu nunc porta, congue libero quis, rutrum nibh. Proin feugiat vel augue mattis cursus.</p>
    </div>
  </div>
</div>
like image 148
Michael Benjamin Avatar answered Sep 21 '22 02:09

Michael Benjamin