CSS3 transform property working differently in Internet Explorer

Easier Approach

Instead of positioning from the top and left, position instead from the bottom and right. After you've done this, simply change your -50% translations to positive 50%. This will remove the overflow e.g.

.center-center {
    position: absolute;
    bottom: 50%;
    right: 50%;
    transform: translate(50%, 50%);
}

You can see these changes in action here: http://jsfiddle.net/bd17gsss/

It's worth noting that this bug is still filed, and our team will still give it the appropriate consideration when time and cycles permit us to do so.

Original Answer

There appears to be a layout bug with position: absolute in this particular demo. It's behaving similar to position: relative when it shouldn't be. I've opened a bug on this issue for the Internet Explorer team to investigate further.

For now, you could switch your position value from absolute to fixed, which appears to render the centered element correctly. This prevents you from having to use a fixed set of dimensions over and over, and instead allows you to use this approach as a general-purpose .modal style class that will center anything it is applied to.

The obvious caveat with this change is that your element is positioned according to the viewport, and no longer the document itself. This will freeze it on the screen effectively.

.modal {
    position: fixed;
    top: 50%; left: 50%;
    background-color: red;
    transform: translate(-50%, -50%);
}

To demonstrate the success this approach has with various dimensions, we can cycle through a few example sets and test the rendering of the element to ensure it is properly centered:

(function () {

    var xandy,
        index = 0,
        modal = document.querySelector( ".modal" ),
        sizes = [
            { x: "50%"  , y: "30%"   },
            { x: "400px", y: "288px" },
            { x: "25vw" , y: "75vh"  },
            { x: "90%"  , y: "90%"   }
        ];

    setInterval(function changeSize () {
        xandy = sizes[ index++ % sizes.length ];
        modal.style.width = xandy.x;
        modal.style.height = xandy.y;
    }, 1000 );

}());

The end-result can be viewed online here: http://jsfiddle.net/jonathansampson/c00u5ev8/


If anyone else is still having fun trying to work around this issue (seeing as Internet Explorer bugs never get fixed because we all love having to work around them instead), and you'd like to be able to use position: relative; instead of position: absolute;, or top and left rather than bottom and right, try this instead:

.centredDiv {
    position: relative;
    top: calc(50% - 100vh);
    left: calc(50% - 100vw);
    transform: translate(-50%, -50%) translate(100vw, 100vh);
}

You can use 100 view height/view width or an arbitrary pixel value representing a maximum theoretical scroll height/width so that the top/left values would never conceivably overflow the parent, and then just offset that in the transform.


If I was in an elevator with Hitler, Stalin, and Internet Explorer, and I had a gun with only 1 bullet... I would kill Internet Explorer.


If actually just answered this very question in another thread, you can use display: table; and display: table-cell; to solve this issue (works cross-browser as well!), see my live code here: http://codepen.io/TheDutchCoder/pen/GggWqP

In your case it would be:

#wrapper {
  display: table;
  width: 100%;
  height: 100%;
}

#centred {
  display: table-cell;
  vertical-align: middle;
  text-align: center;
}