Flexible box model - display : flex, box, flexbox?
You use whichever ones you need for the browsers you need to support.
display: box
- Firefox 2.0? (prefixed)
- Chrome 4.0? (prefixed)
- Safari/iOS 3.1? (prefixed)
- Android 2.1 (prefixed)
As far as I can tell, wrapping via box-lines: multiple
is not implemented in any browser.
display: flexbox
- Chrome 17-?? (prefixed)
- Internet Explorer 10 (prefixed)
display: flex - the current standard
- Chrome 21 (prefixed), 29 (unprefixed)
- Opera 12.1 (unprefixed), 15 (webkit prefix)
- Firefox 22 (unprefixed)
- Safari/iOS 7 (prefixed)
- Blackberry 10 (prefixed)
- Internet Explorer 11 (unprefixed)
http://caniuse.com/#feat=flexbox (Note that IE10 is the only browser marked as having partial support that supports wrapping)
The specs for flexbox
and flex
are similar enough there's no reason not to include both, especially since IE10 only supports the flexbox
spec. The spec for box
is very different and might not be worth including depending on the effect you're after, even though nearly all properties have an analog to the ones found in the flexbox
/flex
specs.
You may find that there are some browsers that support multiple specs. There will likely come a time where they will drop support for the older spec, so always make sure you include the flex
properties.
CSS3 Flexbox: display: box vs. flexbox vs. flex
These are different styles.display: box;
is a version of 2009.display: flexbox;
is a version of 2011.display: flex;
is the actual version.
Quote of Paul Irish
Warning: Flexbox has undergone some major revisions, so this article
is out of date. In summary, the old standard (Flexbox 2009), which
this article is based on, was implemented in Chrome since v4, Firefox
since v2, and IE10 beta.Since then, the new flexbox standard debuted and started to debut in
Chrome 17. Stephan Hay has written a guide on the new flexbox
implementation. Since then, the spec underwent naming changes which
started landing in Chrome 21. Chrome 22 has a stable implementation of
the latest spec.At this point, implementing either has its risks, so be aware.
Here is the blog about the different flexbox statements.
This is a blog entry by css-tricks about the different versions.
When i use flexbox, i always write it like that:
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
Edit:
Still not everyone has a browser/device capable of viewing flexbox layouts. So for fallback solutions or alternatives there is this article by Kenan Yusuf on how to use flexbox without using flexbox.
Flexible box layout model: How should auto margins in the cross-axis direction behave?
The Firefox/Gecko behavior is correct.
WebKit is stretching up to 400px (the max-width) due to the header element's default "align-self: stretch" value. However, the spec is clear that "align-self: stretch" is only supposed to stretch if you have no auto margins in the cross axis. Quoting the spec:
If a flex item has ‘align-self: stretch’, [...] and neither of its
cross-axis margins are ‘auto’, the used outer cross size is the used
cross size of its flex line, clamped according to the item's min and
max cross size properties
http://www.w3.org/TR/css3-flexbox/#cross-sizing
The exception for "neither of its cross-axis margins are auto" is what Firefox is honoring here and WebKit/Blink appear to be ignoring.
Now, to achieve your desired layout: It looks like you want both stretchiness and centering, and I don't think you can get both of those things simultaneously in the cross axis.
You can get them simultaneously in the main axis of a flex container, though -- so you can fix this by adding a horizontal flex container around the header and the footer.
I've done that here:
http://jsfiddle.net/4Rv7K/16/
The relevant code (just with the 'header' for simplicity):
body {
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
}
horizFlex {
display: -webkit-flex;
display: flex;
}
header {
-webkit-flex: 1 0 auto;
flex: 1 0 auto;
max-width: 400px;
height: 20px;
background-color: yellow;
margin: 0 auto;
}
[...]
<body><horizFlex><header>Header</header></horizFlex></body>
I think this achieves the layout you're looking for by wrapping the header and footer each in a horizontal flex container. The flex container stretches to the width of its parent (the body), and inside of it we have a single flex item (e.g. the ), which is flexible up to its max-width, and which we center (with auto margins) once it has reached its max-width.
Better way to set distance between flexbox items
- Flexbox doesn't have collapsing margins.
- Flexbox doesn't have anything akin to
border-spacing
for tables (edit: CSS propertygap
fulfills this role in newer browsers, Can I use)
Therefore achieving what you are asking for is a bit more difficult.
In my experience, the "cleanest" way that doesn't use :first-child
/:last-child
and works without any modification on flex-wrap:wrap
is to set padding:5px
on the container and margin:5px
on the children. That will produce a 10px
gap between each child and between each child and their parent.
Demo
.upper {
margin: 30px;
display: flex;
flex-direction: row;
width: 300px;
height: 80px;
border: 1px red solid;
padding: 5px; /* this */
}
.upper > div {
flex: 1 1 auto;
border: 1px red solid;
text-align: center;
margin: 5px; /* and that, will result in a 10px gap */
}
.upper.mc /* multicol test */ {
flex-direction: column;
flex-wrap: wrap;
width: 200px;
height: 200px;
}
<div class="upper">
<div>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa<br/>aaa</div>
<div>aaa<br/>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa</div>
</div>
<div class="upper mc">
<div>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa<br/>aaa</div>
<div>aaa<br/>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa</div>
</div>
Flexible box model explanation
As suggested by @cimmanon in the comments, the w3 specification explains it much better: http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#flex:
In short:
flex-basis specifies the initial main size of the flex item, before free space is distributed according to the flex factors.
flex-grow controls the distribution of positive free space (when the size of the container is bigger than the size required to display the flex items)
flex-shrink controls the distribution of negative space (when the container dimension is less than the size required to display the items)
Align multiple elements with flex
Switch to flex-direction: column
.
Add flex-wrap: wrap
.
Define a height for the container (so the flex items know where to wrap).
Box #1 will consume all space in the first column, forcing the following boxes to wrap to a new column.
No changes to the HTML.
.wrap { display: flex; flex-wrap: wrap; flex-direction: column; /* NEW */ height: 100px; /* NEW */ justify-content: space-between; /* NEW */}.elem1 { width: 20%; flex-basis: 100%; /* NEW */ border: 1px solid red;}.elem2,.elem3 { width: 75%; flex-basis: 40%; /* NEW */ border: 1px solid red;}
<div class="wrap"> <div class="elem1">1</div> <div class="elem2">2</div> <div class="elem3">3</div></div>
What's the difference between display:inline-flex and display:flex?
display: inline-flex
does not make flex items display inline. It makes the flex container display inline. That is the only difference between display: inline-flex
and display: flex
. A similar comparison can be made between display: inline-block
and display: block
, and pretty much any other display type that has an inline counterpart.1
There is absolutely no difference in the effect on flex items; flex layout is identical whether the flex container is block-level or inline-level. In particular, the flex items themselves always behave like block-level boxes (although they do have some properties of inline-blocks). You cannot display flex items inline; otherwise you don't actually have a flex layout.
It is not clear what exactly you mean by "vertically align" or why exactly you want to display the contents inline, but I suspect that flexbox is not the right tool for whatever you are trying to accomplish. Chances are what you're looking for is just plain old inline layout (display: inline
and/or display: inline-block
), for which flexbox is not a replacement; flexbox is not the universal layout solution that everyone claims it is (I'm stating this because the misconception is probably why you're considering flexbox in the first place).
1 The differences between block layout and inline layout are outside the scope of this question, but the one that stands out the most is auto width: block-level boxes stretch horizontally to fill their containing block, whereas inline-level boxes shrink to fit their contents. In fact, it is for this reason alone you will almost never use display: inline-flex
unless you have a very good reason to display your flex container inline.
Flexible Box Layout in Opera
There's a known bug in Blink (used by Chrome and Opera) regarding flex items that are "stretch-aligned" (like in your test).
https://code.google.com/p/chromium/issues/detail?id=341310
Your test is valid, and the spec is very clear on this:
http://www.w3.org/TR/css3-flexbox/#algo-stretch
You should however consider inserting a <!DOCTYPE html> line at the top, so that browsers don't enter quirks mode. Blink fails differently with your test, depending on quirks mode or not. :)
Related Topics
Property: 0' or 'Property: 0Px' in CSS
Maintain Div Aspect Ratio According to Height
How to Use Template Literals in Tailwindcss to Change Classes Dynamically
Background Image, Linear Gradient Jagged Edged Result Needs to Be Smooth Edged
<Input> Doesn't Inherit the Font from <Body>
Bootstrap 4 Change Breakpoints
Segments in a Circle Using CSS3
Bootstrap Dropdowns Menus Appearing Behind Other Elements - IE7
Scrollable Menu with Bootstrap - Menu Expanding Its Container When It Should Not
CSS Endless Rotation Animation
Changing the Width of Bootstrap Popover
Css3 Transition - Fade Out Effect
Stylesheet Not Updating When I Refresh My Site