Adblock Plus and (a little) more

Mixing absolute and relative lengths in SVG clip paths · 2009-03-12 12:14 by Wladimir Palant

A supposedly simple task turned out to be pretty hard and now I am left guessing whether I am dealing with an SVG spec issue or with a Gecko bug. I need to make corners of a XUL element transparent, something that should be easy if you apply SVG effects to it. The following svg:clipPath element should do:

<clipPath id="c1" clipPathUnits="userSpaceOnUse">
    <rect x="0" y="0" width="100%" height="100%" rx="10" ry="10"/>

Only that it doesn’t work, percentages are resolved relative to window size rather than element size (is this by the spec or a bug?). I thought that changing units might work:

<clipPath id="c1" clipPathUnits="objectBoundingBox">
    <rect x="0" y="0" width="1" height="1" rx="10px" ry="10px"/>

Of course now the coordinate system changed and “10px” means 10 times the width/height of the element rather than ten pixel. Is there any solution other than hardcoding element size in the SVG code?


Comment [6]

  1. Neil Rashbrook · 2009-03-12 12:44 · #

    Does -moz-border-radius have any effect?

    Reply from Wladimir Palant:

    On svg:rect? No. And I don’t expect any CSS-based solutions, CSS in SVG goes back to the same transformed coordinate system.

  2. Neil Rashbrook · 2009-03-12 13:59 · #

    No, I meant on the original XUL element, to round the corners off. Or did I misunderstand the problem?

    Reply from Wladimir Palant:

    The element is actually a frame and I am trying to cut away the corners, not something I can do with -moz-border-radius.

  3. Robert O'Callahan · 2009-03-12 14:42 · #

    I think that’s all according to spec. I agree it’s not as useful as it could be.

  4. Cameron McCormack · 2009-03-12 22:29 · #

    Sounds like a useful thing to want to be able to do. Maybe a use case for the layout module?

  5. Jonathan Watt · 2009-03-13 15:37 · #

    For your first code snippet (userSpaceOnUse), the percentage lengths are resolved relative to the width/height of the clipped element’s viewport element, or the width/height of the viewport’s viewBox attribute if it has one. That may or may not be the same as the content area (window).

    For your second code snippet (objectBoundingBox), offhand I don’t see any good reason for lengths with an absolute unit to have their unit ignored. (It’s also a shame that the specification says that numbers without units are a factor in this case – it would be more consistent and less confusing if they were treated as px units as elsewhere and authors had to use percentages – but there’s no going back there).

    I’ll bring this up with the SVG WG.

    Reply from Wladimir Palant:

    No, the unit isn’t ignored – it’s just the way SVG defines pixels. If you have a look at, it says: “Thus, in the the initial coordinate system, because the user coordinate system aligns exactly with the parent’s coordinate system, and because often the parent’s coordinate system aligns with the device pixel grid, “5px” might actually map to 5 devices pixels. However, if there are any coordinate system transformation due to the use of transform or viewBox attributes, because “5px” maps to 5 user units and because the coordinate system transformations have resulted in a revised user coordinate system, “5px” likely will not map to 5 device pixels.” And with objectBoundingBox we are in a transformed coordinate system. All other units are defined as multiple of “pixels” and that’s how they are interpreted here as well.

    Thanks for pointing me to the viewBox attribute, I think I understand now why the first code snippet fails. Unfortunately, it doesn’t help solving the problem – even if I could use the viewBox attribute on a non-SVG element (maybe I can), I would still need to change its value dynamically as the element size changes. Otherwise the viewport pixels and screen pixels will get “out of sync” again.

  6. Jonathan Watt · 2009-03-13 18:00 · #

    > And with objectBoundingBox we are in a transformed coordinate system.

    My recollection was that objectBoundingBox simply changes what percentages lengths are relative to and makes all other length types factors, not that it creates an implicit transform. Unfortunately, you’re right, that’s exactly what the spec says it does. :-/

    Maybe the spec can still be changed in that regard though (to make objectBoundingBox only change the behavior of percentage lengths and raw numbers). I doubt anyone is using ‘mm’ etc. with objectBoundingBox, since such lengths are completely useless in that case. The bare number case will not be fixable though, since people certainly are using that.

Commenting is closed for this article.