Floats, Inline Block or Display Table? Or Flexbox?Karen Menezes on April 13, 2014
I avoid using CSS frameworks for my own projects, because I personally find most of them too dictatorial for custom design or final production code. You may beg to differ. Having said that, it's always a good idea to observe how different frameworks handle their grids. You'll generally see attribute selectors like selector[class*="col-"], which uses a substring match and may interfere with other classes, !importants and plenty of decimal points. For smaller projects, grids are often as simple as floating a 75% and 25% column and adding some padding.
Secondly, most ready-to-ship grids have some custom breakpoints (often called mobile/tablet/desktop or small/medium/large), which is not ideal, because your breakpoints depend on where the content breaks and not at some random idea of a device breakpoint. Not that you can't change these using a mixin via a preprocessor that many of these frameworks depend on, but different projects have different needs. The web has always been fluid, so it's best to think of your content and usability and then design around that...
Using box-sizing border-box universally makes grids so much simpler. I'm a big fan of using padding instead of margins, where possible, since border-box includes padding in the total width/height of the element.
I also love calc. It has great browser support, but is still an at-risk feature, so use with a fallback and with care. With calc, you could effectively have 7 boxes of equal width by declaring calc: width(100% / 7). How cool is that!
You can read this article to look at what calc can achieve...
Most grids and front-end frameworks I've seen insist on floats for all layouting. But sometimes, you don't want floats... You may occasionally be better off with inline-block, rarely display-table, and if your browser support is ideal, flexbox. In fact, I've started using flexbox on real world projects for layout enhancements like vertical centering (when it's alright for older browsers to have content aligned at the top).
Let's look at some advantages and disadvantages of popular layouting methods for responsive sites:
- - Most popular way to lay things out; most grid frameworks follow this.
- - Everyone's aware of float bugs due to the popularity of floating, and there are well documented ways to overcome them.
- - Need to be cleared. Can be quite painful if you're changing widths at 2-3 media query breakpoints, because the floats will need to be cleared that many times.
- - No vertical centering
- - No equal heights
- - No source order independence
- - Large layout blocks that don't need equal heights and vertical centering
- - Vertical centering is most useful for some layouts
- - Don't need to be cleared. Useful for complex layouts when breakpoints need to be changed at more than a couple of screen widths. You can see this demo to understand how advantageous inline-block can be, for this use case.
- - Suffers from inherent whitespace, which will disturb your grid calculations. You can't make a two column grid with the left being 30% and the right being 70%, with display: inline-block, because the whitespace will break the grid and push the second column to the next line. There are ways around this. The easiest is if you're using lists with the HTML5 doctype, because you don't need to add closing list tags and this removes the whitespace bug. See this article for more.
- - No equal heights
- - No source order independence
- - When you require vertical centering, but not equal heights with CSS.
- - When you want to avoid clearing your floats at different breakpoints.
- - When you can get around the whitespace issue, without driving the rest of your dev team crazy.
- - When you can get around the whitespace issue, whilst ensuring that your templating language does not try to add closing li items. That's not cool, bro.
- - When you're using list items for layout and don't need a closing li tag, inline-block truly shines.
Stop whining about your table nightmares for layout. Get over it.
Stop jumping every time you see a table.
- - Provides you with vertical centering and equal heights
- - Extra wrapper divs (although the spec says you don't need to declare all of them, I've seen weird bugs in iOS when you don't have them).
- - If you require spacing between table-cells, you'll have to use border-collapse: separate on the parent element with display: table (since table-cells can't have margins), but this will add padding to the leftmost edge of the first cell and the rightmost edge of the last cell. That could break your grid. However, there is a way around this...
- - Content can overflow its cells and it's a bit hard to deal with.
- - How the hell do you go from 4 cells to 2 to 1 in a responsive layout? Going from 4 to 1 is easy, because you can replace the table display with a block display in your stylesheet. But if someone knows how to go from 4 to 2 columns on a breakpoint, I'd love to hear from you...
- - Those delicate moments when you need vertical centering + equal heights for a responsive layout with only 1 breakpoint to move from table to block
So everyone's going Yaaay for Flexbox. I'm holding my tongue. I've been experimenting quite a bit over the last few months.. It takes a while to wrap your head around it... and it's quirky.
I'm also seeing cross browser inconsistencies with the unprefixed standards syntax supported in current Firefox, Chrome, Opera and IE11+
This scares me. I'm going to work on an article on some weird issues I've seen across browsers for Flexbox, but in a little while.
I have great faith in the CSS grids specification, but it's sort of early days for it... so let's wait and watch, and experiment.
All said and done, Flexbox is awesome and beyond your wildest, most perverted CSS layout dreams.
- - Source order independence. Could be of tremendous value for responsive layouts and eliminates the need for JS for this.
- - Vertical centering
- - Equal heights
- - Flex boxes move along interchangebly the X and Y axis, with such ease, that you can really change things around with a couple of properties.
- - Boxes grow and shrink, can be columns or rows, fit to the available space however you wish to declare this.
- - There are multiple ways to do the same thing with flexbox.
- - Syntax is initially unintuitive. You spend the first few hours looking at demos saying WOW, followed by WTF.
- - I've been noticing weird cross browser inconsistencies that I need to document in another article. Hopefully file some bugs, I already have one in mind for Firefox (if it's not filed already). I'm scared... It took me a long time to figure some of these out.
- - A deep understanding of Flexbox takes a while. Once the layout gets more complex, or you add a couple of divs, things can get confusing. I'm going to document this more in an article.
- - Lots of vendor prefixes, with a different syntax for older IE and Webkit. Use something like Autoprefixr to work around this. Or write some mixins. Or do something..
- - Doesn't work on IE9. If you don't have to support IE9, you're fine.
- - Reports of the older syntax impacting performance. I wouldn't care too much about this honestly, especially if you were using JS to do the things Flexbox now can...
- - You can already start using it for vertical centering, if you don't need things to look the same on IE9.
- - If you don't need IE9 support, it's perfect for source order independent layouts, equal heights.
- - I would highly recommend using it for personal projects.
- - App layouts where things need to stretch and squish. Flexbox really shines here.
So that's my round up of layouting tools in CSS. Let me know what you think.