width vs. flex-basis: [width] - elements get expanded? [duplicate] - css

There have been questions and articles about this, but nothing conclusive as far as I can tell. The best summary I could find is
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.
...which in itself doesn't say much about the behavior of elements with flex-basis set. With my current knowledge of flexbox I don't see why that couldn't describe width also.
I'd like to know how exactly flex-basis is different from width in practice:
If I replace width with flex-basis(and vice versa), what will change visually?
What happens if I set both to a different value? What happens if they have the same value?
Are there some special cases where using either width or flex-basis would have a significant difference to using the other?
How do width and flex-basis differ when used in conjunction with other flexbox styles, such as flex-wrap, flex-grow and flex-shrink?
Any other significant differences?
Edit/clarification: This question has been asked in a different format in What exactly flex-basis property sets? but I felt a more direct comparison or summary of the differences of flex-basis and width (or height) would be nice.

Consider flex-direction
The first thing that comes to mind when reading your question is that flex-basis doesn't always apply to width.
When flex-direction is row, flex-basis controls width.
But when flex-direction is column, flex-basis controls height.
Key Differences
Here are some important differences between flex-basis and width / height:
flex-basis applies only to flex items. Flex containers (that aren't also flex items) will ignore flex-basis but can use width and height.
flex-basis works only on the main axis. For example, if you're in flex-direction: column, the width property would be needed for sizing flex items horizontally.
flex-basis has no effect on absolutely-positioned flex items. width and height properties would be necessary. Absolutely-positioned flex items do not participate in flex layout.
By using the flex property, three properties – flex-grow, flex-shrink and flex-basis – can be neatly combined into one declaration. Using width, the same rule would require multiple lines of code.
Browser Behavior
In terms of how they are rendered, there should be no difference between flex-basis and width, unless flex-basis is auto or content.
From the spec:
7.2.3. The flex-basis property
For all values other than auto and content, flex-basis is resolved the same way as width in horizontal writing modes.
But the impact of auto or content may be minimal or nothing at all. More from the spec:
auto
When specified on a flex item, the auto keyword retrieves the value
of the main size property as the used flex-basis. If that value is
itself auto, then the used value is content.
content
Indicates automatic sizing, based on the flex item’s content.
Note: This value was not present in the initial release of Flexible
Box Layout, and thus some older implementations will not support it.
The equivalent effect can be achieved by using auto together with a
main size (width or height) of auto.
So, according to the spec, flex-basis and width resolve identically, unless flex-basis is auto or content. In such cases, flex-basis may use content width (which, presumably, the width property would use, as well).
The flex-shrink factor
It's important to remember the initial settings of a flex container. Some of these settings include:
flex-direction: row - flex items will align horizontally
justify-content: flex-start - flex items will stack at the start of the line on the main axis
align-items: stretch - flex items will expand to cover the cross-size of the container
flex-wrap: nowrap - flex items are forced to stay in a single line
flex-shrink: 1 - a flex item is allowed to shrink
Note the last setting.
Because flex items are allowed to shrink by default (which prevents them from overflowing the container), the specified flex-basis / width / height may be overridden.
For example, flex-basis: 100px or width: 100px, coupled with flex-shrink: 1, will not necessarily be 100px.
To render the specified width – and keep it fixed – you will need to disable shrinking:
div {
width: 100px;
flex-shrink: 0;
}
OR
div {
flex-basis: 100px;
flex-shrink: 0;
}
OR, as recommended by the spec:
flex: 0 0 100px; /* don't grow, don't shrink, stay fixed at 100px */
7.2. Components of
Flexibility
Authors are encouraged to control flexibility using the flex shorthand
rather than with its longhand properties directly, as the shorthand
correctly resets any unspecified components to accommodate common
uses.
Browser Bugs
Some browsers have trouble sizing flex items in nested flex containers.
flex-basis ignored in a nested flex container. width works.
When using flex-basis, the container ignores the sizing of its children, and the children overflow the container. But with the width property, the container respects the sizing of its children and expands accordingly.
References:
Chrome does not expand flex parent according to children's content
Flex item overflowing when using flex-basis
Difference between width and flex-basis
Flex-basis is being ignored when sizing nested flex containers.
flex-basis:100px does something different from width:100px+flex-basis:auto
Examples:
https://jsfiddle.net/t419zhra/ (source: #Dremora)
https://codepen.io/anon/pen/NVxaoy (source #Daniel)
https://jsfiddle.net/voc9grx6/ (source: Chromium Bugs)
https://jsfiddle.net/qjpat9zk/ (source: Chromium Bugs)
flex items using flex-basis and white-space: nowrap overflow inline-flex container. width works.
It seems that a flex container set to inline-flex doesn't recognize flex-basis on a child when rendering a sibling with white-space: nowrap (although it could just be an item with undefined width). The container doesn't expand to accommodate the items.
But when the width property is used instead of flex-basis, the container respects the sizing of its children and expands accordingly. This is not a problem in IE11 and Edge.
References:
inline flex container width not growing
Inline flex container (display: inline-flex) is expanding the full width of parent container
Example:
https://jsfiddle.net/p18h0jxt/1/ (from first post above)
flex-basis (and flex-grow) not working on table element
References:
Why does flex-box work with a div, but not a table?
Why doesn't flex-grow: 1 work for a table in Safari? (and Edge)
flex-basis fails in Chrome and Firefox when the grandparent container is a shrink-to-fit element. The set-up works fine in Edge.
Absolutely positioned container not expanding width to fit flexbox content
Like in the example presented in the link above, involving position: absolute, the use of float and inline-block, will also render the same flawed output (jsfiddle demo).
Bugs affecting IE 10 and 11:
flex shorthand declarations with unitless flex-basis values are ignored
flex-basis doesn't account for box-sizing: border-box
flex-basis doesn't support calc()
Importance is ignored on flex-basis when using flex shorthand

In addition to Michael_B's excellent summary it's worth repeating this:
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.
The important part here is initial.
By itself, this does resolve to width/height until the other flex grow/shrink properties come into play.
So. a child with
.child {
flex-basis:25%;
flex-grow:1;
}
will be 25% wide initially but then immediately expand as much as it can until the other elements are factored in. If there are none..it will be 100% wide/tall.
A quick demo:
.flex {
width: 80%;
margin: 1em auto;
height: 25px;
display: flex;
background: rebeccapurple;
}
.child {
flex-basis: auto;
/* default */
background: plum;
}
.value {
flex-basis: 25%;
}
.grow {
flex-grow: 1;
}
<div class="flex">
<div class="child auto">Some Content</div>
</div>
<div class="flex">
<div class="child value">Some Content</div>
</div>
<div class="flex">
<div class="child grow">Some Content</div>
</div>
Experimenting with the flex-grow, flex-shrink and flex-basis
(or the shorthand flex :fg fs fb)...can lead to some interesting results.

Nobody seems to mention that there is one key difference between flex-basis and width (or height, depending on the current writing mode), if we ignore the flexible sizing aspect (flex-grow: 0; flex-shrink: 0;).
It originates from the exception in Flex Layout, that the automatic minimum size for flex items defaults to min-content instead of zero, like usually. In other words, the default min-width: auto computes to min-content instead of 0.
The result is, that flex-basis is (by default) bound below by min-content. If you specify a value smaller than min-content, for example flex-basis: 0, it will compute to min-content. This essentially means that (by default) you can't make the box's content overflow, since the box has at least the size of the content.
This is a key difference to width, which can size the box arbitrarily small (by default), since min-width defaults to 0. If the value of width is smaller than min-content, the contents will overflow the box.
This behavior is mentioned in the spec, but only implicitly in the following comment at the wrong place at the end of 7.1.1. Basic Values of flex.
By default, flex items won’t shrink below their minimum content size (the length of the longest word or fixed-size element). To change this, set the min-width or min-height property. (See § 4.5 Automatic Minimum Size of Flex Items.)
As mentioned in the comment, setting a minimum size lowers the bound, and setting it to zero effectively disables it, making flex-basis behave again as expected.
But there are drawbacks. Firstly, there is no minimum size property for the main axis. You have to use the correct min-width/min-height or min-block-size/min-inline-size property for the current flex-direction. If you changed the flex-direction, you would need to again find the correct minimum size property.
Secondly, flex-basis can't be used anymore to distribute space towards proportionally sized boxes instead of simply adding to their initial size. For more details, see Figure 7 in the spec.
Here is a minimal example. Set min-width: 0 to make flex-basis behave as expected again.
.container {
display: flex;
}
.container div {
background-color: lightgrey;
border: 1px solid black;
margin: 0 10px;
/* disable any flexible sizing */
flex-grow: 0;
flex-shrink: 0;
/* TOGGLE ME */
/* min-width: 0; */
}
.mincontent {
width: min-content;
}
.smallerflexbasis {
flex-basis: 3ex;
}
.smallerwidth {
width: 3ex;
}
<div class="container">
<div class="mincontent">Lorem ipsum</div>
<div class="smallerflexbasis">Lorem ipsum</div>
<div class="smallerwidth">Lorem ipsum</div>
</div>

Possibly the most important point to add:
What if the browser doesn't support flex? In such a case, width/height take over and their values apply.
It is a very good idea - almost essential - to define width/height on elements, even if you then have a completely different value for flex-basis. Remember to test by disabling display:flex and seeing what you get.

It makes a difference if you're wrapping.
Say, you set a child to width:0 and expect it to wrap, well that's not going to happen. But with flex-basis:0 it will wrap. (provided overflow isn't hidden)

