Svg Foreignobject Contents Do Not Display Unless Plain Text

SVG foreignObject contents do not display unless plain text

Since you're using d3 you need to tell d3 that the div is a html div and not some element in the svg namespace. Try

.append("xhtml:div")

SVG foreignObject not showing on any browser, why?

2019 year answer:

  • foreignObject should have x, y, width and height defined
  • add xmlns:xhtml="http://www.w3.org/1999/xhtml" to your <svg ... tag definition
  • all your HTML tags inside SVG should start with xhtml: prefix

Example:

<svg class="front" viewBox="0 0 376 244" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xhtml="http://www.w3.org/1999/xhtml">
...
<foreignObject x="0" y="165" width="100%" height="38">
<xhtml:span class="copy-popover">Click to Copy</xhtml:span>
</foreignObject>
...
</svg>

HTML element inside SVG not displayed

Short answer

Specify the namespace in all tags in a foreignObject: replace .append("p") by .append("xhtml:p") and it will work: http://jsfiddle.net/EHzcR/2/


Long answer

In the context of foreign objects, <p></p> is not recognized as a xhtml paragraph. Why? Simply because the namespace xhtml is not included in the foreignObject context (a foreignObject might contain anything (xml formated data for example) so it doesn't consider the input as html if you don't explicitly say it.).

So the p tag is considered as a custom tag, not as a xhtml tag. Thus, as the web browser doesn't recognize the tag p in the tags it knows, so it just doesn't interpret it and its content, even if it exists, it won't throw an error as well because this content might be totally valid, just not for its direct use.

It is fun to see that you always specify the namespace svg even if it is not necessary and how we all forget that the p, div... also have a very popular namespace.

The selection.html() function doesn't work because in its implementation it uses the .innerHTML() function of the element, but here, the foreignObject, not being an html element, doesn't have such a function.

foreignObject display:block not working in chrome

It appears, from my tests on Mac OS X, that Chrome doesn't support foreignObjects at least not with your required extension. I've tried your source, and also taken this example from mdn:

https://developer.mozilla.org/en-US/docs/Web/SVG/Element/foreignObject

<svg width="400px" height="300px" viewBox="0 0 400 300"
xmlns="http://www.w3.org/2000/svg">
<desc>This example uses the 'switch' element to provide a
fallback graphical representation of a paragraph, if
XHTML is not supported.</desc>
<!-- The 'switch' element will process the first child element
whose testing attributes evaluate to true.-->
<switch>
<!-- Process the embedded XHTML if the requiredExtensions attribute
evaluates to true (i.e., the user agent supports XHTML
embedded within SVG). -->
<foreignObject width="100" height="50"
requiredExtensions="http://www.w3.org/1999/xhtml">
<!-- XHTML content goes here -->
<body xmlns="http://www.w3.org/1999/xhtml">
<p>Here is a paragraph that requires word wrap</p>
</body>
</foreignObject>
<!-- Else, process the following alternate SVG.
Note that there are no testing attributes on the 'text' element.
If no testing attributes are provided, it is as if there
were testing attributes and they evaluated to true.-->
<text font-size="10" font-family="Verdana">
<tspan x="10" y="10">Here is a paragraph that</tspan>
<tspan x="10" y="20">requires word wrap!</tspan>
</text>
</switch>
</svg>

Now it's feasible that the MDN example has something that just doesn't work with Chrome, but for me I only get the text fallback rendering in Chrome Version 28.0.1500.71

Does your xhtml embed work in Chrome without the display:none?

Update

From my tests you can get the above example to work if you remove the requiredExtensions attribute. Obviously this is probably not a great idea, as it is my understanding that that attribute is there to make sure the content can be rendered properly by the user agent. However, if your target audience is only ever going to be browser-based you can probably make a good assumption that the UA will be able to support basic XHTML. Now as to whether certain UAs need that attribute to understand the embed content, that's a different story.

It is feasible that there is a correct namespace to use that both Firefox and Chrome will support, this answer could be interesting:

<textarea> inside <foreignObject> handles as expected in Chrome but not Firefox

However, it does seem that foreignObjects still cause issues around the web, so it could just be the browser vendors need to improve their support.

Update x2

So far I've got the following to work in both Firefox and Chrome now it would seem, strange thing this foreignObject ;)

<!DOCTYPE html>
<html>
<style>
svg {
position: relative;
}
.tooltip {
display: none;
position: absolute;
left: 0;
top: 0;
width: 350px;
padding: 5px;
font-size: 11px;
text-align: left;
color: rgb(0, 0, 0);
background: rgb(204, 204, 204);
border: 2px solid rgb(153, 153, 153);
border-radius: 5px;
text-shadow: rgba(0, 0, 0, 0.1) 1px 1px 1px;
box-shadow: rgba(0, 0, 0, 0.1) 1px 1px 2px 0px;
}
svg:hover .tooltip {
display: block;
}
</style>
<body>
<svg width="400px" height="300px" viewBox="0 0 400 300"
xmlns="http://www.w3.org/2000/svg">
<foreignObject id="foo" height="700" width="370" y="0" x="0">
<span xmlns="http://www.w3.org/1999/xhtml" class="tooltip">
<div><b>Comments</b></div>
</span>
</foreignObject>
</svg>
</body>
</html>

SVG foreignObject not showing in Chrome

You need to have an HTML body be the sub-element of foreignobject. Once you have that you can put anything inside the body.



Related Topics



Leave a reply



Submit