Css3 Transform Affecting Other Elements with Chrome/Safari

CSS3 Transform affecting other elements with chrome/safari

This is a known issue with Macintosh text rendering on Chrome 22 (and apparently Safari). GPU acceleration causes MacOS to switch from subpixel to greyscale antialiasing which makes the font weight appear to decrease noticeably.

Update:

As the OP notes below, the fix is to apply -webkit-font-smoothing: antialiased - which applies grayscale anti-aliasing at all times. If you do this, you'll probably want to increase your font-weights all around since greyscale anti-aliased text looks notably thinner than sub-pixel

You can get the same effect by applying properties that cause the content to always be GPU accelerated (such as back-face-visibility: hidden) but because these are not guaranteed to cause GPU acceleration in future browser versions - it is more future proofed to simply specify greyscale.

css rotate with transition seem to affect other elements opacity?

The backface-visibility property determines if the element should be visible or not when it's faced away from the screen, commonly used when you "flip" and element.

In this case, it seems that it has the same effect as when you add:

-webkit-transform: translate3d(0,0,0);

Demo - http://jsfiddle.net/tTa5r/4/

which forces hardware acceleration giving you a slightly thinner (anti-aliased), but a more consistent font rendering before and after the transition.

There is a third option as well, and that is to add:

-webkit-font-smoothing: antialiased;

Demo - http://jsfiddle.net/tTa5r/3/

I answered a similar question before and @mddw posted a comment linking to a blog post that describes the methods of antialiasing which seems to be the reason for why you see a differens during and after the transition.

http://cantina.co/2012/05/18/little-details-subpixel-vs-greyscale-antialiasing/

Hope that helps!

Strange behaviour with transitions in Safari

While I cannot give you an explanation as to why Safari behaves this way (although I can imagine that since the translateX value is in % — based on the width — it gets thrown off and waits for the latter to be in its final state before animating the former), I can offer a fix with a few tweaks (tested on Safari, Chrome and Firefox on macOS 10.15).

By removing the width property completely and instead animating the left and right properties (and only using translateY), you can achieve the same result.

Your initial state was a block centered which took up 50% of the width; here we let the width be dictated by the left and right of 25% each, leaving the remaining 50% for the width.

The transform has been simplified to just affect translateY — the top values remains unchanged.

In your active state, we increase the left and right values to 30% each, totaling 60% and leaving us with 40% for the width, same as before.

button = document.querySelector('.button')
block = document.querySelector('.block')

button.addEventListener('click', () => {
block.classList.toggle('active');
});
.block {
border: 1px solid red;
position: fixed;
top: 50%;
left: 25%;
right: 25%;
height: 50%;
transform: translateY(-50%);
transition: all 0.5s ease;
}

.active {
top: 100%;
left: 30%;
right: 30%;
transform: translateY(-40px);
}
<div class="button">Click me</div>
<div class="block"></div>

Transform scale() Safari bug when used on elements with border

CSS transform scale() function appears to have a bug on Safari when it's used on elements with a border.

You can say that again! Unfortunately, the reported bug(s) for this (and similar) issues go back many years, with the following bug referenced in most:

  • https://bugs.webkit.org/show_bug.cgi?id=27684 (Opened in 07/2009)

If you didn't catch the date, it's a 10 year old bug that's still causing developers issues today! YIKES.

Basically, the issue comes down to Safari rasterizing the layer. On transform/scale, it resizes the layer, however it does not re-render the rasterized layer. In your use-case, the rasterized image is scaled up, but the text/image is blurry.

As for a workaround/fix? There are a couple ways you can "address" this:

1) Force a re-render

A quick/easy fix is to force Safari to re-render your layer when you transform. One way this can be achieved is by applying a CSS property which you then change after transforming (some people have success changing a background-color, for example). For your specific use case, I had luck with the following combination:

img {
outline: 1px solid #000;
border: none;
}

img:hover {
outline: none;
border: 1px solid #000;
}

By toggling those specific values, I was able to force Safari to re-render the rasterized layer, thus rendering a sharp image (similar to the non-border example). Here's a JSFiddle with the full code example: https://jsfiddle.net/gc56brfh/

2) Scale down, then up

Another workaround, documented here, is to set the element's initial size to the "scaled up" dimensions, and then scale down the element until you're ready to scale it up. That way, the element is rasterized to the correct dimensions.

CSS wise, that may look like:

img {
-webkit-transform: translateZ(0) scale(0.2);
height: 250px;
}

img:hover {
-webkit-transform: translateZ(0) scale(1);
}

In the above, we've set the initial size of the img to 250px (this is based on your original css, with images being 50px and then scaled up 5). We then scale down the image by 0.2, resulting in 50px. On hover, we then scale back up to 250px by setting scale(1).

Here's an updated JSFiddle: https://jsfiddle.net/df2zqgnx/

One thing to note is that other CSS properties might need to be updated with this workaround. For example, you'll notice in the fiddle I also needed to update the border from 1px to 5px to compensate for the scaling down.

Anyway, hope this was helpful and one of the solutions works for you!

CSS3 hover effects make weird impact on other elements in Chrome

I just had to apply: -webkit-backface-visibility: hidden; to all the affected elements and everything works well in Chrome.



Related Topics



Leave a reply



Submit