stephen.hanson
stephen.hanson

Reputation: 9624

CSS calc() not working correctly with em in IE

I have a simple scenario where I would like two boxes to display next to each other and to take the full width of the page, with 0.75em margin between them. Here is my markup:

<div class="box"></div>
<div class="box"></div>

and the CSS:

.box {
  float: left;
  width: calc(50% - 0.375em); /* 0.375 * (2 boxes) = 0.75 */
  margin-right: 0.75em;
}

.box:last-of-type {
  margin-right: 0;
}

This works correctly on Chrome, but when I try to load it in IE11, the second box wraps to the next line. I have set the font-size on the html element to 16px. Interestingly, if I replace 0.375em with 6px (16px * 0.375 = 6px), the boxes show up correctly on one line in IE11. Any thoughts anyone?

Here is a JSFiddle where you can see this not working in IE: http://jsfiddle.net/Lcuu8/3/

Upvotes: 0

Views: 2344

Answers (3)

Jukka K. Korpela
Jukka K. Korpela

Reputation: 201866

IE miscalculates 0.375em when em equals 16px. Instead of the mathematically correct result 6px, it gets 5.92px. This can be seen by setting the width of an element to 0.375em and inspecting the element in developer tools. There you can see that IE also shows the declared with as 0.37em, so it seems to drop any digits after 0.37! This happens also when using simply width: 0.375em, without using calc() at all.

In this case, the bug makes the width of each box a fraction of a pixel larger than it should be, and thus the second box does not fit on the right of the first a box.

A simple solution is to use integers. Mathematically, 0.375 equals 3/8, so you would replace

width: calc(50% - 0.375em)

by

width: calc(50% - 3em/8)

Upvotes: 1

Suresh Ponnukalai
Suresh Ponnukalai

Reputation: 13998

In your code, calc function is working correctly. But the problem comes from the decimal number you have used for calculation.

In Chrome the values are truncated. For ex, 50, 50.5 and 50.6 all show the same width in chrome which IE does not.

Use rounded values in the calculation part, you will get the desired result in IE and Chrome.

 .box {
 float: left;
 width: calc(50% - 0.4em); /* 0.375 * (2 boxes) = 0.75 */
 margin-right: 0.8em;
 }

DEMO

Upvotes: 0

codewizard
codewizard

Reputation: 1687

It is probably due to the way IE is handling the percentage. My suggestion would be to simplify and allow IE to handle the percentage differently. I've created an alternative method in this jsfiddle

Where I've created wrappers

<div class="boxWrapper"><div class="box"></div></div>
<div class="boxWrapper"><div class="box"></div></div>

And then set your CSS to handle the margin inside the wrappers

html, body { font-size: 16px; }
.boxWrapper {
    width:50%;
    float:left;
}
.box {
    height : 5em;
    background: slategray;
    margin-right: 0.375em;
    display:block;
}
.boxWrapper:last-child .box {
    margin-left: 0.375em;
    margin-right:0;
    background: silver;
}

Upvotes: 0

Related Questions