Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebKit CSS Transforms: Scaling doesn't work on Retina Mac if the scale factor is greater than 1 for certain HTML elements

Sample Fiddle: http://jsfiddle.net/pmLs1cxv/5/

HTML:

<p>
    <input type="checkbox" class="two" />
    <input type="radio" class="two" />
    <button type="submit" class="two"></button>
</p>
<p>
    <input type="checkbox" />
    <input type="radio" />
    <button type="submit"></button>
</p>

CSS:

.two {
    transform: scale(2);
}

I have a radio button and a checkbox that I apply transform: scale(2) to. On my Thunderbolt (not retina) display, they scale properly to 2x, like so: Thunderbolt

But then I drag the same window over to my Retina MacBook's display, and they suddenly turn back to original size, like so: Retina

I did not do anything to the window or inside the window, I just dragged the window between the two displays. Whenever the window is on the Thunderbolt Display, the controls pop back into 2x mode, and when the window is on the Retina MacBook's display, they pop back to original size. How do I ensure they scale on retina displays? (Using transform: scale(4) doesn't do anything; it isn't a matter of retina displays requiring 2x the scale factor.)

Note: I tested in Chrome 44 and Safari 8.0.7 and the behavior occurs in both, thus my titling the question WebKit. Interestingly, using zoom: 200% instead of transform: scale(2) causes Chrome to render the boxes in a different style that bypasses this issue, but that doesn't work in Safari, where it exhibits the same behavior described above. I have tested this on multiple Retina MacBook Pros and they all exhibit this behavior, so it is not an issue local to my machine.

EDIT: I modified the fiddle to include a <button> element as well, and same thing occurs, so this is not limited to radios and checkbox inputs.

EDIT 2: I tested <img> elements and they scale properly. As a result I don't think this is an issue for all elements, just specific ones, and I have found that it impacts radio buttons, checkboxes, and buttons so far.

like image 735
Display Name Avatar asked Aug 05 '15 22:08

Display Name


1 Answers

Try using CSS 3D transforms instead. For example, instead of transform: scale(2) you can use transform: scale3d(2,2,1).

This works because using 3D transforms forces Webkit browsers to create a new GPU layer for that element instead of transforming it using other methods. From this article by Paul Lewis and Paul Irish of the Chrome team:

In Blink and WebKit browsers a new layer is created for any element which has a CSS transition or animation on opacity, but many developers use translateZ(0) or translate3d(0,0,0) to manually force layer creation.

This article by Tom Wiltzius of the Chrome Team has more criteria for what creates a layer and what does not. (Warning: That article was written in 2013 and may not be fully accurate now.)

This sounds like a legitimate WebKit bug, though. I would recommend reporting it to either the WebKit or Chrome teams.

like image 103
Ben Visness Avatar answered Nov 15 '22 08:11

Ben Visness