12

I have a parent div with rounded corners that contains a canvas:

<div id="box">
    <canvas width="300px" height="300px"></canvas>
</div>​

#box {
    width: 150px;
    height: 150px;
    background-color: blue;
    border-radius: 50px;
    overflow: hidden;
}​

The canvas renders a red rectangle that overflows the parent. As expected, this is what I get in all browsers:

enter image description here

The problem:

However, for webkit browsers running in Mac OS lion (I tested Safari 5.1.5 and Chrome 19), the canvas is still visible in the round corners:

enter image description here

Interestingly, this problem seems to happen only when the inner element is a canvas. For any other child element, the content is correctly hidden.

One workaround would be to apply the same rounded corners to the canvas itself, but unfortunately this is not possible, since I need to animate the canvas relative position.

Another workaround that should work, is to redraw the canvas in a clipped region that resembles the rounded corners shape, but I would prefer a cleaner CSS3 solution.

So, does one know how to fix this for Safari and Chrome on Mac?

EDIT: Problem also happens in Chrome on Win7

jsFiddle here

Jose Rui Santos
  • 15,009
  • 9
  • 58
  • 71

6 Answers6

9

Issue 137818: Large canvas does not honor containing div's border-radius

I solved this with CSS tag to parent div to:

transform: translate3d(0,0,0);

it works on the current chrome version 36.0.1985.143 m

jsfiddle.net/PJqXY/38/

#box {
    width: 150px;
    height: 150px;
    background-color: blue;
    border-radius: 50px;
    overflow: hidden;
    transform: translate3d(0,0,0);
}
arserbin3
  • 6,010
  • 8
  • 36
  • 52
Dowai
  • 109
  • 1
  • 7
6

Here's the code to add in the css :

 -webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC); /* this fixes the overflow:hidden in Chrome/Opera */

HTML Source Code

<div id="box">
  <canvas width="300px" height="300px"></canvas>
</div>

Css Source Code

#box {
    width: 150px;
    height: 150px;
    background-color: blue;
    border-radius: 50px;
    overflow: hidden;
    -webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC); /* this fixes the overflow:hidden in Chrome/Opera */
}

Javascript Source Code

var $canvas = $("canvas");

if ($canvas[0].getContext) {
    var context = $canvas[0].getContext('2d');
    context.fillStyle = 'red';
    context.fillRect(10, 10, 300, 60);
}

Note : This Need's Jquery

Example : http://jsfiddle.net/PJqXY/12/

Varun Sridharan
  • 1,983
  • 2
  • 20
  • 54
  • I've tried this solution before, but unfortunately it does not work for Safari 5.1.7 Win7. The disadvantage of using masks is the dependency with the border-radius. If I change the border-radius, will need a new mask image. Anyway, I gave you +1 for your effort and for making a base64 coded image that saves an extra HTTP request. – Jose Rui Santos Sep 09 '12 at 07:43
4

This is what I found out:

In the canvas element, when the multiplication of width by height is 66000 or greater, the canvas ignores the parent's overflow property.

For example, the following one fails, because 300*220 = 66000

<canvas width="300" height="220"></canvas>

This one works fine:

<canvas width="300" height="219"></canvas>

I've found this bug report after googling for "canvas 66000". It is not related with overflow, but I am sure is the same bug.

Thanks for Jeemusu for pointing me in the right direction.

Jose Rui Santos
  • 15,009
  • 9
  • 58
  • 71
  • Try using a canvas of size 256x256 (success), then try 256x257 (failure), that means that the limit is suspiciously close to 65,536 or 2^16 pixels. – lazd May 14 '13 at 20:12
  • @lazd You are right. To be more precise, this problem happens when the width*height > 2^16 – Jose Rui Santos May 15 '13 at 06:51
  • Well, what I said before is not totally correct (width*height > 2^16), but that the limit is suspiciously close 2^16 – Jose Rui Santos May 15 '13 at 07:02
4

Bug still exists (11/2015), but another workaround is to add position: relative; to the overflow:hidden; element.

Laurent VB
  • 1,187
  • 9
  • 18
3

Does the canvas have to use a width/height value? If you set the height of the canvas in the html to a smaller value, or even remove the values all together it gets clipped properly (only tested in Chrome).

http://jsfiddle.net/LwZ6v/

Jeemusu
  • 10,415
  • 3
  • 42
  • 64
  • +1 That's a great workaround that fixes the issue in Chrome and Safari! Thanks a lot!! However, it's not clear why works for `height` <= 219px, but fails for values >= 220px (assuming `width` remains unchanged to 300px) – Jose Rui Santos Jun 07 '12 at 09:11
  • It doesn't make a lot of sense to me either. If it worked for `height <= 140px`, which is the height - 10px margin of the red canvas, I could understand... but where it gets 219px from I have no idea. – Jeemusu Jun 07 '12 at 09:18
2

I found an asfwer for Safari. Add webkit mask with single pixel png to the parent and the clipping of overflowing parts will render fine.

-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);

JsFiddle sample