if you set a div's min-width:600px, if the window size goes under 600px, you will see a horizontal scrollbar which is not a good ux design.
If you set its flex-basis:600px, if the window size goes under 600px, that box will shrink and you will not see a horizontal bar.
Note that flex-basis applies only to the flex items.

Related

Why are flex items overflowing container when flex-shrink set to 0? [duplicate]

There have been questions and articles about this, but nothing conclusive as far as I can tell. The best summary I could find is
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.
...which in itself doesn't say much about the behavior of elements with flex-basis set. With my current knowledge of flexbox I don't see why that couldn't describe width also.
I'd like to know how exactly flex-basis is different from width in practice:
If I replace width with flex-basis(and vice versa), what will change visually?
What happens if I set both to a different value? What happens if they have the same value?
Are there some special cases where using either width or flex-basis would have a significant difference to using the other?
How do width and flex-basis differ when used in conjunction with other flexbox styles, such as flex-wrap, flex-grow and flex-shrink?
Any other significant differences?
Edit/clarification: This question has been asked in a different format in What exactly flex-basis property sets? but I felt a more direct comparison or summary of the differences of flex-basis and width (or height) would be nice.
Consider flex-direction
The first thing that comes to mind when reading your question is that flex-basis doesn't always apply to width.
When flex-direction is row, flex-basis controls width.
But when flex-direction is column, flex-basis controls height.
Key Differences
Here are some important differences between flex-basis and width / height:
flex-basis applies only to flex items. Flex containers (that aren't also flex items) will ignore flex-basis but can use width and height.
flex-basis works only on the main axis. For example, if you're in flex-direction: column, the width property would be needed for sizing flex items horizontally.
flex-basis has no effect on absolutely-positioned flex items. width and height properties would be necessary. Absolutely-positioned flex items do not participate in flex layout.
By using the flex property, three properties – flex-grow, flex-shrink and flex-basis – can be neatly combined into one declaration. Using width, the same rule would require multiple lines of code.
Browser Behavior
In terms of how they are rendered, there should be no difference between flex-basis and width, unless flex-basis is auto or content.
From the spec:
7.2.3. The flex-basis property
For all values other than auto and content, flex-basis is resolved the same way as width in horizontal writing modes.
But the impact of auto or content may be minimal or nothing at all. More from the spec:
auto
When specified on a flex item, the auto keyword retrieves the value
of the main size property as the used flex-basis. If that value is
itself auto, then the used value is content.
content
Indicates automatic sizing, based on the flex item’s content.
Note: This value was not present in the initial release of Flexible
Box Layout, and thus some older implementations will not support it.
The equivalent effect can be achieved by using auto together with a
main size (width or height) of auto.
So, according to the spec, flex-basis and width resolve identically, unless flex-basis is auto or content. In such cases, flex-basis may use content width (which, presumably, the width property would use, as well).
The flex-shrink factor
It's important to remember the initial settings of a flex container. Some of these settings include:
flex-direction: row - flex items will align horizontally
justify-content: flex-start - flex items will stack at the start of the line on the main axis
align-items: stretch - flex items will expand to cover the cross-size of the container
flex-wrap: nowrap - flex items are forced to stay in a single line
flex-shrink: 1 - a flex item is allowed to shrink
Note the last setting.
Because flex items are allowed to shrink by default (which prevents them from overflowing the container), the specified flex-basis / width / height may be overridden.
For example, flex-basis: 100px or width: 100px, coupled with flex-shrink: 1, will not necessarily be 100px.
To render the specified width – and keep it fixed – you will need to disable shrinking:
div {
width: 100px;
flex-shrink: 0;
}
OR
div {
flex-basis: 100px;
flex-shrink: 0;
}
OR, as recommended by the spec:
flex: 0 0 100px; /* don't grow, don't shrink, stay fixed at 100px */
7.2. Components of
Flexibility
Authors are encouraged to control flexibility using the flex shorthand
rather than with its longhand properties directly, as the shorthand
correctly resets any unspecified components to accommodate common
uses.
Browser Bugs
Some browsers have trouble sizing flex items in nested flex containers.
flex-basis ignored in a nested flex container. width works.
When using flex-basis, the container ignores the sizing of its children, and the children overflow the container. But with the width property, the container respects the sizing of its children and expands accordingly.
References:
Chrome does not expand flex parent according to children's content
Flex item overflowing when using flex-basis
Difference between width and flex-basis
Flex-basis is being ignored when sizing nested flex containers.
flex-basis:100px does something different from width:100px+flex-basis:auto
Examples:
https://jsfiddle.net/t419zhra/ (source: #Dremora)
https://codepen.io/anon/pen/NVxaoy (source #Daniel)
https://jsfiddle.net/voc9grx6/ (source: Chromium Bugs)
https://jsfiddle.net/qjpat9zk/ (source: Chromium Bugs)
flex items using flex-basis and white-space: nowrap overflow inline-flex container. width works.
It seems that a flex container set to inline-flex doesn't recognize flex-basis on a child when rendering a sibling with white-space: nowrap (although it could just be an item with undefined width). The container doesn't expand to accommodate the items.
But when the width property is used instead of flex-basis, the container respects the sizing of its children and expands accordingly. This is not a problem in IE11 and Edge.
References:
inline flex container width not growing
Inline flex container (display: inline-flex) is expanding the full width of parent container
Example:
https://jsfiddle.net/p18h0jxt/1/ (from first post above)
flex-basis (and flex-grow) not working on table element
References:
Why does flex-box work with a div, but not a table?
Why doesn't flex-grow: 1 work for a table in Safari? (and Edge)
flex-basis fails in Chrome and Firefox when the grandparent container is a shrink-to-fit element. The set-up works fine in Edge.
Absolutely positioned container not expanding width to fit flexbox content
Like in the example presented in the link above, involving position: absolute, the use of float and inline-block, will also render the same flawed output (jsfiddle demo).
Bugs affecting IE 10 and 11:
flex shorthand declarations with unitless flex-basis values are ignored
flex-basis doesn't account for box-sizing: border-box
flex-basis doesn't support calc()
Importance is ignored on flex-basis when using flex shorthand
In addition to Michael_B's excellent summary it's worth repeating this:
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.
The important part here is initial.
By itself, this does resolve to width/height until the other flex grow/shrink properties come into play.
So. a child with
.child {
flex-basis:25%;
flex-grow:1;
}
will be 25% wide initially but then immediately expand as much as it can until the other elements are factored in. If there are none..it will be 100% wide/tall.
A quick demo:
.flex {
width: 80%;
margin: 1em auto;
height: 25px;
display: flex;
background: rebeccapurple;
}
.child {
flex-basis: auto;
/* default */
background: plum;
}
.value {
flex-basis: 25%;
}
.grow {
flex-grow: 1;
}
<div class="flex">
<div class="child auto">Some Content</div>
</div>
<div class="flex">
<div class="child value">Some Content</div>
</div>
<div class="flex">
<div class="child grow">Some Content</div>
</div>
Experimenting with the flex-grow, flex-shrink and flex-basis
(or the shorthand flex :fg fs fb)...can lead to some interesting results.
Nobody seems to mention that there is one key difference between flex-basis and width (or height, depending on the current writing mode), if we ignore the flexible sizing aspect (flex-grow: 0; flex-shrink: 0;).
It originates from the exception in Flex Layout, that the automatic minimum size for flex items defaults to min-content instead of zero, like usually. In other words, the default min-width: auto computes to min-content instead of 0.
The result is, that flex-basis is (by default) bound below by min-content. If you specify a value smaller than min-content, for example flex-basis: 0, it will compute to min-content. This essentially means that (by default) you can't make the box's content overflow, since the box has at least the size of the content.
This is a key difference to width, which can size the box arbitrarily small (by default), since min-width defaults to 0. If the value of width is smaller than min-content, the contents will overflow the box.
This behavior is mentioned in the spec, but only implicitly in the following comment at the wrong place at the end of 7.1.1. Basic Values of flex.
By default, flex items won’t shrink below their minimum content size (the length of the longest word or fixed-size element). To change this, set the min-width or min-height property. (See § 4.5 Automatic Minimum Size of Flex Items.)
As mentioned in the comment, setting a minimum size lowers the bound, and setting it to zero effectively disables it, making flex-basis behave again as expected.
But there are drawbacks. Firstly, there is no minimum size property for the main axis. You have to use the correct min-width/min-height or min-block-size/min-inline-size property for the current flex-direction. If you changed the flex-direction, you would need to again find the correct minimum size property.
Secondly, flex-basis can't be used anymore to distribute space towards proportionally sized boxes instead of simply adding to their initial size. For more details, see Figure 7 in the spec.
Here is a minimal example. Set min-width: 0 to make flex-basis behave as expected again.
.container {
display: flex;
}
.container div {
background-color: lightgrey;
border: 1px solid black;
margin: 0 10px;
/* disable any flexible sizing */
flex-grow: 0;
flex-shrink: 0;
/* TOGGLE ME */
/* min-width: 0; */
}
.mincontent {
width: min-content;
}
.smallerflexbasis {
flex-basis: 3ex;
}
.smallerwidth {
width: 3ex;
}
<div class="container">
<div class="mincontent">Lorem ipsum</div>
<div class="smallerflexbasis">Lorem ipsum</div>
<div class="smallerwidth">Lorem ipsum</div>
</div>
Possibly the most important point to add:
What if the browser doesn't support flex? In such a case, width/height take over and their values apply.
It is a very good idea - almost essential - to define width/height on elements, even if you then have a completely different value for flex-basis. Remember to test by disabling display:flex and seeing what you get.
It makes a difference if you're wrapping.
Say, you set a child to width:0 and expect it to wrap, well that's not going to happen. But with flex-basis:0 it will wrap. (provided overflow isn't hidden)
if you set a div's min-width:600px, if the window size goes under 600px, you will see a horizontal scrollbar which is not a good ux design.
If you set its flex-basis:600px, if the window size goes under 600px, that box will shrink and you will not see a horizontal bar.
Note that flex-basis applies only to the flex items.

