Home > front end >  Why does width % on flex-container shrink past its contents, but flex-basis does not?
Why does width % on flex-container shrink past its contents, but flex-basis does not?

Time:12-29

I have been playing around with the flex-box and have been trying to understand how it works. I have noticed that a % width for the flex-container will shrink past its contents, however if I swap width for flex-basis it overrides the percentage and stops it from shrinking past its contents. See the below example and replace 'width' with 'flex-basis':

    <!DOCTYPE html>
    <html>
    <head>
    <style>
    .flex-container {
      display: flex;
      background-color: DodgerBlue;
    }
    
    .flex-container > div {
      background-color: #f1f1f1;
      margin: 2px;
      padding: 2px;
      font-size: 30px;
      width: 20%;
    }
    </style>
    </head>
    <body>
    
    <h1>Create a Flex Container</h1>
    
    <div >
      <div>Item 1</div>
      <div>Item 2</div>
      <div>Item 3</div>  
    </div>
    
    <p>A Flexible Layout must have a parent element with the <em>display</em> property set to <em>flex</em>.</p>
    
    <p>Direct child elements(s) of the flexible container automatically becomes flexible items.</p>
    
    </body>
    </html>

As far as I am aware the min-width: auto property should kick in and prevent the flex-item from shrinking past its min-content however this only works for flex-basis and not the width even though min-width is supposed to override both. Could someone please explain what is going on here? Am I missing something?

CodePudding user response:

To understand this you need to consider two concepts: The "flex base size" and the "main size".

It's a bit tricky to explain but if you refer to the full algorithm in the specification You will notice that we first calculate the "flex base size" and later we calculate the "hypothetical main size" which is the final size.

For the "hypothetical main size":

The hypothetical main size is the item’s flex base size clamped according to its used min and max main sizes (and flooring the content box size at zero).

When you use width you are affecting the "main sizes" that is used to define the final width (the "hypothetical main size"). In other words, it's not only the min-width that is responsible of the non-shrinking effect but it's the "min max main sizes".

Here is another example to better understand:

.flex-container {
  display: flex;
  background-color: DodgerBlue;
}

.flex-container>div {
  background-color: #f1f1f1;
  margin: 2px;
  padding: 2px;
  font-size: 30px;
  flex-basis: 20%;
  width: 40px;
}
<div >
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
</div>

In the above, the items cannot shrink past 40px defined in the width.

If you don't define width,min-width and max-width, the browser will automatically define the "min max mains sizes" based on the content but if you give explicit values they will be considered in the algorithm.


It may sounds a bit strange but if you think about it's logical. flex-basis define "only" an initial size that can be affected by other factors to define the final one. When using width or height we are defining the sizes.

  • Related