Is it possible to "snap to pixel" after a CSS translate?

James Long picture James Long · Aug 15, 2013 · Viewed 13.5k times · Source

I created a modal box and vertically centred it using a technique Chris Coyer mentioned. The only problem I've found with it so far is that sometimes the box is offset by half a pixel, which can make some of the children look a little wonky. My question is,: is it possible to snap the result to the nearest whole pixel?

Update

Here are a couple of pictures to better illustrate the issue. In this first image, you can see the text inputs and link underlines have rendered correctly:

Modal box with crisp lines

The second image shows the effect after the CSS transforms have been used. Notice the blur of the link underline and the incorrectly rendered text inputs.

enter image description here

Although the second image doesn't show it, occasionally I notice the top and bottom white lines wit the same blurred effect.

For the record, the text inputs are styled using simple borders and a background colour. I've included the CSS for those inputs here so you can see there's nothing special happening:

input {
    background-color: #FFFFFF;
    border: 1px solid #CCCCCC;
    border-radius: 0;
    box-shadow: 0 1px 3px -1px #D5D5D5 inset;
    color: #4C4C4C;
    display: inline-block;
    font-family: Arial,Helvetica,sans-serif;
    font-size: 12px;
    max-width: 100%;
    padding: 5px;
    transition: border-color 0.1s ease 0s;
}

Answer

derrylwc picture derrylwc · May 7, 2014

The only bulletproof solution is to ensure that your element occupies an even number of pixels. If the height (or width) is not divisible by 2, then it will attempt to render your element on a half-pixel, causing the blurriness.

Firefox doesn't have this issue because it supports true subpixel rendering. So, even though your element is on a half-pixel, Firefox handles it elegantly.

In my experience, Webkit typically snaps elements to the nearest pixel –– (for instance, when using the letter-spacing property) -- so it's kinda strange that it doesn't behave the same way for translate.