CSS How to properly use absolutely positioned container with flex childs? [duplicate]

There have been questions and articles about this, but nothing conclusive as far as I can tell. The best summary I could find is
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.
...which in itself doesn't say much about the behavior of elements with flex-basis set. With my current knowledge of flexbox I don't see why that couldn't describe width also.
I'd like to know how exactly flex-basis is different from width in practice:
If I replace width with flex-basis(and vice versa), what will change visually?
What happens if I set both to a different value? What happens if they have the same value?
Are there some special cases where using either width or flex-basis would have a significant difference to using the other?
How do width and flex-basis differ when used in conjunction with other flexbox styles, such as flex-wrap, flex-grow and flex-shrink?
Any other significant differences?
Edit/clarification: This question has been asked in a different format in What exactly flex-basis property sets? but I felt a more direct comparison or summary of the differences of flex-basis and width (or height) would be nice.
Consider flex-direction
The first thing that comes to mind when reading your question is that flex-basis doesn't always apply to width.
When flex-direction is row, flex-basis controls width.
But when flex-direction is column, flex-basis controls height.
Key Differences
Here are some important differences between flex-basis and width / height:
flex-basis applies only to flex items. Flex containers (that aren't also flex items) will ignore flex-basis but can use width and height.
flex-basis works only on the main axis. For example, if you're in flex-direction: column, the width property would be needed for sizing flex items horizontally.
flex-basis has no effect on absolutely-positioned flex items. width and height properties would be necessary. Absolutely-positioned flex items do not participate in flex layout.
By using the flex property, three properties – flex-grow, flex-shrink and flex-basis – can be neatly combined into one declaration. Using width, the same rule would require multiple lines of code.
Browser Behavior
In terms of how they are rendered, there should be no difference between flex-basis and width, unless flex-basis is auto or content.
From the spec:
7.2.3. The flex-basis property
For all values other than auto and content, flex-basis is resolved the same way as width in horizontal writing modes.
But the impact of auto or content may be minimal or nothing at all. More from the spec:
auto
When specified on a flex item, the auto keyword retrieves the value
of the main size property as the used flex-basis. If that value is
itself auto, then the used value is content.
content
Indicates automatic sizing, based on the flex item’s content.
Note: This value was not present in the initial release of Flexible
Box Layout, and thus some older implementations will not support it.
The equivalent effect can be achieved by using auto together with a
main size (width or height) of auto.
So, according to the spec, flex-basis and width resolve identically, unless flex-basis is auto or content. In such cases, flex-basis may use content width (which, presumably, the width property would use, as well).
The flex-shrink factor
It's important to remember the initial settings of a flex container. Some of these settings include:
flex-direction: row - flex items will align horizontally
justify-content: flex-start - flex items will stack at the start of the line on the main axis
align-items: stretch - flex items will expand to cover the cross-size of the container
flex-wrap: nowrap - flex items are forced to stay in a single line
flex-shrink: 1 - a flex item is allowed to shrink
Note the last setting.
Because flex items are allowed to shrink by default (which prevents them from overflowing the container), the specified flex-basis / width / height may be overridden.
For example, flex-basis: 100px or width: 100px, coupled with flex-shrink: 1, will not necessarily be 100px.
To render the specified width – and keep it fixed – you will need to disable shrinking:
div {
width: 100px;
flex-shrink: 0;
}
OR
div {
flex-basis: 100px;
flex-shrink: 0;
}
OR, as recommended by the spec:
flex: 0 0 100px; /* don't grow, don't shrink, stay fixed at 100px */
7.2. Components of
Flexibility
Authors are encouraged to control flexibility using the flex shorthand
rather than with its longhand properties directly, as the shorthand
correctly resets any unspecified components to accommodate common
uses.
Browser Bugs
Some browsers have trouble sizing flex items in nested flex containers.
flex-basis ignored in a nested flex container. width works.
When using flex-basis, the container ignores the sizing of its children, and the children overflow the container. But with the width property, the container respects the sizing of its children and expands accordingly.
References:
Chrome does not expand flex parent according to children's content
Flex item overflowing when using flex-basis
Difference between width and flex-basis
Flex-basis is being ignored when sizing nested flex containers.
flex-basis:100px does something different from width:100px+flex-basis:auto
Examples:
https://jsfiddle.net/t419zhra/ (source: #Dremora)
https://codepen.io/anon/pen/NVxaoy (source #Daniel)
https://jsfiddle.net/voc9grx6/ (source: Chromium Bugs)
https://jsfiddle.net/qjpat9zk/ (source: Chromium Bugs)
flex items using flex-basis and white-space: nowrap overflow inline-flex container. width works.
It seems that a flex container set to inline-flex doesn't recognize flex-basis on a child when rendering a sibling with white-space: nowrap (although it could just be an item with undefined width). The container doesn't expand to accommodate the items.
But when the width property is used instead of flex-basis, the container respects the sizing of its children and expands accordingly. This is not a problem in IE11 and Edge.
References:
inline flex container width not growing
Inline flex container (display: inline-flex) is expanding the full width of parent container
Example:
https://jsfiddle.net/p18h0jxt/1/ (from first post above)
flex-basis (and flex-grow) not working on table element
References:
Why does flex-box work with a div, but not a table?
Why doesn't flex-grow: 1 work for a table in Safari? (and Edge)
flex-basis fails in Chrome and Firefox when the grandparent container is a shrink-to-fit element. The set-up works fine in Edge.
Absolutely positioned container not expanding width to fit flexbox content
Like in the example presented in the link above, involving position: absolute, the use of float and inline-block, will also render the same flawed output (jsfiddle demo).
Bugs affecting IE 10 and 11:
flex shorthand declarations with unitless flex-basis values are ignored
flex-basis doesn't account for box-sizing: border-box
flex-basis doesn't support calc()
Importance is ignored on flex-basis when using flex shorthand
In addition to Michael_B's excellent summary it's worth repeating this:
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.
The important part here is initial.
By itself, this does resolve to width/height until the other flex grow/shrink properties come into play.
So. a child with
.child {
flex-basis:25%;
flex-grow:1;
}
will be 25% wide initially but then immediately expand as much as it can until the other elements are factored in. If there are none..it will be 100% wide/tall.
A quick demo:
.flex {
width: 80%;
margin: 1em auto;
height: 25px;
display: flex;
background: rebeccapurple;
}
.child {
flex-basis: auto;
/* default */
background: plum;
}
.value {
flex-basis: 25%;
}
.grow {
flex-grow: 1;
}
<div class="flex">
<div class="child auto">Some Content</div>
</div>
<div class="flex">
<div class="child value">Some Content</div>
</div>
<div class="flex">
<div class="child grow">Some Content</div>
</div>
Experimenting with the flex-grow, flex-shrink and flex-basis
(or the shorthand flex :fg fs fb)...can lead to some interesting results.
Nobody seems to mention that there is one key difference between flex-basis and width (or height, depending on the current writing mode), if we ignore the flexible sizing aspect (flex-grow: 0; flex-shrink: 0;).
It originates from the exception in Flex Layout, that the automatic minimum size for flex items defaults to min-content instead of zero, like usually. In other words, the default min-width: auto computes to min-content instead of 0.
The result is, that flex-basis is (by default) bound below by min-content. If you specify a value smaller than min-content, for example flex-basis: 0, it will compute to min-content. This essentially means that (by default) you can't make the box's content overflow, since the box has at least the size of the content.
This is a key difference to width, which can size the box arbitrarily small (by default), since min-width defaults to 0. If the value of width is smaller than min-content, the contents will overflow the box.
This behavior is mentioned in the spec, but only implicitly in the following comment at the wrong place at the end of 7.1.1. Basic Values of flex.
By default, flex items won’t shrink below their minimum content size (the length of the longest word or fixed-size element). To change this, set the min-width or min-height property. (See § 4.5 Automatic Minimum Size of Flex Items.)
As mentioned in the comment, setting a minimum size lowers the bound, and setting it to zero effectively disables it, making flex-basis behave again as expected.
But there are drawbacks. Firstly, there is no minimum size property for the main axis. You have to use the correct min-width/min-height or min-block-size/min-inline-size property for the current flex-direction. If you changed the flex-direction, you would need to again find the correct minimum size property.
Secondly, flex-basis can't be used anymore to distribute space towards proportionally sized boxes instead of simply adding to their initial size. For more details, see Figure 7 in the spec.
Here is a minimal example. Set min-width: 0 to make flex-basis behave as expected again.
.container {
display: flex;
}
.container div {
background-color: lightgrey;
border: 1px solid black;
margin: 0 10px;
/* disable any flexible sizing */
flex-grow: 0;
flex-shrink: 0;
/* TOGGLE ME */
/* min-width: 0; */
}
.mincontent {
width: min-content;
}
.smallerflexbasis {
flex-basis: 3ex;
}
.smallerwidth {
width: 3ex;
}
<div class="container">
<div class="mincontent">Lorem ipsum</div>
<div class="smallerflexbasis">Lorem ipsum</div>
<div class="smallerwidth">Lorem ipsum</div>
</div>
Possibly the most important point to add:
What if the browser doesn't support flex? In such a case, width/height take over and their values apply.
It is a very good idea - almost essential - to define width/height on elements, even if you then have a completely different value for flex-basis. Remember to test by disabling display:flex and seeing what you get.
It makes a difference if you're wrapping.
Say, you set a child to width:0 and expect it to wrap, well that's not going to happen. But with flex-basis:0 it will wrap. (provided overflow isn't hidden)
if you set a div's min-width:600px, if the window size goes under 600px, you will see a horizontal scrollbar which is not a good ux design.
If you set its flex-basis:600px, if the window size goes under 600px, that box will shrink and you will not see a horizontal bar.
Note that flex-basis applies only to the flex items.

