Flexible Box Model - Display:Flex, Box, Flexbox

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 property gap 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



Leave a reply



Submit