Flexible box layout (or flexbox) is a new box model
 optimized for UI layout. As one of the first CSS modules designed for 
actual layout (floats were really meant mostly for things such as 
wrapping text around images), it makes a lot of tasks much easier,
 or even possible at all. Flexbox’s repertoire includes the simple 
centering of elements (both horizontally and vertically), the expansion 
and contraction of elements to fill available space, and source-code 
independent layout, among others abilities.
Flexbox has lived a storied existence. It started as a feature of Mozilla’s XUL, where it was used to lay out application UI, such as the toolbars in Firefox, and it has since been rewritten multiple times. The specification has only recently reached stability, and we have fairly complete support across the latest versions of the leading browsers.
There are, however, some caveats. The specification changed between the implementation in Internet Explorer (IE) and the release of IE 10, so you will need to use a slightly different syntax. Chrome currently still requires the
When you specify that an element will use the flexbox model, its children are laid out along either the horizontal or vertical axis, depending on the direction specified. The widths of these children expand or contract to fill the available space, based on the flexible length they are assigned.
This is not exactly all of the CSS needed for our example, because I’ve stripped out the extra styling that you probably already know how to use in order to save space.
Let’s look at the CSS that is needed to center the heading on the page. First, we set the
The syntax used by IE 10 is
What do we gain now that our elements have been to yoga class and become all flexible? They gain untold powers: they can flex their size and position relative to the available space; they can be laid out either horizontally or vertically; and they can even achieve source-order independence. (Two holy grails in one specification? We’re doing well.)
To explicitly set the axis that the element is aligned along, you can do this with the
There are some differences here in the various versions of the specification, which are highlighted at the end of this article. Another caveat to bear in mind is that

Simple horizontal and vertical centering using flexbox. Larger view.
You might notice that the text is also center-aligned vertically inside the

