I came across a CSS bug this week that I had not seen before. For BrowserID, we use box-sizing: border-box on all of our elements using the following snippet of CSS:

* {
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
       -o-box-sizing: border-box;
          box-sizing: border-box;

This bit of CSS makes most elements use the old IE box-model - a box model that is much more sane than the W3C standard box model. Using the border-box box-model, the width and height of an element includes the element's padding and border. See Paul Irish's article on why this is awesome.

The strangeness I saw this week only occurrs in Firefox and IE - when setting the min-xxx of an element that has a padding, these browsers use the W3C box model instead of the border-box box model.

So, imagine an empty div with the given CSS properties

#test_element {
   -webkit-box-sizing: border-box;
      -moz-box-sizing: border-box;
        -o-box-sizing: border-box;
           box-sizing: border-box;
   min-height: 100px;
   padding: 10px 0;
   position: absolute;

test_element has a total height of 100px in Chrome, Safari and Opera. In Firefox and IE, #test_element has a height of 120px.

This is a known Firefox issue and even documented on MDN. The behavior may be changed in future versions of Firefox, I am unsure of Microsoft's stance on this.

In my circumstance, I dynamically set the min-height of a content element based on the height of a header and footer. Because the content element I want to size has a padding, I have to make sure to accommodate the padding in Firefox and IE.

Instead of relying on browser sniffing to say "act differently for Firefox and IE", I created a test that checks whether the browser suffers from the issue. This is more robust than browser sniffing because Mozilla and Microsoft may fix these bugs at some point in the future. Instead of having to modify my code again to handle versions of Firefox and IE that both pass and fail, I just check if the browser suffers from the problem.

The test I have come up with is straight forward, I create an element, set some styling properties, attach it to the DOM and measure its clientHeight. Styling wise, I set box-sizing to border-box, set its min-height, set a top-padding, and absolutely position the element off of the screen. Once the element is attached to the DOM, I can get the element's clientHeight to see what its total height is. If the total height is not the same as the min-height, the browser suffers from the bug.

function paddingAddedToMinHeight() {
    // create an element, set box-sizing to
    // border-box as well as absolutely position
    // the element off the screen.
    var div = document.createElement("div");
    div.style.MozBoxSizing = "border-box";
    div.style.OBoxSizing = "border-box";
    div.style.boxSizing = "border-box";
    div.style.minHeight = "100px";
    div.style.paddingTop = "10px";
    div.style.position = "absolute";
    div.style.top = "-2000px";
    // An element will not have height until it
    // is attached to the DOM.

    // https://developer.mozilla.org/en/DOM/element.scrollHeight
    // scrollHeight is the height of the element
    // including its padding but not it's margin.
    var divHeight = div.scrollHeight;
    // clean up after ourselves.
    return divHeight === 110;

You can see this in your own browser at JSFiddle.