Friday, July 18, 2014

The secret to designing website layouts without CSS floats

If you have been designing for the Web at all over the past decade you are undoubtedly familiar with the CSS float property. Since the industry (thankfully) adopted the principle of tableless layouts, floats have been the weapon of choice most of us use to lay out our web pages, but is it the best choice?
Despite the popularity of this method it is regularly the cause of frustration and confusion for new designers and becomes a problem when floated elements are left “uncleared”. These uncleared floats can cause multiple issues ranging from sloppy aesthetics to complete inaccessibility. With a small project it’s pretty simple to trouble shoot a float issue but when working on a large web app with dynamic content it can be a tad bit trickier, eating up precious time and costing you money.

A better alternative

Even when used correctly, floats change the normal flow of a document which can cause unexpected behavior and limit styling options. Since a float is not in the ‘normal flow’, non-positioned block boxes created before and after the float box flow vertically as if the float did not exist. With responsive design, where sizes are dynamic and flowing to fill up available space, this is far from ideal. What if there was a better way?
Flexbox is the exciting future of web layouts but, for those of us that must support legacy browsers, this is still a far-off dream. The display property, on the other hand, has full support and can provide almost all the layout functionality of a float without the drawbacks.

inline-block to the rescue

The display property, in combination with float and position, determines the type of box or boxes that are generated for an element. In a very simple nutshell, block level elements span the entire width of their container forcing all subsequent elements to the next line while inline level elements only span the width of their contents, allowing any inline level element to flow up next to it on the same line.
Applying display: inline-block to an element generates an inline-level block container. Think of the text inside a tag. They are all ‘inline’ with one another while the tag itself is a block-level container. By understanding this behavior we can use the display property to inline our content next to each other. Since all of our elements remain in the normal flow, we have no issues with a collapsed parent element. In my opinion this is a much cleaner solution which still achieves the desired result.
See the Pen Inline-block over floats by davidicus on CodePen.

The technique

This method works just about anywhere you would normally apply the float. Let’s take a look at the classic main/sidebar layout. For the HTML we have a wrapper element with two child elements inside like so:
<div class="wrapper">  
        <div class="mainContent">
            <!-- Main content goes here -->
        </div><!-- No Spaces   
     --><div class="sideBar">
            <!-- Sidebar content goes here -->
        </div>  
    </div>
Our CSS:
        .wrapper,
        .mainContent,
        .sideBar { 
            //change the box model for simplicity
            -webkit-box-sizing: border-box;
               -moz-box-sizing: border-box;
                    box-sizing: border-box;
        }
        
        .wrapper {
            font-size: 1em;
            padding: 1.5em;
            width: 100%;
        }
        
        .mainContent,
        .sideBar {
            display: inline-block;
            vertical-align: top;
            width: 100%;
        }
        
        @media (min-width: 700px) {
        
            .mainContent {
                margin-right: 5%;
                width: 60%;
            }
        
            .sideBar { width: 35%; }
        }
Just like that we have the main content and side bar laid out.
The direction of the “float” is determined by the text alignment of the wrapper div. Since default alignment is left we didn’t have to do anything. However, you could easily set it to center or right to achieve some layouts that are not even possible with floats (more on that later). Notice the “no spaces” comment placed in between the two child divs of the .wrapper container. This is important to note, and the reason for doing it is the one “con” about this method.

White space

Let’s go back to the tag example. When writing text in html all white space is wrapped into one single white space character regardless of the amount of spaces you have in your HTML document. So, any gaps you have between your “floated” elements in the markup will actually register as a space between them in the browser, just like our paragraph text. This will naturally cause your size calculations to be off knocking the last element down to the next level of the page. No bueno! Luckily for us there are several solutions to fix this little issue. Such as:
  • Set font-size: 0;. The space that we are dealing with is a character space so setting the font-size to zero makes the size of the space zero as well. The issue with this is that you must bump the font sizes of the child elements back up and any ‘em’ sizing goes completely out the window. This could get a bit cumbersome to keep on top of, so this way is not ideal.
  • Remove the space between your elements in your HTML, thereby removing the space from the equation. I did this for a while but it just looked sloppy and made it more difficult to read.
  • Adding an HTML comment between your elements will also remove the space character as it did in our example. This is my preferred solution. The text highlighting in most text editors is such that the contrast between the note and the elements are enough to significantly improve the readability of your mark up. This will also allow you to keep the proper indentation of the actual element itself. 

Floats work for me, why change?

You may be thinking, “This is good and all but why would I change a method that works just fine for me?” Well, even if you are a float master there are certain things that they just can’t do. For instance:
  • The elusive “centered float”, which is oft-times desirable, requires additional markup and multiple CSS properties to achieve. With the display method this is simply done by applyingtext-align: center to the wrapper.
  • The biggest advantage of choosing the display method is the ability to vertically align your content. How often have you wanted to center an element to its sibling? You could use positioning with the negative margin/translate trick but, again, with a responsive, dynamic environment this is not preferable. Instead applying vertical-align: middle; will perfectly center your elements every time with no extra work on your part. (See the Pen Inline-block over floats by davidicus on CodePen.)

To wrap it up

In reality there is no “one size fits all” when it comes to web design and it really boils down to personal preference. I still use floats in certain situations and sometimes it really is the best tool for the job. I do, however feel there is a definite advantage to using the display method. From my experience, I have found it to be the best, least error prone method for dealing with layouts. For those of you that would like to explore this method more, I have created a “Just Say No To Floats” grid: Inline-block Grid with SASS on CodePen.