Using flex-basis to control page layout with flexbox [duplicate]

There have been questions and articles about this, but nothing conclusive as far as I can tell. The best summary I could find is
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.
...which in itself doesn't say much about the behavior of elements with flex-basis set. With my current knowledge of flexbox I don't see why that couldn't describe width also.
I'd like to know how exactly flex-basis is different from width in practice:
If I replace width with flex-basis(and vice versa), what will change visually?
What happens if I set both to a different value? What happens if they have the same value?
Are there some special cases where using either width or flex-basis would have a significant difference to using the other?
How do width and flex-basis differ when used in conjunction with other flexbox styles, such as flex-wrap, flex-grow and flex-shrink?
Any other significant differences?
Edit/clarification: This question has been asked in a different format in What exactly flex-basis property sets? but I felt a more direct comparison or summary of the differences of flex-basis and width (or height) would be nice.
Consider flex-direction
The first thing that comes to mind when reading your question is that flex-basis doesn't always apply to width.
When flex-direction is row, flex-basis controls width.
But when flex-direction is column, flex-basis controls height.
Key Differences
Here are some important differences between flex-basis and width / height:
flex-basis applies only to flex items. Flex containers (that aren't also flex items) will ignore flex-basis but can use width and height.
flex-basis works only on the main axis. For example, if you're in flex-direction: column, the width property would be needed for sizing flex items horizontally.
flex-basis has no effect on absolutely-positioned flex items. width and height properties would be necessary. Absolutely-positioned flex items do not participate in flex layout.
By using the flex property, three properties – flex-grow, flex-shrink and flex-basis – can be neatly combined into one declaration. Using width, the same rule would require multiple lines of code.
Browser Behavior
In terms of how they are rendered, there should be no difference between flex-basis and width, unless flex-basis is auto or content.
From the spec:
7.2.3. The flex-basis property
For all values other than auto and content, flex-basis is resolved the same way as width in horizontal writing modes.
But the impact of auto or content may be minimal or nothing at all. More from the spec:
auto
When specified on a flex item, the auto keyword retrieves the value
of the main size property as the used flex-basis. If that value is
itself auto, then the used value is content.
content
Indicates automatic sizing, based on the flex item’s content.
Note: This value was not present in the initial release of Flexible
Box Layout, and thus some older implementations will not support it.
The equivalent effect can be achieved by using auto together with a
main size (width or height) of auto.
So, according to the spec, flex-basis and width resolve identically, unless flex-basis is auto or content. In such cases, flex-basis may use content width (which, presumably, the width property would use, as well).
The flex-shrink factor
It's important to remember the initial settings of a flex container. Some of these settings include:
flex-direction: row - flex items will align horizontally
justify-content: flex-start - flex items will stack at the start of the line on the main axis
align-items: stretch - flex items will expand to cover the cross-size of the container
flex-wrap: nowrap - flex items are forced to stay in a single line
flex-shrink: 1 - a flex item is allowed to shrink
Note the last setting.
Because flex items are allowed to shrink by default (which prevents them from overflowing the container), the specified flex-basis / width / height may be overridden.
For example, flex-basis: 100px or width: 100px, coupled with flex-shrink: 1, will not necessarily be 100px.
To render the specified width – and keep it fixed – you will need to disable shrinking:
div {
width: 100px;
flex-shrink: 0;
}
OR
div {
flex-basis: 100px;
flex-shrink: 0;
}
OR, as recommended by the spec:
flex: 0 0 100px; /* don't grow, don't shrink, stay fixed at 100px */
7.2. Components of
Flexibility
Authors are encouraged to control flexibility using the flex shorthand
rather than with its longhand properties directly, as the shorthand
correctly resets any unspecified components to accommodate common
uses.
Browser Bugs
Some browsers have trouble sizing flex items in nested flex containers.
flex-basis ignored in a nested flex container. width works.
When using flex-basis, the container ignores the sizing of its children, and the children overflow the container. But with the width property, the container respects the sizing of its children and expands accordingly.
References:
Chrome does not expand flex parent according to children's content
Flex item overflowing when using flex-basis
Difference between width and flex-basis
Flex-basis is being ignored when sizing nested flex containers.
flex-basis:100px does something different from width:100px+flex-basis:auto
Examples:
https://jsfiddle.net/t419zhra/ (source: #Dremora)
https://codepen.io/anon/pen/NVxaoy (source #Daniel)
https://jsfiddle.net/voc9grx6/ (source: Chromium Bugs)
https://jsfiddle.net/qjpat9zk/ (source: Chromium Bugs)
flex items using flex-basis and white-space: nowrap overflow inline-flex container. width works.
It seems that a flex container set to inline-flex doesn't recognize flex-basis on a child when rendering a sibling with white-space: nowrap (although it could just be an item with undefined width). The container doesn't expand to accommodate the items.
But when the width property is used instead of flex-basis, the container respects the sizing of its children and expands accordingly. This is not a problem in IE11 and Edge.
References:
inline flex container width not growing
Inline flex container (display: inline-flex) is expanding the full width of parent container
Example:
https://jsfiddle.net/p18h0jxt/1/ (from first post above)
flex-basis (and flex-grow) not working on table element
References:
Why does flex-box work with a div, but not a table?
Why doesn't flex-grow: 1 work for a table in Safari? (and Edge)
flex-basis fails in Chrome and Firefox when the grandparent container is a shrink-to-fit element. The set-up works fine in Edge.
Absolutely positioned container not expanding width to fit flexbox content
Like in the example presented in the link above, involving position: absolute, the use of float and inline-block, will also render the same flawed output (jsfiddle demo).
Bugs affecting IE 10 and 11:
flex shorthand declarations with unitless flex-basis values are ignored
flex-basis doesn't account for box-sizing: border-box
flex-basis doesn't support calc()
Importance is ignored on flex-basis when using flex shorthand
In addition to Michael_B's excellent summary it's worth repeating this:
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.
The important part here is initial.
By itself, this does resolve to width/height until the other flex grow/shrink properties come into play.
So. a child with
.child {
flex-basis:25%;
flex-grow:1;
}
will be 25% wide initially but then immediately expand as much as it can until the other elements are factored in. If there are none..it will be 100% wide/tall.
A quick demo:
.flex {
width: 80%;
margin: 1em auto;
height: 25px;
display: flex;
background: rebeccapurple;
}
.child {
flex-basis: auto;
/* default */
background: plum;
}
.value {
flex-basis: 25%;
}
.grow {
flex-grow: 1;
}
<div class="flex">
<div class="child auto">Some Content</div>
</div>
<div class="flex">
<div class="child value">Some Content</div>
</div>
<div class="flex">
<div class="child grow">Some Content</div>
</div>
Experimenting with the flex-grow, flex-shrink and flex-basis
(or the shorthand flex :fg fs fb)...can lead to some interesting results.
Nobody seems to mention that there is one key difference between flex-basis and width (or height, depending on the current writing mode), if we ignore the flexible sizing aspect (flex-grow: 0; flex-shrink: 0;).
It originates from the exception in Flex Layout, that the automatic minimum size for flex items defaults to min-content instead of zero, like usually. In other words, the default min-width: auto computes to min-content instead of 0.
The result is, that flex-basis is (by default) bound below by min-content. If you specify a value smaller than min-content, for example flex-basis: 0, it will compute to min-content. This essentially means that (by default) you can't make the box's content overflow, since the box has at least the size of the content.
This is a key difference to width, which can size the box arbitrarily small (by default), since min-width defaults to 0. If the value of width is smaller than min-content, the contents will overflow the box.
This behavior is mentioned in the spec, but only implicitly in the following comment at the wrong place at the end of 7.1.1. Basic Values of flex.
By default, flex items won’t shrink below their minimum content size (the length of the longest word or fixed-size element). To change this, set the min-width or min-height property. (See § 4.5 Automatic Minimum Size of Flex Items.)
As mentioned in the comment, setting a minimum size lowers the bound, and setting it to zero effectively disables it, making flex-basis behave again as expected.
But there are drawbacks. Firstly, there is no minimum size property for the main axis. You have to use the correct min-width/min-height or min-block-size/min-inline-size property for the current flex-direction. If you changed the flex-direction, you would need to again find the correct minimum size property.
Secondly, flex-basis can't be used anymore to distribute space towards proportionally sized boxes instead of simply adding to their initial size. For more details, see Figure 7 in the spec.
Here is a minimal example. Set min-width: 0 to make flex-basis behave as expected again.
.container {
display: flex;
}
.container div {
background-color: lightgrey;
border: 1px solid black;
margin: 0 10px;
/* disable any flexible sizing */
flex-grow: 0;
flex-shrink: 0;
/* TOGGLE ME */
/* min-width: 0; */
}
.mincontent {
width: min-content;
}
.smallerflexbasis {
flex-basis: 3ex;
}
.smallerwidth {
width: 3ex;
}
<div class="container">
<div class="mincontent">Lorem ipsum</div>
<div class="smallerflexbasis">Lorem ipsum</div>
<div class="smallerwidth">Lorem ipsum</div>
</div>
Possibly the most important point to add:
What if the browser doesn't support flex? In such a case, width/height take over and their values apply.
It is a very good idea - almost essential - to define width/height on elements, even if you then have a completely different value for flex-basis. Remember to test by disabling display:flex and seeing what you get.
It makes a difference if you're wrapping.
Say, you set a child to width:0 and expect it to wrap, well that's not going to happen. But with flex-basis:0 it will wrap. (provided overflow isn't hidden)
if you set a div's min-width:600px, if the window size goes under 600px, you will see a horizontal scrollbar which is not a good ux design.
If you set its flex-basis:600px, if the window size goes under 600px, that box will shrink and you will not see a horizontal bar.
Note that flex-basis applies only to the flex items.

