46

Is there a difference between setting max-width or width to a flex item instead of the flex-basis?

Is it the "breaking point" for the flex-grow/shrink properties?

And when I set flex-wrap: wrap how does the browser decides at which point to move down item to new line? Is it according to their width or 'flex-basis'?

Example: http://jsfiddle.net/wP5UP/ The last two boxes have the same flex-basis: 200px, yet only one of them moves down when the window is between 300px and 400px. Why?

ilyo
  • 35,851
  • 46
  • 106
  • 159

2 Answers2

44

flex-basis allows you to specify the initial/starting size of the element, before anything else is computed. It can either be a percentage or an absolute value.

It is, however, not the breaking point for flex-grow/shrink properties. The browser determines when to wrap the element on the basis of if the initial sizes of elements exceed the width of the cross-axis (in conventional sense, that is the width).

Based on your fiddle, the reason why the last one moves down the window is because the width of the parent has been fully occupied by the previous siblings — and when you allow content to wrap, the elements that fail to fit in the first row gets pushed to the subsequent row. Since flex-grow is a non-zero value, it will simply stretch to fill all spaces left in the second row.

See demo fiddle (modified from yours).

If you look at the fiddle, I have modified for the last item to have a new size declaration:

.size3 {
  flex: 0 1 300px;
}

You will realize that the element measures 300px across as intended. However, when you tweak the flex-grow property such that its value exceeds 0 (see example), it will stretch to fill the row, which is the expected behavior. Since in its new row context it has no siblings to compare to, an integer between 1 to infinity will not influence it's size.

Therefore, flex-grow can be seen as this:

  • 0: (Default value) Do not stretch. Either size to element's content width, or obey flex-basis.
  • 1: Stretch.
  • ≥2 (integer n): Stretch. Will be n times the size of other elements with flex-grow: 1 on the same row, for example.
Terry
  • 63,248
  • 15
  • 96
  • 118
  • And what happens with 'flex-shrink'? What is the breakpoint for it to kick in? – ilyo May 09 '14 at 16:55
  • 2
    `flex-shrink` works similarly to `flex-grow`: it dictates how much the element should shrink when the sum of initial/original widths on the same row exceeds the available space along the cross axis. Setting it to `0` prevents collapsing beyond their minimum widths (usually restricted by content in each element), while dimensionless integer values allows collapsing: `1` will enable collapsing, and `n` allows you to set ratios on how far each element collapses relative to `1`. – Terry May 09 '14 at 17:20
  • I just checked and `flex-basis` can not take dimensionless integers only `px/pt` etc. So I still don't understand what is the difference between it and `width` – ilyo May 09 '14 at 17:53
  • @ilyo Sorry, I got it mixed up with flex-grow/shrink. `flex-basis` establishes the base width of the element prior to redistributing remaining space along the cross-axis, either by justify-content or flex-grow/shrink values. – Terry May 09 '14 at 19:03
  • 1
    @Terry (In conventional sense) Main-axis = width, Cross-axis = vertical. – Vennsoh Oct 01 '14 at 22:21
  • 1
    @Terry @Vennsoh what happens when an element has conflicting `width` and `flex-basis` values? Does one of them affect the other, or is one ignored? Which one? – tomekwi Jun 27 '15 at 19:58
  • @tomekwi I think it's a mix of both. For example, if you set with the 100% with a flex-basis of auto, then all elements will have identical widths. But the best way to test is to create an example and play around with the values yourself. – Terry Jun 27 '15 at 20:00
  • Lets say you have `flex-wrap: wrap` and a few items with a nonzero flex-shrink. If the items are too big to fit on one line, do they shrink to fit on the line, or do they wrap onto a new line? – Kevin Wheeler Feb 18 '16 at 00:54
  • 4
    @tomekwi When you set conflicting `width` and `flex-basis`, `flex-basis` is used. Actually, the only time `width` is used is when `flex-basis` is set to `auto`, which is **default**. Set it to whatever and it will apply. Also notice that if `min-width` and `max-width` are respected, and the siblings on the same row account for it, but it sometimes might look like `flex-shrink|grow" do not apply correctly. – tao Mar 03 '16 at 23:58
  • @Terry 0 is the default for `flex-grow`, not 1. Also, *Will be n times the size of other elements with flex-grow: 1* is incorrect. See: https://medium.freecodecamp.org/even-more-about-how-flexbox-works-explained-in-big-colorful-animated-gifs-a5a74812b053 – Hans Oct 15 '17 at 23:03
  • @Hans Thanks for the correcting. However, for the second statement, it still stands correct. Flex grow is a relative measure, so an element with flex grow of 2 will have twice the amount of growable width compared to its siblings with 1. – Terry Oct 16 '17 at 06:59
  • @Terry It is the rate of growth that the factor applies to, not the size. Your statement of relative size does not hold when an item has non-zero width/flex-basis because the item's final size is its width/flex-basis *plus* factor of growth per flex-grow. `flex-basis:auto` has special behavior as well that contradicts your statement. See: https://www.w3.org/TR/css-flexbox-1/images/rel-vs-abs-flex.svg – Hans Oct 16 '17 at 08:49
4

Good article https://gedd.ski/post/the-difference-between-width-and-flex-basis/

flex-basis is: the size of flex items before they are placed into a flex container. It's the ideal or hypothetical size of the items. But flex-basis is not a guaranteed size! As soon as the browser places the items into their flex container, things change. Often times the flex container won't have enough space, or will have extra space, after all its items' flex-basis values are added up.

zloctb
  • 10,592
  • 8
  • 70
  • 89