CSS Negative Margins Algebra

Relates to Accessibility and CSS Design

Defining CSS layouts with negative margins requires a high level of precision to ensure that all siblings are cleared effectively. Pie-fecta was the earliest example of this technique, demonstrating a complex set of dependant CSS rules. But, this should not make the technique so daunting that it is ignored. Ryan Brill's recent publication provides an insight into the simpler side of the technique. Only glimpsed at in his article, negative margins offer one huge benefit that should put table-based design to rest once and for all - flexible document structure.

As a scenario take the following document structure that defines the main content areas for a three column layout:


<div>
<div id="center">  </div>
<div id="left">    </div>
<div id="right">   </div>
</div>

Since the central column contains the main content, I have chosen to lead with it in the document structure for accessibility and SEO. The left column contains the navigation menu, and the right column a subsidiary menu/content (or perhaps advertising). Deeper into the site hierarchy, I decide to utilise the right column to bind additional information to the central column (eg links to related articles, or recent material). However, the document structure will now be detached since the main navigation (in the left column) separates the two bound columns. While this is of little relevance on a styled page where the columns are always in the same position, it is counter-intuitive for assitive devices or an intelligent search bot, where the style rules do not apply. The solution is to flip the left and right columns in the document tree. And the good news is with negative margins this can be achieved without changing a single rule in the underlying CSS!

So now it is time for the mathematics. I started this entry by emphasising the importance of precision, and there is no better way to ensure this than some CSS algebra.


α = column 1 width (#middle)
β = column 2 width (#left)
γ = column 3 width (#right)

Δ = predefined balancing unit

#middle {
  float:left;
  width:α;
  margin:0 [-(α+(β-Δ))] 0 β;
}

#left {
  float:left;
  width:β;
  margin:0 0 0 -Δ;
}

#right {
  float:right;
  width:γ;
}

The middle column is given a negative right margin to the value of its own width (α) plus the left margin (β) less a predefined unit (Δ). This provides the entire width of the parent container less one unit on the left for the middle column's siblings. The left column is floated with a negative left margin to the value of the predefined unit to place it flush left to the parent. The right column is simply floated right. The predefined unit is arbitrary, but obviously should be less than the width of the left column - I generally use a unit of 1 (eg 1em, 1px, 1%). The underlying premise behind this principle is explained in the CSS2 Specification.

A float can overlap other boxes in the normal flow (e.g. when a normal flow box next to a float has negative margins) Visual Formatting Model, CSS2 Specification

Now, the right and left column can be reversed in the document tree without any need for additional rules or any detrimental affect on the presentation. A clearing element will apply to all three columns - allowing any column to be longest (resolving the inherent problem with absolute positioning).

Here are a few examples:

These examples have been tested across all the major PC browsers, but I have not had an opportunity (or time) to test them on Mac and Linux. The only major bug arises in IE6 for a contained liquid width (ironically not IE5.x). There is also a gotcha involving preformatted text in the IE browsers for both liquid and fixed widths (explained in the above examples). The only hack required accounts for the IE Doubled Float-Margin Bug by declaring the containers' display inline.

Any layout containing floats has potential for browsers discrepancies (eg Peekaboo bug and IE Float Margin as above) and potential self-destruction. So far on quite complex test examples I have found this technique to work adequately cross browser. Plus, in theory the technique can also be applied to sub-containers - so long as the formula is balanced the columns can be cleared.

As for colouring the columns, the Faux Columnstechnique or a similar set of containing wrappers is required. IMHO, such non-semantic containers should be avoided in the document. This can be resolved by utilising presentational javascript. The presentation should first be made accessible to users with no javascript, then an onload event handler can be attached to the window object which performs the wrapping. Here is a little example, which I intend to write up soon - the Elastic Fantastic.

Posted on Thursday, Jul 01, 2004 at 01:59:57.

Comments on CSS Negative Margins Algebra (1)

α comment

Pie-fecta was the earliest example of this technique, demonstrating a complex set of dependant CSS rules.

Not to be pompous, but I believe I came up with the technique before PIE. They seem to be claiming February 9th, whereas I originally wrote about the technique on January 23rd, over at Mezzoblue. Just wanted to clear that up. :)

Posted by Ryan Brill
Thursday, Aug 19, 2004 at 20:35:08

Breadcrumbs Trail

[ Home ] -> TW Blog -> Jul 04 -> CSS Negative Margins Algebra
Site Map

The Severn Solutions website achieves the following standards:

[ XHTML 1.0 ] [ CSS 2 ] [ WAI AA ] [ Bobby AA ]

Page compiled in 0.013 seconds