63

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

andyb
  • 42,062
  • 11
  • 113
  • 146
Jake Blues
  • 985
  • 1
  • 8
  • 12
  • It works fine for me: http://jsfiddle.net/qWdf6/1/ (I changed the picture because my proxy is blocking your, and added the borders to see what's goin on) – Andrea Ligios May 22 '13 at 08:35
  • 1
    It works _because_ you added the `border`. I can confirm that without the border this is broken in Chrome 26 on Windows and correct on Firefox 19 (for comparison). Adding `border:1px solid transparent;` as a workaround fixes Chrome – andyb May 22 '13 at 08:38
  • 1
    Related http://stackoverflow.com/questions/5736503/how-to-make-css3-rounded-corners-hide-overflow-in-chrome-opera – andyb May 22 '13 at 08:43
  • Andrea, thank you. It works fine, but only with border property. I modified your example, and changed border-color to transparent. It's still working. Thanks. – Jake Blues May 22 '13 at 08:49
  • Please add a comment to an answer if you un-accept it! I wasn't sure why my answer was un-accepted until I saw the update to your question. Could you please create an updated demo of the problem? – andyb May 23 '13 at 16:17
  • I've updated my answer with more information on the second problem, but there is no workaround yet - it is another Chrome bug. – andyb May 24 '13 at 20:29
  • position: relative; z-index: 10 .... this is the answer it solved my problem ... BTW firefox dont have this bug ... – J.Tural Feb 05 '16 at 23:36
  • 2
    Not sure about `border:1px solid transparent` but `transform:translateZ(0);` to .wrap worked for me. http://jsfiddle.net/locateganesh/qWdf6/754/ – Ganesh Yadav Feb 10 '17 at 14:25
  • Thks @locateganesh ! It works for me with `transform:translateZ(0);`! – fmoutawe Oct 18 '17 at 22:22

14 Answers14

29

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

See CSS performance relative to translateZ(0) for more information about this technique.

Community
  • 1
  • 1
lefoy
  • 1,087
  • 2
  • 12
  • 25
  • 1
    your solution worked for me. Thanks, Can you edit your code from `transform(translateZ(0))` to `transform:translateZ(0);` – Ganesh Yadav Feb 10 '17 at 14:07
28

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.

Ken
  • 383
  • 4
  • 9
  • 5
    It seems like solution. I don't think that it's needed to add such extremal big z-index, and in your example z-index doesn't work at all, because z-index only works on positioned elements(position: absolute;, position: relative; or position: fixed;) [W3C](http://www.w3.org/wiki/CSS/Properties/z-index). I've updated my example so after a year this question has been resolved finally :) http://jsfiddle.net/qWdf6/136/ – Jake Blues Jun 05 '14 at 10:44
  • Thanks for the remarks, I changed my comment accordingly, but in my case the transparent border still does not work. – Ken Jun 10 '14 at 16:35
  • This seems to resolve the problem with elements bleeding out of an element with `overflow: hidden` and a `border-radius`. – thasmo Sep 12 '16 at 13:59
24

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).

andyb
  • 42,062
  • 11
  • 113
  • 146
  • Sorry. It's my first question on stackoverflow. You were right, but I think this problem isn't resolved up to the hilt. If I add "transition", the child div still extends the beyond of parent div. If this bug hasn't solution, I will accept your answer gladly. ) – Jake Blues May 24 '13 at 14:42
  • No problem! Everyone has to start with their first question! I'll see if I can look at the updated demo. – andyb May 24 '13 at 15:17
  • wow, answer written in 2013 and I ran into this issue in Chrome v73! the culprit was border-radius where i removed radius and everything working fine now. Surprisingly bug #157218 claim it is fixed in 2017! – Armin Nikdel Apr 18 '19 at 11:45
18

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)

Mike Shema
  • 241
  • 2
  • 5
10

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

Jonathan Marzullo
  • 6,451
  • 2
  • 38
  • 45
6

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.

Yousef Salimpour
  • 694
  • 7
  • 15
3

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 {

    }
bob blunt
  • 31
  • 2
2

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.

Nitesh
  • 14,619
  • 4
  • 40
  • 52
  • Thank you. It's enough add border only to .wrap div ;) – Jake Blues May 22 '13 at 09:21
  • Hey I answered first, when I was busy solving the question and after posting saw all the comments about border. Nevermind, happens at Stackoverflow, a 5-10 second delay will get more and more solutions coming. My bad, just couldnt make it on the right time. Great to know that you got your solution. Cheers. Gotcha about wrap div - @JakeBlues – Nitesh May 22 '13 at 09:26
  • Cool trick! Thank you! But if the image has position "absolute" then it does not work. :( In newer Chrome versions (v32) the transparent border is also not needed anymore. – Benny Neugebauer Jan 20 '14 at 14:34
2

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);
dyad
  • 21
  • 1
  • This solution worked for me in case of an absolutely positioned child element that was transformed. Adding `transform: translateX(0)` to the parent element made the child element "obey" the parent elements´ `overflow:hidden` which it didn't before. I guess this is coming down to the fact that a new composite layer is created by the parent element (containing the child element), rather than the child element having it's own layer "outside" the parent. – Chri.s May 02 '18 at 14:17
0

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.

paul
  • 21
  • 1
  • 3
0

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);
}
Benn
  • 4,109
  • 7
  • 53
  • 99
0

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;
}
turzifer
  • 431
  • 1
  • 6
  • 16
0

Adding contain worked for me.

contain: strict;
overflow: hidden;

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

Ben Boyle
  • 1,486
  • 14
  • 11
-1

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.

sergio0983
  • 1,210
  • 8
  • 13