Setting viewport to specific height in flexbox [duplicate]

There have been questions and articles about this, but nothing conclusive as far as I can tell. The best summary I could find is
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.
...which in itself doesn't say much about the behavior of elements with flex-basis set. With my current knowledge of flexbox I don't see why that couldn't describe width also.
I'd like to know how exactly flex-basis is different from width in practice:
If I replace width with flex-basis(and vice versa), what will change visually?
What happens if I set both to a different value? What happens if they have the same value?
Are there some special cases where using either width or flex-basis would have a significant difference to using the other?
How do width and flex-basis differ when used in conjunction with other flexbox styles, such as flex-wrap, flex-grow and flex-shrink?
Any other significant differences?
Edit/clarification: This question has been asked in a different format in What exactly flex-basis property sets? but I felt a more direct comparison or summary of the differences of flex-basis and width (or height) would be nice.
Consider flex-direction
The first thing that comes to mind when reading your question is that flex-basis doesn't always apply to width.
When flex-direction is row, flex-basis controls width.
But when flex-direction is column, flex-basis controls height.
Key Differences
Here are some important differences between flex-basis and width / height:
flex-basis applies only to flex items. Flex containers (that aren't also flex items) will ignore flex-basis but can use width and height.
flex-basis works only on the main axis. For example, if you're in flex-direction: column, the width property would be needed for sizing flex items horizontally.
flex-basis has no effect on absolutely-positioned flex items. width and height properties would be necessary. Absolutely-positioned flex items do not participate in flex layout.
By using the flex property, three properties – flex-grow, flex-shrink and flex-basis – can be neatly combined into one declaration. Using width, the same rule would require multiple lines of code.
Browser Behavior
In terms of how they are rendered, there should be no difference between flex-basis and width, unless flex-basis is auto or content.
From the spec:
7.2.3. The flex-basis property
For all values other than auto and content, flex-basis is resolved the same way as width in horizontal writing modes.
But the impact of auto or content may be minimal or nothing at all. More from the spec:
auto
When specified on a flex item, the auto keyword retrieves the value
of the main size property as the used flex-basis. If that value is
itself auto, then the used value is content.
content
Indicates automatic sizing, based on the flex item’s content.
Note: This value was not present in the initial release of Flexible
Box Layout, and thus some older implementations will not support it.
The equivalent effect can be achieved by using auto together with a
main size (width or height) of auto.
So, according to the spec, flex-basis and width resolve identically, unless flex-basis is auto or content. In such cases, flex-basis may use content width (which, presumably, the width property would use, as well).
The flex-shrink factor
It's important to remember the initial settings of a flex container. Some of these settings include:
flex-direction: row - flex items will align horizontally
justify-content: flex-start - flex items will stack at the start of the line on the main axis
align-items: stretch - flex items will expand to cover the cross-size of the container
flex-wrap: nowrap - flex items are forced to stay in a single line
flex-shrink: 1 - a flex item is allowed to shrink
Note the last setting.
Because flex items are allowed to shrink by default (which prevents them from overflowing the container), the specified flex-basis / width / height may be overridden.
For example, flex-basis: 100px or width: 100px, coupled with flex-shrink: 1, will not necessarily be 100px.
To render the specified width – and keep it fixed – you will need to disable shrinking:
div {
width: 100px;
flex-shrink: 0;
}
OR
div {
flex-basis: 100px;
flex-shrink: 0;
}
OR, as recommended by the spec:
flex: 0 0 100px; /* don't grow, don't shrink, stay fixed at 100px */
7.2. Components of
Flexibility
Authors are encouraged to control flexibility using the flex shorthand
rather than with its longhand properties directly, as the shorthand
correctly resets any unspecified components to accommodate common
uses.
Browser Bugs
Some browsers have trouble sizing flex items in nested flex containers.
flex-basis ignored in a nested flex container. width works.
When using flex-basis, the container ignores the sizing of its children, and the children overflow the container. But with the width property, the container respects the sizing of its children and expands accordingly.
References:
Chrome does not expand flex parent according to children's content
Flex item overflowing when using flex-basis
Difference between width and flex-basis
Flex-basis is being ignored when sizing nested flex containers.
flex-basis:100px does something different from width:100px+flex-basis:auto
Examples:
https://jsfiddle.net/t419zhra/ (source: #Dremora)
https://codepen.io/anon/pen/NVxaoy (source #Daniel)
https://jsfiddle.net/voc9grx6/ (source: Chromium Bugs)
https://jsfiddle.net/qjpat9zk/ (source: Chromium Bugs)
flex items using flex-basis and white-space: nowrap overflow inline-flex container. width works.
It seems that a flex container set to inline-flex doesn't recognize flex-basis on a child when rendering a sibling with white-space: nowrap (although it could just be an item with undefined width). The container doesn't expand to accommodate the items.
But when the width property is used instead of flex-basis, the container respects the sizing of its children and expands accordingly. This is not a problem in IE11 and Edge.
References:
inline flex container width not growing
Inline flex container (display: inline-flex) is expanding the full width of parent container
Example:
https://jsfiddle.net/p18h0jxt/1/ (from first post above)
flex-basis (and flex-grow) not working on table element
References:
Why does flex-box work with a div, but not a table?
Why doesn't flex-grow: 1 work for a table in Safari? (and Edge)
flex-basis fails in Chrome and Firefox when the grandparent container is a shrink-to-fit element. The set-up works fine in Edge.
Absolutely positioned container not expanding width to fit flexbox content
Like in the example presented in the link above, involving position: absolute, the use of float and inline-block, will also render the same flawed output (jsfiddle demo).
Bugs affecting IE 10 and 11:
flex shorthand declarations with unitless flex-basis values are ignored
flex-basis doesn't account for box-sizing: border-box
flex-basis doesn't support calc()
Importance is ignored on flex-basis when using flex shorthand
In addition to Michael_B's excellent summary it's worth repeating this:
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.
The important part here is initial.
By itself, this does resolve to width/height until the other flex grow/shrink properties come into play.
So. a child with
.child {
flex-basis:25%;
flex-grow:1;
}
will be 25% wide initially but then immediately expand as much as it can until the other elements are factored in. If there are none..it will be 100% wide/tall.
A quick demo:
.flex {
width: 80%;
margin: 1em auto;
height: 25px;
display: flex;
background: rebeccapurple;
}
.child {
flex-basis: auto;
/* default */
background: plum;
}
.value {
flex-basis: 25%;
}
.grow {
flex-grow: 1;
}
<div class="flex">
<div class="child auto">Some Content</div>
</div>
<div class="flex">
<div class="child value">Some Content</div>
</div>
<div class="flex">
<div class="child grow">Some Content</div>
</div>
Experimenting with the flex-grow, flex-shrink and flex-basis
(or the shorthand flex :fg fs fb)...can lead to some interesting results.
Nobody seems to mention that there is one key difference between flex-basis and width (or height, depending on the current writing mode), if we ignore the flexible sizing aspect (flex-grow: 0; flex-shrink: 0;).
It originates from the exception in Flex Layout, that the automatic minimum size for flex items defaults to min-content instead of zero, like usually. In other words, the default min-width: auto computes to min-content instead of 0.
The result is, that flex-basis is (by default) bound below by min-content. If you specify a value smaller than min-content, for example flex-basis: 0, it will compute to min-content. This essentially means that (by default) you can't make the box's content overflow, since the box has at least the size of the content.
This is a key difference to width, which can size the box arbitrarily small (by default), since min-width defaults to 0. If the value of width is smaller than min-content, the contents will overflow the box.
This behavior is mentioned in the spec, but only implicitly in the following comment at the wrong place at the end of 7.1.1. Basic Values of flex.
By default, flex items won’t shrink below their minimum content size (the length of the longest word or fixed-size element). To change this, set the min-width or min-height property. (See § 4.5 Automatic Minimum Size of Flex Items.)
As mentioned in the comment, setting a minimum size lowers the bound, and setting it to zero effectively disables it, making flex-basis behave again as expected.
But there are drawbacks. Firstly, there is no minimum size property for the main axis. You have to use the correct min-width/min-height or min-block-size/min-inline-size property for the current flex-direction. If you changed the flex-direction, you would need to again find the correct minimum size property.
Secondly, flex-basis can't be used anymore to distribute space towards proportionally sized boxes instead of simply adding to their initial size. For more details, see Figure 7 in the spec.
Here is a minimal example. Set min-width: 0 to make flex-basis behave as expected again.
.container {
display: flex;
}
.container div {
background-color: lightgrey;
border: 1px solid black;
margin: 0 10px;
/* disable any flexible sizing */
flex-grow: 0;
flex-shrink: 0;
/* TOGGLE ME */
/* min-width: 0; */
}
.mincontent {
width: min-content;
}
.smallerflexbasis {
flex-basis: 3ex;
}
.smallerwidth {
width: 3ex;
}
<div class="container">
<div class="mincontent">Lorem ipsum</div>
<div class="smallerflexbasis">Lorem ipsum</div>
<div class="smallerwidth">Lorem ipsum</div>
</div>
Possibly the most important point to add:
What if the browser doesn't support flex? In such a case, width/height take over and their values apply.
It is a very good idea - almost essential - to define width/height on elements, even if you then have a completely different value for flex-basis. Remember to test by disabling display:flex and seeing what you get.
It makes a difference if you're wrapping.
Say, you set a child to width:0 and expect it to wrap, well that's not going to happen. But with flex-basis:0 it will wrap. (provided overflow isn't hidden)
if you set a div's min-width:600px, if the window size goes under 600px, you will see a horizontal scrollbar which is not a good ux design.
If you set its flex-basis:600px, if the window size goes under 600px, that box will shrink and you will not see a horizontal bar.
Note that flex-basis applies only to the flex items.

