Jaka Dirnbek
Jaka Dirnbek

Reputation: 155

Unexpected behaviour of <use> in svg

I stumbled upon a problem. I am using Chrome 34.0.1847.116 m - latest verstion.

The <use> seems to work OK on <circle> but not on <foreignObject> tag.

<svg height="400" width="400">
    <foreignObject id="first" x="120" y="120" width="180" height="180">
        <div xmlns="http://www.w3.org/1999/xhtml" style="height: 800px">
            <ul>
                <li><strong>First</strong> item</li>
                <li>
                    <em>Second</em> item
                </li>
                <li>Thrid item</li>
            </ul>
        </div>
    </foreignObject>

    <!--<circle id="first" cx="150" cy="50" r="100" fill="lime" />-->


    <polygon id="second" class="poly-in" points="300,200 200,300 100,200 200,0" style="fill:blue;stroke:purple;stroke-width:1" />

    <use id="use-first" xlink:href="#first" href="#first" />

    Sorry, your browser does not support inline SVG.
</svg>

This doesn't work (bug) ...
But, I can get <use> to work when referencing a <circle>
And, I can get <foreignObject> to work when not referenced by a <use>

I am very confused and don't know if I am misunderstanding something or is it a bug. I've been reading w3c paper on SVG and cannot figure it out.

I am looking identical behaviour than in example 2 but for the code posted here with <foreignObject>.

Upvotes: 0

Views: 200

Answers (2)

AmeliaBR
AmeliaBR

Reputation: 27544

The "unexpected behaviour" is actually an expected -- if not very well documented -- limitation of the <use> element.

The W3 specs you linked to only allow to reference , or a graphics element -- a <foreignObject> tag is not a valid reference for <use>.

You could technically get around the specs by referencing a <g> or <svg> tag which then contains the <foreignObject> as a child. However, most browsers don't support foreign objects in a <use> element however it is worded.

Although your example of a bulleted list is harmless, there would be serious implementation difficulties from supporting arbitrary copies of any and all HTML, especially when you factor in the way style properties are supposed to be inherited from the <use> element. See this thread on the W3 SVG mailing list for more discussion (use the "next in thread" link to read all the responses).

Browsers currently have enough problems with interactive graphics properties and <use> elements, I would not expect to see an extension of <use> to foreign objects any time soon (although hopefully SVG2 will have clearer language indicating that it isn't possible).

Working around the issue will really depend on the specifics of what you're trying to do. @gilly3 made some suggestions. You may need to resort to Javascript if you want to copy a large chunk of HTML for use in multiple contexts.

Upvotes: 2

gilly3
gilly3

Reputation: 91497

If you wrap your <foreignObject> in a <switch> and add a corresponding fallback element (such as <text>) you can reference the <switch> from the <use> and the fallback element will display. Obviously, this is less than ideal. And it doesn't work in FireFox or IE.

http://jsfiddle.net/Uz6XZ/4/

As an alternative, if your goal is just to bring the <foreignObject> to the front, I've found you can do so by specifying position: relative on the <div>. That's a bit of a hack and only works in Chrome, not FireFox or IE.

http://jsfiddle.net/Uz6XZ/3/

Upvotes: 1

Related Questions