floated multi-row blocks

The float is a popular css property. Not often used for its intended purpose but still extremely useful in many circumstances. For one, it helped push liquid designs by allowing elements to fill in any available space. Floated blocks would line up next to each other and shift to a next row when all horizontal space was used up. Today I'll show you a little css trick facilitating the css for this particular setup.

issues

While such strings of blocks are popular elements featured on many web pages, there's not really one clean way to css them. The main problem lies with the outline of the blocks related to elements above and below. You need to set a margin to push the individual blocks away from each other, but since the blocks are floated none of the margins will collapse. This will create an extra space to the left or right which is unwanted in most designs.

There are a few typical solutions to fix this. You could mess around with the left or right spacing of its parent (leaving a space equal to the margin between the floated blocks) or you can work with a .first or .last class, using it to nullify the margin on the first or last block within a row. The first fix is messy and upsets the logical flow of the css. The second option only works if you know how many items will be in a row (in other words, it fails in liquid designs) and is quite ugly to implement.

issues

<ul> <li>...</li> <li>...</li> </ul>

We're going to use the above html as a base structure for our floated blocks. I usually add a structural div around it to allow for headings and such, but this is not really important for the issue at hand. The html is composed of a simple unordered list. The li elements will be floated, the ul will act as the container for the floated blocks. The unordered list is a typical way of marking up such elements, but you could just as well use nested divs if you'd like.

ul {overflow:hidden; margin-left:-1em;} ul li {margin-left:1em; width:Xem;}

The trick is very simple. Rather than mess around with the spacing between its parent we'll use the ul to create the needed space. We'll pull it to the left using a negative margin equal to the margin defined on the li element. This way the first block will receive the same position as if no styles were applied and the last item will be able to align with the right edge of the element (as we've used a left margin). All that is left is to determine a good with for the alignment to work. Note that the same method can be applied for vertical alignment.

This little trick requires us to keep two separate values equal to create the effect, which is something I don't like doing. In this case though, it's better than the alternatives I listed above. As we're using negative margins we'll have to add a position:relative and zoom:1 for IE6 (what else is new) and we have to be a little careful with overflow:hidden statements on surrounding element. If for some reason the negative margin is bigger than the margin on the floated blocks than you'll have to use a different clearing method as some elements will hide behind the overflow.

Check the test page to see it working.

conclusion

A very simple trick, but one that many people seem unaware of. Nothing earth shattering, but a good trick to have in your inventory, resulting in cleaner and leaner css. As often the case, the good stuff doesn't have to be hard. Enjoy!