What exactly flex-basis property sets?
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 obeyflex-basis
.1
: Stretch.≥2
(integer n): Stretch. Will be n times the size of other elements withflex-grow: 1
on the same row, for example.
What are the differences between flex-basis and width?
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 ignoreflex-basis
but can usewidth
andheight
.flex-basis
works only on the main axis. For example, if you're inflex-direction: column
, thewidth
property would be needed for sizing flex items horizontally.flex-basis
has no effect on absolutely-positioned flex items.width
andheight
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
andflex-basis
– can be neatly combined into one declaration. Usingwidth
, 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
propertyFor all values other than
auto
andcontent
,flex-basis
is resolved the same way aswidth
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 usedflex-basis
. If that value is
itselfauto
, then the used value iscontent
.
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 usingauto
together with a
main size (width
orheight
) ofauto
.
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 horizontallyjustify-content: flex-start
- flex items will stack at the start of the line on the main axisalign-items: stretch
- flex items will expand to cover the cross-size of the containerflex-wrap: nowrap
- flex items are forced to stay in a single lineflex-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
FlexibilityAuthors 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 unitlessflex-basis
values are ignoredflex-basis
doesn't account forbox-sizing: border-box
flex-basis
doesn't supportcalc()
- Importance is ignored on
flex-basis
when usingflex
shorthand
What does auto and content value of flex-basis do
The only difference in the behavior of those two values is what they do when the width
property is defined for the element.
flex-basis: content
The "content" value will just set the width according to the element's content. It doesn't matter if you've defined a width for the element through the width
property, it would be ignored.
ul {
display: flex;
list-style-type: none;
}
ul li {
background-color: green;
margin: 5px;
width: 100px;
flex-basis: content;
}
<html>
<body>
<ul>
<li>Element</li>
<li>Element</li>
<li>Element</li>
</ul>
</body>
</html>
What is this flex styling is doing in plain English?
The first value is the flex grow which is practically the size of the particular flex item relative to other flex items so if you give it a value of 2 the width will be two times the width of the remaining flex items. That is to say a flex grow of two where the width of a normal flex item is 20px will make that item 40px in size. The second value flex shrink does the opposite.
The third flex-basis means that that flex item will not go beyond that size it's more like min-width in flex box context. #cheers
How flexbox calculates flex-item's width if no flex-basis or width are set?
For this particular case you need to conisder the default shrink effect set by flex-shrink
which has a default value of 1
. Initially your element will overflow like below:
$('div').each(function() {
console.log($(this).width());
})
.container {
display: flex;
width: 600px;
}
.container div {
outline: 1px dotted black;
flex-shrink:0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit! 123456789</div>
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!</div>
</div>
Related Topics
How to Make CSS A:Active Work After the Click
Zebra Striping a Table with Hidden Rows Using CSS3
Word-Wrap:Break-Word Not Working in IE8
CSS Display: Table Min-Height Not Working
Build List of Selectors with Less
Bootstrap 4 Navbar and Content Fill Height Flexbox
How to Prevent CSS Gradient Banding
CSS "Outline" Different Behavior Behavior on Webkit & Gecko
Specifying Style and Weight for Google Fonts
Differencebetween Outline and Border CSS Properties
How to Apply Styles to Multiple Classes at Once
Chrome Renders Colours Differently from Safari and Firefox
Add Ellipses to Overflowing Text in Svg
How to Style Menu Button and Menu Items
Fill Only Half a Star with Svg
Prevent Children from Inheriting Transformation CSS3
What's the Difference Between HTML[Lang="En"] and HTML:Lang(En) in CSS