Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why don't flex items shrink past content size?

Tags:

html

css

flexbox

I have 4 flexbox columns and everything works fine, but when I add some text to a column and set it to a big font size, it is making the column wider than it should be due to the flex property.

I tried to use word-break: break-word and it helped, but still when I resize the column to a very small width, letters in the text are broken into multiple lines (one letter per line), and yet the column does not get smaller width than one letter size.

Watch this video (at the start, the first column is the smallest, but when I resized the window, it is the widest column. I just want to respect flex settings always; flex sizes 1 : 3 : 4 : 4)

I know, setting font-size and column padding to smaller will help... but is there any other solution?

I can not use overflow-x: hidden.

JSFiddle

.container {    display: flex;    width: 100%  }  .col {    min-height: 200px;    padding: 30px;    word-break: break-word  }  .col1 {    flex: 1;    background: orange;    font-size: 80px  }  .col2 {    flex: 3;    background: yellow  }  .col3 {    flex: 4;    background: skyblue  }  .col4 {    flex: 4;    background: red  }
<div class="container">    <div class="col col1">Lorem ipsum dolor</div>    <div class="col col2">Lorem ipsum dolor</div>    <div class="col col3">Lorem ipsum dolor</div>    <div class="col col4">Lorem ipsum dolor</div>  </div>
like image 225
tomas657 Avatar asked Mar 27 '16 12:03

tomas657


People also ask

Why are my flex items overflowing?

The initial value of the flex-wrap property is nowrap . This means that if you have a set of flex items that are too wide for their container, they will overflow it.

How do I make my flex object smaller?

With flex-shrink set to 0 the items are not allowed to shrink and so they overflow the box. Change the flex-shrink value to 1 and you will see each item shrink by the same amount, in order that all of the items now fit in the box. They have become smaller than their initial width in order to do so.

Does Flex shrink?

The element will not shrink: it will retain the width it needs, and not wrap its content. Its siblings will shrink to give space to the target element. Because the target element will not wrap its content, there is a chance for the flexbox container's content to overflow.


2 Answers

The Automatic Minimum Size of Flex Items

You're encountering a flexbox default setting.

A flex item cannot be smaller than the size of its content along the main axis.

The defaults are...

  • min-width: auto
  • min-height: auto

...for flex items in row-direction and column-direction, respectively.

You can override these defaults by setting flex items to:

  • min-width: 0
  • min-height: 0
  • overflow: hidden (or any other value, except visible)

Flexbox Specification

4.5. Automatic Minimum Size of Flex Items

To provide a more reasonable default minimum size for flex items, this specification introduces a new auto value as the initial value of the min-width and min-height properties defined in CSS 2.1.

With regard to the auto value...

On a flex item whose overflow is visible in the main axis, when specified on the flex item’s main-axis min-size property, specifies an automatic minimum size. It otherwise computes to 0.

In other words:

  • The min-width: auto and min-height: auto defaults apply only when overflow is visible.
  • If the overflow value is not visible, the value of the min-size property is 0.
  • Hence, overflow: hidden can be a substitute for min-width: 0 and min-height: 0.

and...

  • The minimum sizing algorithm applies only on the main axis.
  • For example, a flex item in a row-direction container does not get min-height: auto by default.
  • For a more detailed explanation see this post:
    • min-width rendering differently in flex-direction: row and flex-direction: column

You've applied min-width: 0 and the item still doesn't shrink?

Nested Flex Containers

If you're dealing with flex items on multiple levels of the HTML structure, it may be necessary to override the default min-width: auto / min-height: auto on items at higher levels.

Basically, a higher level flex item with min-width: auto can prevent shrinking on items nested below with min-width: 0.

Examples:

  • Flex item is not shrinking smaller than its content
  • Fitting child into parent
  • white-space css property is creating issues with flex

Browser Rendering Notes

  • Chrome vs. Firefox / Edge

    Since at least 2017, it appears that Chrome is either (1) reverting back to the min-width: 0 / min-height: 0 defaults, or (2) automatically applying the 0 defaults in certain situations based on a mystery algorithm. (This could be what they call an intervention.) As a result, many people are seeing their layout (especially desired scrollbars) work as expected in Chrome, but not in Firefox / Edge. This issue is covered in more detail here: flex-shrink discrepancy between Firefox and Chrome

  • IE11

    As noted in the spec, the auto value for the min-width and min-height properties is "new". This means that some browsers may still render a 0 value by default, because they implemented flex layout before the value was updated and because 0 is the initial value for min-width and min-height in CSS 2.1. One such browser is IE11. Other browsers have updated to the newer auto value as defined in the flexbox spec.


Revised Demo

.container {    display: flex;  }    .col {    min-height: 200px;    padding: 30px;    word-break: break-word  }    .col1 {    flex: 1;    background: orange;    font-size: 80px;    min-width: 0;   /* NEW */  }    .col2 {    flex: 3;    background: yellow  }    .col3 {    flex: 4;    background: skyblue  }    .col4 {    flex: 4;    background: red  }
<div class="container">    <div class="col col1">Lorem ipsum dolor</div>    <div class="col col2">Lorem ipsum dolor</div>    <div class="col col3">Lorem ipsum dolor</div>    <div class="col col4">Lorem ipsum dolor</div>  </div>

jsFiddle

like image 144
Michael Benjamin Avatar answered Sep 22 '22 03:09

Michael Benjamin


I'm finding this has bitten me repeatedly over the years for both flex and grid, so I'm going to suggest the following:

* { min-width: 0; min-height: 0; } 

and then just use min-width: auto or min-height: auto if you need that behaviour.

In fact, throw in box-sizing as well to make all layout more sane:

* { box-sizing: border-box; min-width: 0; min-height: 0; } 

Does anyone know if there are any odd consequences? I've not encountered anything in several years of using a mix of the above. In fact, I can't think of any cases where I'd want to layout from content outwards to the flex/grid, rather than flex/grid inwards to the content --- and surely if they exist, they're rare. So this feels like a bad default. But maybe I'm missing something?

like image 39
voracity Avatar answered Sep 20 '22 03:09

voracity