I wanted to like flexbox, I really did. I read Paul Irish’s Quick hits with flexible box layout and drooled. However, the lack of browser support at the time meant I couldn’t do anything more than bookmark the article for future reference.
Then I stumbled across Richard Herrera’s Flexie, a JavaScript library to enable flexbox support in bad browsers. It looked incredibly promising, and I resolved to use it the next chance I got.
Well, I got a chance recently to try a flexbox layout. For three frustrating days I struggled with inconsistent browser implementations and unexpected limitations. I watched with growing horror as what should have been a simple, elegant solution grew into a maintenance nightmare. And in the end, I kicked it to the curb.
What version of flexbox are you talking about?
It turns out that the flexbox spec has recently been rewritten. Unsure how to clarify which version I was complaining about, I asked Eric Meyer, who said he plans to call them Flexbox 2009 and Flexbox 2012.
Actually, what he said was “I plan to call them ‘Flexbox 2009′ and ‘Flexbox [fill in latest draft's release year here],’” but for the ease of discussion I’m going to assume the new spec will be finalized in 2012
So, for posterity’s sake, this article is referring to the old-and-busted Flexbox 2009. The new-hotness Flexbox 2012 spec looks to be mostly done, but of course hasn’t been implemented in any browsers yet. Hopefully, the new version will address these problems and make flexbox a viable option in the future.
Why did you want to use flexbox?
First and foremost, curiosity. It sounded promising, and I wanted to see if it would work. If it worked, I planned to use it to create a source-order independent layout without abusing floats and absolute positioning.
In the design, my layout went header > navigation > sidebar > content > footer, and I wanted my source to be header > content > sidebar > navigation > footer. (Here’s John Albin on why this is a good thing.)
I can already do this by using floats to reorder the sidebar and content columns, and absolute positioning for the navigation, but those techniques have shortcomings. Floats are fragile, and break page layout if the widths are wrong, plus they need additional markup for a 3-column layout. And absolute positioning works fine, but it requires that you know the height of your header and navigation elements.
I was working on a generic WordPress parent theme, so if I could use flexbox to solve these layout problems, I could make life much easier for anyone making a child theme.
Step One: Chrome
I do all my initial development in Chrome, and I’m pleased to say that flexbox was really easy to set up. Where normally I would write CSS like this:
#main {
width: 960px;
margin: 0 auto;
}
#content {
width: 600px;
padding: 15px;
float: right;
}
#sidebar {
width: 300px;
padding: 15px;
float: left;
}
With flexbox, I just modified it like this:
/* vendor prefixes left out for clarity */
#main {
width: 960px;
margin: 0 auto;
display: box;
box-orient: horizontal;
box-direction: reverse;
}
#content {
width: 600px;
padding: 15px;
}
#sidebar {
width: 300px;
padding: 15px;
}
That takes care of getting the sidebar and content columns to display in the correct order, now let’s put the navigation above the content. Here’s how I usually do it:
#page {
position: relative;
}
#header {
height: 200px;
padding-bottom: 25px;
}
#navigation {
height: 25px;
position: absolute;
top: 200px;
left: 0;
}
With flexbox, it’s like this:
/* vendor prefixes left out for clarity */
#page {
display: box;
box-orient: vertical;
}
#header {
box-ordinal-group: 1;
}
#main {
box-ordinal-group: 3;
}
#navigation {
box-ordinal-group: 2;
}
#footer {
box-ordinal-group: 4;
}
Here’s a demo using this flexbox layout.
After all that, my layout was working perfectly in Chrome and Safari.
Step Two: Firefox
Unfortunately, when I tested the layout in Firefox, it fell apart. Despite claiming to support flexbox, Firefox seems to have a broken implementation. The two problems I ran into right away were that the page wasn’t centered, and the content and sidebar columns were too narrow.
The centering failed because Firefox treats display:box as display:inline-block. Since my entire page was wrapped in the #page div — which I was applying display:box to — the margin:auto rule to center the page was being ignored. To get around this, I ended up adding a Firefox-only stylesheet that applied yet another flexbox layout, this time to center the #page div:
Additionally, I found that when I set body to display:box, I ran into problems with WordPress. The admin bar (which is normally fixed position) was stretching to cover the entire page. I was able to fix it by adding box-align:start, which prevented the admin bar from stretching. However, this solution makes me nervous, since this problem would affect any site with more than just the one element inside body. Flexbox will try to apply its layout to all immediate children of body.
/* these rules apply to Firefox only */
@-moz-document url-prefix() {
body {
width: 100%;
display : -moz-box;
display : box;
-moz-box-orient: horizontal;
box-orient: horizontal;
-moz-box-pack : center;
box-pack : center;
-moz-box-align: start;
box-align: start;
}
#content {
width: 630px;
}
#sidebar {
width: 330px;
}
}
The @-moz-document url-prefix() rule is a gecko-specific rule that makes sure the code inside the declaration is only seen by mozilla browsers.
You’ll notice I also overrode the width for the content and sidebar columns. That’s because Firefox changes the box model for children of flexbox items so that padding/border are included in the width. As a result, our normal widths end up being too narrow.
Firefox has other problems with flexbox as well. It completely ignores any width specified with percentages, and it has issues with overflow:hidden. None of these are unsolvable problems, but it means that you need to maintain an extra set of styles just for Firefox.
Step Three: Internet Explorer
IE10 is supposed to support flexbox, but none of the other versions do. To get around this, I added Flexie. The good news is that it worked perfectly. The flexbox layout was applied correctly, and everything looked hunky-dory. The bad news is that any IE users with JavaScript disabled will see a broken page layout.
To get around this, I would need write some fallback CSS to apply a non-flexbox layout. Then I would need to make sure it only gets added for non-JS users. But then I’m stuck supporting three sets of layout styles: one for Webkit, one for Firefox, and one for non-JS IE. Also, I could end up with a conflict if a user with a browser that supports flexbox disabled JavaScript. I’m not entirely sure what the best approach to take here would be, since this is when I gave up on flexbox.
Throwing in the towel
By the time I reached this point, I had been working on adding flexbox for three days. It was just about done, and with a few more tweaks, I probably could have made it work. But I couldn’t shake a nagging feeling that I was working way to hard to enable something that was supposed to make life easier. Is it really an improvement if I end up needing to maintain three sets of layout styles?
At the same time, I found out that the CSS working group had rewritten the flexbox spec. That means that even if I decided to finish the job and commit myself to Flexbox 2009, I would have to do it all over again in a year or two when the browsers implement Flexbox 2012.
The moral of the story is that the Flexbox 2009 spec is promising, but ultimately not worth the increased development and maintenance costs. I’m going to wait for Flexbox 2012, or one of the other competing CSS3 layout modules.
Eric A. Meyer
Not so. Flexbox 2009 and Flexbox 201x have completely different syntaxes, which means no collisions, and the 2009 version is unlikely to be dropped from browsers within the expected lifetime of a given design. So you can use 2009 (assuming you want to, and as you detailed, the barriers are not trivial) without worrying about having to redo anything, any more than people using floats for layout will have to redo things when real advanced layout comes to CSS.
Scott Vandehey
That’s a great point, Eric. Thanks. I hadn’t considered the lifespan of a typical design vs the lifespan of flexbox 2009 in the browsers.
That said, a large factor in wanting to use flexbox for me was getting a leg up on how things will be done in the future — and knowing that flexbox 2009 is a dead-end reduces that desirability quite a bit for me.
Jason Featheringham
Not to split hairs, but you should first and foremost use flexbox as you need it, not just to get a leg up. With that in mind, it won’t matter if 20xx supercedes 2009 or not. Then, it matters if it served your purpose at the time.
Peter Gasston
Yes, the current implementations of Flexbox are buggy. Firefox’s implementation was actually implemented *before* the spec was written: the original spec was based on their implementation, but the spec has changed since then and the implementation hasn’t.
I certainly wouldn’t use it for any client/ end-user sites as it stands, but it’s unfair to say that Flexbox sucks – it does what it’s supposed to do very well, when it’s fully implemented.
Scott Vandehey
I don’t think it’s unfair at all. The difference between broken and buggy are academic. Ultimately, it’s still a pain to get it working across browsers, and so it sucks.
karl
Note that in fact, NONE of the browsers you tried have broken implementations. They just have experimental implementations and that is exactly the purpose of -vendor- extension. It is there to test things, NOT to be used in production sites.
The big issue being that Web developers are willing to use things which are unstable and when it is breaking even if there is a kind of “I told you so”, they are angry ;)
Sincerely, I’m not sure how we can move forward with these vendor extensions. I was writing about these today.
Either people are forgetting half of them, or they left them for ever in their CSS.
Scott Vandehey
The spec isn’t finalized, and these are work-in-progress, and that’s why they use the vendor prefixes. I get all that — but when you contrast flexbox with other specs that are still vendor prefixed like box-shadow or even linear gradients, flexbox is definitely more of a pain. Just because the browsers have an excuse for the situation, doesn’t make the situation suck any less.
DC Crowley
I will agree with Scott Vandehay. I have tried it out and it does not quite do what it says it will. So CSS Template Layout Module which does not really work yet does look promising. That said Flexbox is possibly ‘the weapon of choice’ when laying out blocks and navigation regions on a page. So please don’t dump flexbox completely :)
Ric
I’m running Chrome 15 and the navigation appears at the bottom just above the footer.
Pingback: Bruce Lawson’s personal site : Reading List
T
I recently tried template layout (http://code.google.com/p/css-template-layout/) which was pretty simple to implement. However, it doesn’t work with any jquery after 1.4. I’m surprised no one has picked up development.
CC007
Of course flexbox isn’t fully supported, since it’s still in progress. Why would a browser write full support for a feature which will change in a few months, maybe even in a few days.
The flexbox layout will make life easier, but only once it’s finished and implemented in browsers. Yes, we don’t want to wait, but we have to. We know we tried to get to use it too fast, by looking at flexbox 2009. It doesn’t surprise me: it could be a very usefull layout structure and I really like to use it too.
We just have to wait and see…
Benxamin
While porting a legacy desktop app to mobile, and first step was to add modernizr to detect features I want to support.
I saw the modernizr “flexbox-legacy” class, did some research, and found that it refers to the “Flexbox 2009.” It was relatively easy to style that in Firefox (https://developer.mozilla.org/en/CSS/box-flex).
Then, went to Chrome for the latest “flexbox” and added those rules later in the stylesheet. The target elements were the same, so they cascaded perfectly (even as Chrome has both “flexbox” and “flexbox-legacy”).
The parent > child relationship being consistent between the two specs is essential for happy cascading. And I love that the syntaxes are different so it’s very apparent which is which.
Darren
Er, am I the only one to point out that the moral of the story is not to expect too much from working draft specs which have not been finished and have flaky implementations in current browsers? That’s what the selector prefixes are all about? Save your judgement until you try using a new CSS tool that’s complete and is supported fully and correctly by browsers? Oh, and if test driving a new concept car by some students – wear a helmet.
Brian
For others who may be confused by this article, release builds of Firefox have never implemented any version of the flexbox draft, but rather the draft was based on something implemented in Firefox about 10 years ago for XUL. The claim that Firefox’s “implementation” is buggy is bogus since it predates any draft.
That said, there is an implementation of the new draft in recent Firefox nightlies but it is disabled by a pref. Saying, “Firefox has problems with flexbox” is bogus since you’re not testing that implementation of the draft but something quite different.
Martin
I think it makes a lot more sense to call these different “flexbox” models the box- and the flex-model to avoid confusion. This is also how they are used with display: box (old model) and display: flex (new model).
Anyhow, very encouraging to see that there will be a reasonable way to create layouts in the near future (as I’ve heard but not tested the new model should also be implemented in IE10).