Bug with transform: scale and overflow: hidden in Chrome

Google ChromeTransformTransitionCss

Google Chrome Problem Overview


Working with CSS3 property transform: scale, I found interesting issue. I wanted to make a little zoom effect for pictures. But when I used for the parent div overflow: hidden and border-radius, the child div extended the beyond of parent div.

Update:

Problem isn't solved. If I add transition, is still doesn't work. I tried to solve this issue, but without success.

Here is a demo

Google Chrome Solutions


Solution 1 - Google Chrome

transform: translateZ(0); on the wrap element did the trick for me.

See https://stackoverflow.com/questions/10814178/css-performance-relative-to-translatez0 for more information about this technique.

Solution 2 - Google Chrome

The transparent border did not worked for me but to change the z-index of .wrap div and image worked (in my case, image is in fact a video)

Here is the css:

.videoContainer{
    overflow: hidden;
    z-index: 10;
}

video{
    margin-left: -55%;
    transform: scale(-1,1);
    -webkit-transform: scale(-1,1);
    -moz-transform: scale(-1,1);
    z-index: 0;
}

NOTE: see Jake Blues comment below concerning the necessity to have positioned element for enabling z-index to work properly.

Solution 3 - Google Chrome

It's a known bug in Webkit-based browsers - see #62363. You can add a border:1px solid transparent; to your .wrap class to workaround the problem.

For the updated requirement, adding a transition to an element with a border-radius, that's another known Chomre/Webkit bug #157218. Sorry but no known general workaround still, although one comment on that bug says that using the chrome://flags and using the --ignore-gpu-blacklist flag fixes it in Chrome 29 (which just hit the Chrome dev channel today).

Solution 4 - Google Chrome

Both ways of solving this issuer worked fine:

  1. Add the following line to a parent wrapper (z-index: 0 is not necessary for the image itself): position: relative; z-index: 10

  2. Or add transform: translateZ(0); to a parent wrapper (with the corresponding prefixes for better browser support)

Solution 5 - Google Chrome

This happens due to composited layers not being clipped by their parent layers. So sometimes you need to bring the parent with overflow:hidden onto its own compositing layer so it can apply overflow:hidden correctly.

So you must add the CSS property transform: translateZ(0) to the parent element of your transformed element.

/* add to parent so it is composited on its own layer before rendering */
.parent-of-transformed-element {
     -webkit-transform:translateZ(0);
     transform:translateZ(0);
}

Then overflow:hidden will work due to having the transformed element be composited on its own rendering layer like its transformed child.

Tested on latest Safari and Chrome on iOS and non iOS devices

Solution 6 - Google Chrome

Strangely I just ran into this problem after upgrading to Chrome 65, and for me adding will-change: transform; to the IFRAME styles did the trick.

Solution 7 - Google Chrome

sorry for my poor English.

if the page isn't have positioned element, there is no need to set container element and child element z-index attribute both.

just adding z-index: 0(or other) attribute to container element.

.container {
    border-radius: .14rem;
    overflow: hidden;
    z-index: 0;
}
.child {
       
    }

Solution 8 - Google Chrome

Here is the Solution.

The HTML:

<div class="wrap">
    <div class="image"></div>
</div>

The CSS:

.wrap{
    width: 400px;
    height: 260px;
    overflow: hidden;
    border-radius: 15px;
    border:1px solid transparent;
}
div.image{
    background: url(http://blog.dothegreenthing.com/wp-content/uploads/2012/10/take-a-smile.jpg) no-repeat;
    width: 400px;
    height: 260px;


}
div.image:hover{
    -webkit-transform: scale(1.2, 1.2);
    transform: scale(1.2, 1.2);
    cursor: pointer;
    border:1px solid transparent;
}

Chrome needs a transparent border surrounding the box. Hope this helps.

Solution 9 - Google Chrome

I had a similar issue with the latest version of Chrome 65. I have an iFrame video scaled larger using transform: scale() in a div, and on the latest Chrome version, it was no longer masked on the sides and was popping out of the parent container, even with overflow: hidden;

While translateZ sort of helped, it was only when I used translateX on the parent instead did it mask the width properly:

 transform:translateX(0);

Solution 10 - Google Chrome

The bug still exists in webkit Browsers (Safari and Chrome under iOS) when the mask is scaled. And then all the workarounds above do not work. But using the non standard css property -webkit-mask-box-image helps for scaled masks as well.

Solution 11 - Google Chrome

I have been after this for long time and only thing that has worked for me is this rotate(0.1deg) translateZ(0) . So if you are scaling the element

.something:hover img{

	-webkit-transform: scale(1.1) rotate(0.1deg) translateZ(0);
	-moz-transform: scale(1.1) rotate(0.1deg) translateZ(0);
	-o-transform: scale(1.1) rotate(0.1deg) translateZ(0);
	transform: scale(1.1) rotate(0.1deg) translateZ(0);

}

without the rotate the fix does not work on my end.

If you add transform to ANY img parent ( like rotate the container where the image is ) , you need to add same fix to the element for example

.something_parent{
    transform: translate(-9%,9%) rotate(0.1deg) translateZ(0);
    -webkit-transform: translate(-9%,9%) rotate(0.1deg) translateZ(0);
    -mos-transform: translate(-9%,9%) rotate(0.1deg) translateZ(0);
    -o-transform: translate(-9%,9%) rotate(0.1deg) translateZ(0);
}

Solution 12 - Google Chrome

On Chrome build 78.0.3904.87, after trying will-change: transform, border: 1px solid transparent, transform: translateZ(0) on the parent element without success, I was able to get rid of the problem by reducing the border-radius from 50% to 49%. It seems border-radius: 50% is a special case.

So my working solution is:

.parent {
  z-index: 1;
  position: absolute;
  overflow: hidden;
  border-radius: 49%;
}

.child {
  z-index: 0;
  position: absolute;
}

Solution 13 - Google Chrome

Adding contain worked for me.

contain: strict;
overflow: hidden;

https://developer.mozilla.org/en-US/docs/Web/CSS/contain

Solution 14 - Google Chrome

Well... trying to find a workaround found that

-webkit-appearance: button; 

fixed this behavior, but has some undesirable side effects if the element isn´t actually a button, like borders behaving wierd, but, replacing <a> with <button> in my case kept the scaled content within its bounds.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJake BluesView Question on Stackoverflow
Solution 1 - Google ChromelefoyView Answer on Stackoverflow
Solution 2 - Google ChromeKenView Answer on Stackoverflow
Solution 3 - Google ChromeandybView Answer on Stackoverflow
Solution 4 - Google ChromeMike ShemaView Answer on Stackoverflow
Solution 5 - Google ChromeJonathan MarzulloView Answer on Stackoverflow
Solution 6 - Google ChromeYousef SalimpourView Answer on Stackoverflow
Solution 7 - Google Chromebob bluntView Answer on Stackoverflow
Solution 8 - Google ChromeNiteshView Answer on Stackoverflow
Solution 9 - Google ChromedyadView Answer on Stackoverflow
Solution 10 - Google ChromepaulView Answer on Stackoverflow
Solution 11 - Google ChromeBennView Answer on Stackoverflow
Solution 12 - Google ChrometurziferView Answer on Stackoverflow
Solution 13 - Google ChromeBen BoyleView Answer on Stackoverflow
Solution 14 - Google Chromesergio0983View Answer on Stackoverflow