7
votes

I have a problem with SVG's foreignObjects elements on Safari. I am working with SVG elements and what I am using d3.js library.

What I did is to append on canvas a foreignObject element because differently from rect or other SVG elements didn't allow to put html elements inside. Now, after some days of development I noticed that it seems that Safari doesn't allow to put html elements inside a foreignObject. Better, it allows to do and all seems to work according to the inspector, but the I put inside the foreignObject has a background set.

The result is that I can correctly drag the foreignObject and the div inside inside the canvas but differently from Chrome or Firefox, the div's background stay on the canvas top left corner not following the div.

Here below I paste the portion of the style and foreign object code I append to the canvas

SVG

<foreignObject transform="translate(304,215)rotate(-174.86597769360367)" height="180" width="40" class="dragging">
<div class="new-rect" style="background-image: url(data:image/png;base64,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); left:-45px;">
</div>
</foreignObject>

Style

foreignObject{
    cursor:pointer;
    position:relative;
}
foreignObject div.new-rect{
    position: absolute;
    top: -8px;
    background-repeat: no-repeat;
    background-size: auto;
    height: 180px;
    width: 130px;
}

On Safari (mobile and desktop) background is away its div

That's all. I think I am doing something that Safari doesn't like. But question is .. what ?

6
You may need to add a namespace to the HTML div, e.g. <div xmlns="w3.org/1999/xhtml"> I've also had some problems when the foreignObject's x and y aren't both set to "0"Ian
@Ian not working for me. I solved using html elementsPierpaolo Ercoli

6 Answers

16
votes

Setting position: "fixed" on the div inside foreignObject fixed the foreignObject position for me in Safari (as well as on Chrome on iOS). It doesn't seem to scale the foreignObject according to the scaling of the SVG though

1
votes

I've found that you need to insert a <body> element to get it work in Safari, like this:

<foreignObject width="170" height="28">
    <body xmlns="http://www.w3.org/1999/xhtml">
        <div>my content</div>
    </body>
</foreignObject>
1
votes

You can use <image> element in SVG instead of <foreignObject>. This can solve the scale and position issue easily to avoid <foreignObject> bug on Safari

Remember to change the src attribute to href.

0
votes

Try wrapping your foreignObjects in group elements. I found that trying to style foreignObjects with transforms doesn't work well in Safari. Also most SVG's don't work in canvas elements in Firefox.

<g transform="translate(304,215)rotate(-174.86597769360367)">
    <foreignObject>
        <div> whatever in here </div>
    <foreignObject>
</g>
0
votes

Try adding in an inline width and height for the foreignObject. This seems to work on Safari.

<foreignObject style="overflow: visible;" y="0" x="0" width="240" height="160">
    <div class="info-panel" xmlns="http://www.w3.org/2000/xmlns/" >
        <div class="panel-text" xmlns="http://www.w3.org/2000/xmlns/">
    <h1>ForeignObject</h1>
    <p>For this to work in Safari try adding in a width and height inline on the foreignObject element. The background will also expand to the more text you add.</p>
            </div>
    </div>
</foreignObject>

Demo https://codepen.io/chrisgannon/pen/2107d092ec56025bba036934d680f2bc

0
votes

I found a weird bug with iOS Safari regarding foreignObject. When I set the opacity in CSS for the HTML content within the foreignObject (it was a button in my case) it would position it absolutely over the SVG. But it positioned as expected when I removed the opacity. Took me hours to debug this issue.