Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why does <g> not work in <clipPath> in svg?

Tags:

svg

The following code does not work:

<svg>
    <defs>
        <clipPath id="test">
            <g>
                <rect x="0" y="0" width="10" height="10"></rect>
            </g>
        </clipPath>
    </defs>
    <rect x="0" y="0" width="100" height="100" clip-path="url(#test)"></rect>
</svg>

But this does work:

<svg>
    <defs>
        <clipPath id="test">
            <rect x="0" y="0" width="10" height="10"></rect>
        </clipPath>
    </defs>
    <rect x="0" y="0" width="100" height="100" clip-path="url(#test)"></rect>
</svg>

In my project, I have some paths in the group tag and I want to reuse the group as a clipPath target and show the path at the same time. For example:

<svg>
    <defs>
        <g id="group">
            <path d="..."></path>
            <path d="..."></path>
            <path d="..."></path>
            <path d="..."></path>
        </g>
        <clipPath id="test">
            <use xlink:href="#group" fill="#000"></use>
        </clipPath>
    </defs>
    <!-- show the stroke of the group -->
    <use xlink:href="#group" stroke="#000"></use>
    <!-- at same time, clip the rect to make some animation as the background -->
    <rect x="0" y="0" width="100" height="100" clip-path="url(#test)"></rect>
</svg>
like image 291
Pathen Avatar asked Sep 11 '25 16:09

Pathen


1 Answers

Because the SVG specification says so

Content model:
Any number of the following elements, in any order:

    descriptive elements
    animation elements
    shape elements
    ‘text’
    ‘use’

Unfortunately <g> elements are not in that list.

Firefox used to support clipping <g> elements a long time ago till we noticed that we weren't a) acting per the specification above and b) compatible with other implementations so we restricted our clipPath implementation to be consistent. So if you got Chrome and Safari on board for a specification change we'd likely be OK with that.

Note that you can work around this by clipping a <use> element that points to a <g> element.

like image 156
Robert Longson Avatar answered Sep 14 '25 10:09

Robert Longson