An interactive slideshow built using flexbox. Larger view.
The HTML and CSS for this example are similar to the previous one’s. We’re enabling flexbox and centering the elements on the page in the same way. In addition, we want to make the title (inside the
In this example, we’ve set a consistent height, but this could be set to be flexible, too, in exactly the same way. We probably wouldn’t always want all elements to be the same size, so let’s make one bigger. On hover, we’ve set the element to take up 2 flex units:

An interactive slideshow with
To make our chosen element move to the first position, we just have to set a lower number. I chose
This relays accessibility hints to the underlying system and to assistive technology to tell the user that that element is pressed and, thus, active. If you’d like more information on WAI-ARIA, check out “Introduction to WAI-ARIA” by Gez Lemon. Because I’m adding the attribute after the user clicks, this example requires a simple JavaScript file in order to work, but flexbox itself doesn’t require it; it’s just there to handle the user interaction.
Hopefully, this has given you some inspiration and enough introductory knowledge of flexbox to enable you to experiment with your own designs.
* Opera will soon switch to WebKit. It will then require the 
This takes effect only when there are multiple flex lines, which is the case when flex items are allowed to wrap using the 
The flex property is more or less unchanged between the new standard 
and the draft supported by Microsoft. The main difference is that it has
 been converted to a shorthand in the new version, with separate 
properties: 
In the old version of the specification, the 
When setting the
The old version of the specification also has writing mode-independent values for
The 
At the time of writing, Firefox does not support the
The current specification has a
While some browsers use an older syntax, Firefox looks like it is close to updating, and IE 11 uses the latest version in leaked Windows Blue builds. There is currently no word on Safari, but it is a no-brainer considering that Chrome had the latest syntax before the Blink-WebKit split. For the time being, use the tables above to map the various syntaxes, and get your flex on.
Layout in CSS is only getting more powerful, and flexbox is one of the first steps out of the quagmire we’ve found ourselves in over the years, first with table-based layouts, then float-based layouts. IE 10 already supports an early draft of the Grid layout specification, which is great for page layout, and Regions and Exclusions will revolutionize how we handle content flow and layout.
Flexbox can be used today if you only need to support relatively modern browsers or can provide a fallback, and in the not too distant future, all sorts of options will be available, so that we can use the best tool for the job. Flexbox is shaping up to be a mighty fine tool.
Flexbox has lived a storied existence. It started as a feature of Mozilla’s XUL, where it was used to lay out application UI, such as the toolbars in Firefox, and it has since been rewritten multiple times. The specification has only recently reached stability, and we have fairly complete support across the latest versions of the leading browsers.
There are, however, some caveats. The specification changed between the implementation in Internet Explorer (IE) and the release of IE 10, so you will need to use a slightly different syntax. Chrome currently still requires the
-webkit- prefix, and Firefox and Safari 
are still on the much older syntax. Firefox has updated to the latest 
specification, but that implementation is currently behind a runtime 
flag until it is considered stable and bug-free enough to be turned on 
by default. Until then, Firefox still requires the old syntax.When you specify that an element will use the flexbox model, its children are laid out along either the horizontal or vertical axis, depending on the direction specified. The widths of these children expand or contract to fill the available space, based on the flexible length they are assigned.
Example: Horizontal And Vertical Centering (Or The Holy Grail Of Web Design)
Being able to center an element on the page is perhaps the number one wish among Web designers — yes, probably even higher than gaining the highly prized parent selector or putting IE 6 out of its misery (OK, maybe a close second then). With flexbox, this is trivially easy. Let’s start with a basic HTML template, with a heading that we want to center. Eventually, once we’ve added all the styling, it will end up looking like this vertically and horizontally centered demo.<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="utf-8"/>
   <title>Centering an Element on the Page</title>
</head>
<body>
   <h1>OMG, I’m centered</h1>
</body>
</html>
Nothing special here, not even a wrapper div. The magic all happens in the CSS:html {
   height: 100%;
} 
body {
   display: -webkit-box;   /* OLD: Safari,  iOS, Android browser, older WebKit browsers.  */
   display: -moz-box;      /* OLD: Firefox (buggy) */ 
   display: -ms-flexbox;   /* MID: IE 10 */
   display: -webkit-flex;  /* NEW, Chrome 21+ */
   display: flex;          /* NEW: Opera 12.1, Firefox 22+ */
   -webkit-box-align: center; -moz-box-align: center; /* OLD… */
   -ms-flex-align: center; /* You know the drill now… */
   -webkit-align-items: center;
   align-items: center;
   -webkit-box-pack: center; -moz-box-pack: center; 
   -ms-flex-pack: center; 
   -webkit-justify-content: center;
   justify-content: center;
   margin: 0;
   height: 100%;
   width: 100% /* needed for Firefox */
} 
h1 {
   display: -webkit-box; display: -moz-box;
   display: -ms-flexbox;
   display: -webkit-flex;
   display: flex;
 
   -webkit-box-align: center; -moz-box-align: center;
   -ms-flex-align: center;
   -webkit-align-items: center;
   align-items: center;
   height: 10rem;
}
I’ve included all of the different prefixed versions in the CSS above,
 from the very oldest, which is still needed, to the modern and 
hopefully final syntax. This might look confusing, but the different 
syntaxes map fairly well to each other, and I’ve included tables at the 
end of this article to show the exact mappings.This is not exactly all of the CSS needed for our example, because I’ve stripped out the extra styling that you probably already know how to use in order to save space.
Let’s look at the CSS that is needed to center the heading on the page. First, we set the
html and body elements to have 100% height and remove any margins. This will make the container of our h1 take up the full height of the browser’s window. Firefox also needs a width specified on the body to force it to behave. Now, we just need to center everything.Enabling Flexbox
Because thebody element contains the heading that we want to center, we will set its display value to flex:body {
   display: flex;
}
This switches the body element to use the flexbox 
layout, rather than the regular block layout. All of its children in the
 flow of the document (i.e. not absolutely positioned elements) will now
 become flex items.The syntax used by IE 10 is
display: -ms-flexbox, while older Firefox and WebKit browsers use display: -prefix-box (where prefix is either moz or webkit). You can see the tables at the end of this article to see the mappings of the various versions.What do we gain now that our elements have been to yoga class and become all flexible? They gain untold powers: they can flex their size and position relative to the available space; they can be laid out either horizontally or vertically; and they can even achieve source-order independence. (Two holy grails in one specification? We’re doing well.)
Centering Horizontally
Next, we want to horizontally center ourh1 element. No big deal, you might say; but it is somewhat easier than playing around with auto margins. We just need to tell the flexbox to center its flex items. By default, flex items are laid out horizontally, so setting the justify-content property will align the items along the main axis:body {
   display: flex;
   justify-content: center;
}
For IE 10, the property is called flex-pack, while for older browsers it is box-pack (again, with the appropriate prefixes). The other possible values are flex-start, flex-end, space-between and space-around. These are start, end, justify and distribute, respectively, in IE 10 and the old specification (distribute is, however, not supported in the old specification). The flex-start value aligns to the left (or to the right with right-to-left text), flex-end aligns to the right, space-between evenly distributes the elements along the axis, and space-around evenly distributes along the axis, with half-sized spaces at the start and end of the line.To explicitly set the axis that the element is aligned along, you can do this with the
flex-flow property. The default is row, which will give us the same result that we’ve just achieved. To align along the vertical axis, we can use flex-flow: column.
 If we add this to our example, you will notice that the element is 
vertically centered but loses the horizontal centering. Reversing the 
order by appending -reverse to the row or column values is also possible (flex-flow: row-reverse or flex-flow: column-reverse), but that won’t do much in our example because we have only one item.There are some differences here in the various versions of the specification, which are highlighted at the end of this article. Another caveat to bear in mind is that
flex-flow directions are writing-mode sensitive. That is, when using writing-mode: vertical-rl to switch to vertical text layout (as used traditionally in China, Japan and Korea), flex-flow: row will align the items vertically, and column will align them horizontally.Centering Vertically
Centering vertically is as easy as centering horizontally. We just need to use the appropriate property to align along the “cross-axis.” The what? The cross-axis is basically the axis perpendicular to the main one. So, if flex items are aligned horizontally, then the cross-axis would be vertical, and vice versa. We set this with thealign-items property (flex-align in IE 10, and box-align for older browsers):body {
   /* Remember to use the other versions for IE 10 and older browsers! */
   display: flex;
   justify-content: center;
   align-items: center;
}
This is all there is to centering elements with flexbox! We can also use the flex-start (start) and flex-end (end) values, as well as baseline and stretch. Let’s have another look at the finished example:Simple horizontal and vertical centering using flexbox. Larger view.
You might notice that the text is also center-aligned vertically inside the
h1
 element. This could have been done with margins or a line height, but 
we used flexbox again to show that it works with anonymous boxes (in 
this case, the line of text inside the h1 element). No matter how high the h1 element gets, the text will always be in the center:h1 {
   /* Remember to use the other versions for IE 10 and older browsers! */
   display: flex;
   align-items: center;
   height: 10rem;
}
Flexible Sizes
If centering elements was all flexbox could do, it’d be pretty darn cool. But there is more. Let’s see how flex items can expand and contract to fit the available space within a flexbox element. Point your browser to this next example.An interactive slideshow built using flexbox. Larger view.
The HTML and CSS for this example are similar to the previous one’s. We’re enabling flexbox and centering the elements on the page in the same way. In addition, we want to make the title (inside the
header element) remain consistent in size, while the five boxes (the section elements) adjust in size to fill the width of the window. To do this, we use the new flex property:section {
   /* removed other styles to save space */
   -prefix-box-flex: 1; /* old spec webkit, moz */
   flex: 1;
   height: 250px;
}
What we’ve just done here is to make each section element take up 1 
flex unit. Because we haven’t set any explicit width, each of the five 
boxes will be the same width. The header element will take up a set width (277 pixels) because it is not flexible. We divide the remaining width inside the body
 element by 5 to calculate the width of each of the section elements. 
Now, if we resize the browser window, the section elements will grow or 
shrink.In this example, we’ve set a consistent height, but this could be set to be flexible, too, in exactly the same way. We probably wouldn’t always want all elements to be the same size, so let’s make one bigger. On hover, we’ve set the element to take up 2 flex units:
section:hover {
   -prefix-box-flex: 2;
   flex: 2;
   cursor: pointer;
}
Now the available space is divided by 6 rather than 5, and the 
hovered element gets twice the base amount. Note that an element with 2 
flex units does not necessarily become twice as wide as one with 1 unit.
 It just gets twice the share of the available space added to its 
“preferred width.” In our examples, the “preferred width” is 0 (the 
default).Source-Order Independence
For our last party trick, we’ll study how to achieve source-order independence in our layouts. When clicking on a box, we will tell that element to move to the left of all the other boxes, directly after the title. All we have to do is set the order with theorder 
property. By default, all flex items are in the 0 position. Because 
they’re in the same position, they follow the source order. Click on your favorite person in the updated example to see their order change.An interactive slideshow with
flex-order. Larger view.To make our chosen element move to the first position, we just have to set a lower number. I chose
-1. We also need to set the header to -1 so that the selected section element doesn’t get moved before it:header {
   -prefix-box-ordinal-group: 1; /* old spec; must be positive */
   -ms-flex-order: -1; /* IE 10 syntax */
   order: -1; /* new syntax */
} 
section[aria-pressed="true"] {
   /* Set order lower than 0 so it moves before other section elements,
      except old spec, where it must be positive.
 */
   -prefix-box-ordinal-group: 1;
   -ms-flex-order: -1;
   order: -1;
   -prefix-box-flex: 3;
   flex: 3;
   max-width: 370px; /* Stops it from getting too wide. */
}
In the old specification, the property for setting the order (box-ordinal-group) accepts only a positive integer. Therefore, I’ve set the order to 2 for each section element (code not shown) and updated it to 1 for the active element. If you are wondering what  aria-pressed="true"
 means in the example above, it is a WAI-ARIA attribute/value that I add
 via JavaScript when the user clicks on one of the sections.This relays accessibility hints to the underlying system and to assistive technology to tell the user that that element is pressed and, thus, active. If you’d like more information on WAI-ARIA, check out “Introduction to WAI-ARIA” by Gez Lemon. Because I’m adding the attribute after the user clicks, this example requires a simple JavaScript file in order to work, but flexbox itself doesn’t require it; it’s just there to handle the user interaction.
Hopefully, this has given you some inspiration and enough introductory knowledge of flexbox to enable you to experiment with your own designs.
Syntax Changes
As you will have noticed throughout this article, the syntax has changed a number of times since it was first implemented. To aid backward- and forward-porting between the different versions, we’ve included tables below, which map the changes between the specifications.| Speci- fication  | 
IE | Opera | Firefox | Chrome | Safari | 
| Standard | 11? | 12.10+ * | Behind flag | 21+ (-webkit-) | 
|
| Mid | 10 (-ms-) | 
||||
| Old | 3+ (-moz-) | 
<21 (-webkit-) | 
3+ (-webkit-) | 
-webkit- prefix if it has not been dropped by that time.| Speci- fication  | 
Property name | Block-level flex | Inline-level flex | 
| Standard | display | 
flex | 
inline-flex | 
| Mid | display | 
flexbox | 
inline-flexbox | 
| Old | display | 
box | 
inline-box | 
| Speci- fication  | 
Property name | start | center | end | justify | distribute | 
| Standard | justify-content | 
flex-start | 
center | 
flex-end | 
space-between | 
space-around | 
| Mid | flex-pack | 
start | 
center | 
end | 
justify | 
distribute | 
| Old | box-pack | 
start | 
center | 
end | 
justify | 
N/A | 
| Speci- fication  | 
Property name | start | center | end | baseline | stretch | 
| Standard | align-items | 
flex-start | 
center | 
flex-end | 
baseline | 
stretch | 
| Mid | flex-align | 
start | 
center | 
end | 
baseline | 
stretch | 
| Old | box-align | 
start | 
center | 
end | 
baseline | 
stretch | 
| Speci- fication  | 
Property name | auto | start | center | end | baseline | stretch | 
| Standard | align-self | 
auto | 
flex-start | 
center | 
flex-end | 
baseline | 
stretch | 
| Mid | flex-item-align | 
auto | 
start | 
center | 
end | 
baseline | 
stretch | 
| Old | N/A | ||||||
| Speci- fication  | 
Property name | start | center | end | justify | distribute | stretch | 
| Standard | align-content | 
flex-start | 
center | 
flex-end | 
space-between | 
space-around | 
stretch | 
| Mid | flex-line-pack | 
start | 
center | 
end | 
justify | 
distribute | 
stretch | 
| Old | N/A | ||||||
flex-wrap
 property and there isn’t enough space for all flex items to display on 
one line. This will align each line, rather than each item.| Speci- fication  | 
Property name | Value | 
| Standard | order | 
|
| Mid | flex-order | 
<number> | 
| Old | box-ordinal-group | 
<integer> | 
| Speci- fication  | 
Property name | Value | 
| Standard | flex | 
none | [ <flex-grow> <flex-shrink>? || <flex-basis>] | 
| Mid | flex | 
none | [ [ <pos-flex> <neg-flex>? ] || <preferred-size> ] | 
| Old | box-flex | 
<number> | 
flex-grow, flex-shrink and flex-basis. The values may be used in the same way in the shorthand. However, the default value for flex-shrink (previously called negative flex) is now 1. This means that items do not shrink by default. Previously, negative free space would be distributed using the flex-shrink ratio, but now it is distributed in proportion to flex-basis multiplied by the flex-shrink ratio.| Speci- fication  | 
Property name | Horizontal | Reversed horizontal | Vertical | Reversed vertical | 
| Standard | flex-direction | 
row | 
row-reverse | 
column | 
column-reverse | 
| Mid | flex-direction | 
row | 
row-reverse | 
column | 
column-reverse | 
| Old | box-orientbox-direction | 
horizontalnormal | 
horizontalreverse | 
verticalnormal | 
verticalreverse | 
box-direction property needs to be set to reverse to get the same behavior as row-reverse or column-reverse in the later version of the specification. This can be omitted if you want the same behavior as row or column because normal is the initial value.When setting the
direction to reverse, the 
main flexbox axis is flipped. This means that when using a left-to-right
 writing system, the items will display from right to left when row-reverse is specified. Similarly, column-reverse will lay out flex items from bottom to top, instead of top to bottom.The old version of the specification also has writing mode-independent values for
box-orient. When using a left-to-write writing system, horizontal may be substituted for inline-axis, and vertical may be substituted for block-axis. If you are using a top-to-bottom writing system, such as those traditional in East Asia, then these values would be flipped.| Speci- fication  | 
Property name | No wrapping | Wrapping | Reversed wrap | 
| Standard | flex-wrap | 
nowrap | 
wrap | 
wrap-reverse | 
| Mid | flex-wrap | 
nowrap | 
wrap | 
wrap-reverse | 
| Old | box-lines | 
single | 
multiple | 
N/A | 
wrap-reverse value flips the start and end of the 
cross-axis, so that if flex items are laid out horizontally, instead of 
items wrapping onto a new line below, they will wrap onto a new line 
above.At the time of writing, Firefox does not support the
flex-wrap or older box-lines property. It also doesn’t support the shorthand.The current specification has a
flex-flow shorthand, 
which controls both wrapping and direction. The behavior is the same as 
the one in the version of the specification implemented by IE 10. It is 
also currently not supported by Firefox, so I would recommend to avoid 
using it when specifying only the flex-direction value.Conclusion
Well, that’s a (flex-)wrap. In this article, I’ve introduced some of the myriad of possibilities afforded by flexbox. Be it source-order independence, flexible sizing or just the humble centering of elements, I’m sure you can find ways to employ flexbox in your websites and applications. The syntax has settled down (finally!), and implementations are here. All major browsers now support flexbox in at least their latest versions.While some browsers use an older syntax, Firefox looks like it is close to updating, and IE 11 uses the latest version in leaked Windows Blue builds. There is currently no word on Safari, but it is a no-brainer considering that Chrome had the latest syntax before the Blink-WebKit split. For the time being, use the tables above to map the various syntaxes, and get your flex on.
Layout in CSS is only getting more powerful, and flexbox is one of the first steps out of the quagmire we’ve found ourselves in over the years, first with table-based layouts, then float-based layouts. IE 10 already supports an early draft of the Grid layout specification, which is great for page layout, and Regions and Exclusions will revolutionize how we handle content flow and layout.
Flexbox can be used today if you only need to support relatively modern browsers or can provide a fallback, and in the not too distant future, all sorts of options will be available, so that we can use the best tool for the job. Flexbox is shaping up to be a mighty fine tool.
Further Reading
- “CSS Flexible Box Layout Module” (specification), W3C
 - “Flexible Box Layout Module,” Can I Use?
 - “Flexible box (‘Flexbox’) layout,” Microsoft
 - “Using CSS Flexible Boxes,” Mozilla
 - “‘Old’ Flexbox and ‘New’ Flexbox,” Chris Coyier
 
No comments:
Post a Comment