What are the differences between flex-basis and width?

There have been questions and articles about this, but nothing conclusive as far as I can tell. The best summary I could find is
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.
...which in itself doesn't say much about the behavior of elements with flex-basis set. With my current knowledge of flexbox I don't see why that couldn't describe width also.
I'd like to know how exactly flex-basis is different from width in practice:
If I replace width with flex-basis(and vice versa), what will change visually?
What happens if I set both to a different value? What happens if they have the same value?
Are there some special cases where using either width or flex-basis would have a significant difference to using the other?
How do width and flex-basis differ when used in conjunction with other flexbox styles, such as flex-wrap, flex-grow and flex-shrink?
Any other significant differences?
Edit/clarification: This question has been asked in a different format in What exactly flex-basis property sets? but I felt a more direct comparison or summary of the differences of flex-basis and width (or height) would be nice.
Consider flex-direction
The first thing that comes to mind when reading your question is that flex-basis doesn't always apply to width.
When flex-direction is row, flex-basis controls width.
But when flex-direction is column, flex-basis controls height.
Key Differences
Here are some important differences between flex-basis and width / height:
flex-basis applies only to flex items. Flex containers (that aren't also flex items) will ignore flex-basis but can use width and height.
flex-basis works only on the main axis. For example, if you're in flex-direction: column, the width property would be needed for sizing flex items horizontally.
flex-basis has no effect on absolutely-positioned flex items. width and height properties would be necessary. Absolutely-positioned flex items do not participate in flex layout.
By using the flex property, three properties – flex-grow, flex-shrink and flex-basis – can be neatly combined into one declaration. Using width, the same rule would require multiple lines of code.
Browser Behavior
In terms of how they are rendered, there should be no difference between flex-basis and width, unless flex-basis is auto or content.
From the spec:
7.2.3. The flex-basis property
For all values other than auto and content, flex-basis is resolved the same way as width in horizontal writing modes.
But the impact of auto or content may be minimal or nothing at all. More from the spec:
auto
When specified on a flex item, the auto keyword retrieves the value
of the main size property as the used flex-basis. If that value is
itself auto, then the used value is content.
content
Indicates automatic sizing, based on the flex item’s content.
Note: This value was not present in the initial release of Flexible
Box Layout, and thus some older implementations will not support it.
The equivalent effect can be achieved by using auto together with a
main size (width or height) of auto.
So, according to the spec, flex-basis and width resolve identically, unless flex-basis is auto or content. In such cases, flex-basis may use content width (which, presumably, the width property would use, as well).
The flex-shrink factor
It's important to remember the initial settings of a flex container. Some of these settings include:
flex-direction: row - flex items will align horizontally
justify-content: flex-start - flex items will stack at the start of the line on the main axis
align-items: stretch - flex items will expand to cover the cross-size of the container
flex-wrap: nowrap - flex items are forced to stay in a single line
flex-shrink: 1 - a flex item is allowed to shrink
Note the last setting.
Because flex items are allowed to shrink by default (which prevents them from overflowing the container), the specified flex-basis / width / height may be overridden.
For example, flex-basis: 100px or width: 100px, coupled with flex-shrink: 1, will not necessarily be 100px.
To render the specified width – and keep it fixed – you will need to disable shrinking:
div {
width: 100px;
flex-shrink: 0;
}
OR
div {
flex-basis: 100px;
flex-shrink: 0;
}
OR, as recommended by the spec:
flex: 0 0 100px; /* don't grow, don't shrink, stay fixed at 100px */
7.2. Components of
Flexibility
Authors are encouraged to control flexibility using the flex shorthand
rather than with its longhand properties directly, as the shorthand
correctly resets any unspecified components to accommodate common
uses.
Browser Bugs
Some browsers have trouble sizing flex items in nested flex containers.
flex-basis ignored in a nested flex container. width works.
When using flex-basis, the container ignores the sizing of its children, and the children overflow the container. But with the width property, the container respects the sizing of its children and expands accordingly.
References:
Chrome does not expand flex parent according to children's content
Flex item overflowing when using flex-basis
Difference between width and flex-basis
Flex-basis is being ignored when sizing nested flex containers.
flex-basis:100px does something different from width:100px+flex-basis:auto
Examples:
https://jsfiddle.net/t419zhra/ (source: #Dremora)
https://codepen.io/anon/pen/NVxaoy (source #Daniel)
https://jsfiddle.net/voc9grx6/ (source: Chromium Bugs)
https://jsfiddle.net/qjpat9zk/ (source: Chromium Bugs)
flex items using flex-basis and white-space: nowrap overflow inline-flex container. width works.
It seems that a flex container set to inline-flex doesn't recognize flex-basis on a child when rendering a sibling with white-space: nowrap (although it could just be an item with undefined width). The container doesn't expand to accommodate the items.
But when the width property is used instead of flex-basis, the container respects the sizing of its children and expands accordingly. This is not a problem in IE11 and Edge.
References:
inline flex container width not growing
Inline flex container (display: inline-flex) is expanding the full width of parent container
Example:
https://jsfiddle.net/p18h0jxt/1/ (from first post above)
flex-basis (and flex-grow) not working on table element
References:
Why does flex-box work with a div, but not a table?
Why doesn't flex-grow: 1 work for a table in Safari? (and Edge)
flex-basis fails in Chrome and Firefox when the grandparent container is a shrink-to-fit element. The set-up works fine in Edge.
Absolutely positioned container not expanding width to fit flexbox content
Like in the example presented in the link above, involving position: absolute, the use of float and inline-block, will also render the same flawed output (jsfiddle demo).
Bugs affecting IE 10 and 11:
flex shorthand declarations with unitless flex-basis values are ignored
flex-basis doesn't account for box-sizing: border-box
flex-basis doesn't support calc()
Importance is ignored on flex-basis when using flex shorthand
In addition to Michael_B's excellent summary it's worth repeating this:
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.
The important part here is initial.
By itself, this does resolve to width/height until the other flex grow/shrink properties come into play.
So. a child with
.child {
flex-basis:25%;
flex-grow:1;
}
will be 25% wide initially but then immediately expand as much as it can until the other elements are factored in. If there are none..it will be 100% wide/tall.
A quick demo:
.flex {
width: 80%;
margin: 1em auto;
height: 25px;
display: flex;
background: rebeccapurple;
}
.child {
flex-basis: auto;
/* default */
background: plum;
}
.value {
flex-basis: 25%;
}
.grow {
flex-grow: 1;
}
<div class="flex">
<div class="child auto">Some Content</div>
</div>
<div class="flex">
<div class="child value">Some Content</div>
</div>
<div class="flex">
<div class="child grow">Some Content</div>
</div>
Experimenting with the flex-grow, flex-shrink and flex-basis
(or the shorthand flex :fg fs fb)...can lead to some interesting results.
Nobody seems to mention that there is one key difference between flex-basis and width (or height, depending on the current writing mode), if we ignore the flexible sizing aspect (flex-grow: 0; flex-shrink: 0;).
It originates from the exception in Flex Layout, that the automatic minimum size for flex items defaults to min-content instead of zero, like usually. In other words, the default min-width: auto computes to min-content instead of 0.
The result is, that flex-basis is (by default) bound below by min-content. If you specify a value smaller than min-content, for example flex-basis: 0, it will compute to min-content. This essentially means that (by default) you can't make the box's content overflow, since the box has at least the size of the content.
This is a key difference to width, which can size the box arbitrarily small (by default), since min-width defaults to 0. If the value of width is smaller than min-content, the contents will overflow the box.
This behavior is mentioned in the spec, but only implicitly in the following comment at the wrong place at the end of 7.1.1. Basic Values of flex.
By default, flex items won’t shrink below their minimum content size (the length of the longest word or fixed-size element). To change this, set the min-width or min-height property. (See § 4.5 Automatic Minimum Size of Flex Items.)
As mentioned in the comment, setting a minimum size lowers the bound, and setting it to zero effectively disables it, making flex-basis behave again as expected.
But there are drawbacks. Firstly, there is no minimum size property for the main axis. You have to use the correct min-width/min-height or min-block-size/min-inline-size property for the current flex-direction. If you changed the flex-direction, you would need to again find the correct minimum size property.
Secondly, flex-basis can't be used anymore to distribute space towards proportionally sized boxes instead of simply adding to their initial size. For more details, see Figure 7 in the spec.
Here is a minimal example. Set min-width: 0 to make flex-basis behave as expected again.
.container {
display: flex;
}
.container div {
background-color: lightgrey;
border: 1px solid black;
margin: 0 10px;
/* disable any flexible sizing */
flex-grow: 0;
flex-shrink: 0;
/* TOGGLE ME */
/* min-width: 0; */
}
.mincontent {
width: min-content;
}
.smallerflexbasis {
flex-basis: 3ex;
}
.smallerwidth {
width: 3ex;
}
<div class="container">
<div class="mincontent">Lorem ipsum</div>
<div class="smallerflexbasis">Lorem ipsum</div>
<div class="smallerwidth">Lorem ipsum</div>
</div>
Possibly the most important point to add:
What if the browser doesn't support flex? In such a case, width/height take over and their values apply.
It is a very good idea - almost essential - to define width/height on elements, even if you then have a completely different value for flex-basis. Remember to test by disabling display:flex and seeing what you get.
It makes a difference if you're wrapping.
Say, you set a child to width:0 and expect it to wrap, well that's not going to happen. But with flex-basis:0 it will wrap. (provided overflow isn't hidden)
if you set a div's min-width:600px, if the window size goes under 600px, you will see a horizontal scrollbar which is not a good ux design.
If you set its flex-basis:600px, if the window size goes under 600px, that box will shrink and you will not see a horizontal bar.
Note that flex-basis applies only to the flex items.

Resources