Creating a CSS Fill Utility for Flex Items?

66 views Asked by At

I'm reviewing SUITCSS's design of a fill utility:

.u-sizeFill {
  flex: 1 1 0% !important; /* 1 */
  flex-basis: 0% !important; /* 2 */
}

This would be applied to flex that where we want them to fill up the remaining space.

Just want to see whether I'm interpreting this right. The basis is 0%, so the item can have 0 width by default? The flex grow and flex shrink are both 1 so, it will grow and shrink at the same rate. Is this interpretation correct?

.u-sizeFill {
  flex: 1 1 0% !important; /* 1 */
  flex-basis: 0% !important; /* 2 */
}
<div style="display: flex; background-color: yellow; width: 5rem; height: 3rem">
      <div style="min-width: 0" class="u-sizeFill">
        Lorem ipsum dolor sit amet, probo option similique vix te, ei summo
        aliquip nec. Atqui diceret ceteros.
      </div>
</div>

1

There are 1 answers

1
Temani Afif On BEST ANSWER

I can see two different situations in order to understand the use case of this class. Either this class is applied to all the elements or to only one element.

First we should notice that flex-shrink:1 is the default value so we are only setting flex-grow:1 and flex-basis:0%


When applied to all the elements

In such situation this class will allow us to distribute all the space equally without considering the content of the different elements. It will not only distribute the free space.

Here is a basic example:

.box {
  display:flex;
  border:1px solid;
  margin:5px;
}
.box > span {
  flex:1 1 0%;
  background:yellow;
  outline:1px solid #000;
}
<div class="box">
  <span>text</span>
  <span>more text</span>
  <span>another long text here</span>
</div>

<div class="box">
  <span>A</span>
  <span>more text here</span>
  <span>another loooong text here</span>
</div>

Notice how in the below code our 3 elements have equal size even if the content will change. We created a 3 column layout.

Now, let's remove flex-basis:0% and keep only flex-grow:1

.box {
  display:flex;
  border:1px solid;
  margin:5px;
}
.box > span {
  flex-grow:1;
  background:yellow;
  outline:1px solid #000;
}
<div class="box">
  <span>text</span>
  <span>more text</span>
  <span>another long text here</span>
</div>

<div class="box">
  <span>A</span>
  <span>more text here</span>
  <span>another loooong text here</span>
</div>

We no more have equal elements and the width will change depending on the content because we are distrbuting the free space!

Here is from the specification an illustration that will make you better understand:

enter image description here

A diagram showing the difference between "absolute" flex (starting from a basis of zero) and "relative" flex (starting from a basis of the item’s content size). The three items have flex factors of 1, 1, and 2, respectively: notice that the item with a flex factor of 2 grows twice as fast as the others.


When applied to one the element

In this case, we will ensure that this element will not affect the other elements when added to the layout as it will simply take the remaining space if any. In other words, its content will not get considering in the space distribution.

Here is an example:

.box {
 margin:5px;
 border:1px solid;
 display:flex;
}
.box > span:not(.extra) {
  width:40%;
  background:yellow;
  outline:1px solid;
  min-height:30px;
}
.extra {
  flex:1 1 0%;
  background:green;
}
<div class="box">
  <span></span>
  <span></span>
  <span class="extra">I am extra</span>
</div>
<div class="box">
  <span></span>
  <span></span>
  <span class="extra">I am extra element with long text</span>
</div>
<div class="box">
  <span></span>
  <span></span>
  <span class="extra">..</span>
</div>
<div class="box">
  <span></span>
  <span></span>
</div>

As you can see, in all the cases the extra element will simply take the 20% remaining space without affecting the layout.

Now remove the flex-basis and you will see a different behavior:

.box {
 margin:5px;
 border:1px solid;
 display:flex;
}
.box > span:not(.extra) {
  width:40%;
  background:yellow;
  outline:1px solid;
  min-height:30px;
}
.extra {
  flex-grow:1;
  background:green;
}
<div class="box">
  <span></span>
  <span></span>
  <span class="extra">I am extra</span>
</div>
<div class="box">
  <span></span>
  <span></span>
  <span class="extra">I am extra element with long text</span>
</div>
<div class="box">
  <span></span>
  <span></span>
  <span class="extra">..</span>
</div>
<div class="box">
  <span></span>
  <span></span>
</div>

As you can see in the second situation, our elements will shrink breaking the initial layout which may not be an intended result.