With IE11 supporting the CSS Flexible Box Layout Module (Flexbox), I couldn't wait to use Flexbox in production. A homepage redesign for a long-time client was a great opportunity to get to grips with Flexbox.
The homepage sported a fluid grid layout, easily Solved with Flexbox.
Then the grid items themselves were a lot like the well known Media Object: an image with some text. In this case the image was placed above the text instead of besides them. Easy peasy, right:
Resize your browser window and you'll notice that Chrome, Safari and Firefox will properly scale down the image. But, IE11 won't do that. Instead it will remain the original height and shrink down the width of the image, distorting your intrinsically sized image:
In another comment on the Modernizr issue, Greg Whitworth proposes a workaround for our intrinsically sized image:
"(...) placing elements with intrinsic aspect ratio inside of an item instead of making those elements the flex-items."
There we go:
That solves the problem only partially... While the image scales down nicely, the wrapping element doesn't:
This is also a known issue to the IE Team, but it isn't fixed yet, as far as I can tell.
Uncle Dave's Ol' Padded Box To The Rescue
I started poking around to find a workaround for the wrapper div. Remember Uncle Dave's Ol' Padded Box? This beautiful and simple technique can be adapted for our purposes. In our case the images had an aspect ratio of 16:9, so we could use that to our advantage.
By setting the height of the wrapping element to 0 and giving it a 16:9 padding-bottom we can make sure the wrapping element is as large as the image:
Looking good! Chrome, Safari and IE11 all scale down the wrapping element and the image nicely when resizing the window. But Firefox doesn't! Instead it doesn't account for the image at all:
I filed a bug for that.
Within a few hours, Daniel Holbert from Mozilla replied to the bug report, stating that Firefox is actually showing the correct behaviour and the other browsers get it wrong!
Percentage values for margin and padding are normally resolved to the width of the element (e.g. elements with display: block), but with flex items percentage values for margin and padding are resolved to the respective dimension of the containing block (height for vertical margin and padding, width for horizontal margin and padding).
Since the wrapping element has a height of 0, 56.25% of 0 is still 0, so it doesn't get any room as a flex item. Here's the Firefox bug report with more information. Here's the corresponding Chrome bug report, here the Webkit one and here's a thread on the www-style mailing list, where the browser vendors discuss the differences.
It looks like Firefox is planning to change its behaviour to match Chrome's behaviour of resolving percentage margin and padding to the width of the element. See this comment on the Firefox bug report.
This will hopefully mean that in the future we no longer need a workaround!
The final workaround
It looks like the wrapping element doesn't get a height to account for when laying out the flex-items. If we wrap our wrapping element with another wrapping element, that will get its height from its children:
Finally, we worked around the inconsistencies in IE11 and Firefox. Our beloved Media Object behaves correctly in all browsers now. As the bugs are filed in the respective bug trackers, I hope they will get fixed soon.