I'm using a textPath and tspans to fit text into a svg path, and it works great in Chrome, but not so much in Edge and FF (o. Any help would be greatly appreciated
Here's a jsfiddle the svg node:
https://jsfiddle.net/ych9dr59/
And here's the relevant text code:
<text text-anchor="middle" font-size="8pt" font-family="Calibri" pointer-events="none">
<textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#text_5_4_5_1590" startOffset="50%">
<tspan dy="-14pt">12): Maintain a</tspan>
</textPath>
<textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#text_5_4_5_1590" startOffset="50%">
<tspan dy="8pt">policy that</tspan>
</textPath>
<textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#text_5_4_5_1590" startOffset="50%">
<tspan dy="8pt">addresses</tspan>
</textPath>
<textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#text_5_4_5_1590" startOffset="50%">
<tspan dy="8pt">information security</tspan>
</textPath>
<textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#text_5_4_5_1590" startOffset="50%">
<tspan dy="8pt">for all personnel. </tspan>
</textPath>
</text>
SVG text element is pretty buggy in general in my experience. My recommendation for maximum cross-browser sanity would be to use a separate text element for each text fragment and use normal x/y positioning and a transform/rotate to render your text.
Firefox is actually rendering correctly. According to the 1.1 spec, the start of each new textPath should be an absolute reset of the current text position. You should manually adjust the dy offsets of the tspans so they're cumulative (instead of 8pt in ever one, it should be 8pt, 16pt, 24pt). So it's actually a Chrome bug that your stuff works in the first place.
Edge only seems to support a single textPath element per text element, so you do need to wrap each textPath in its own text element.
Any solution, why IE and Chrome will be show my svg-sprite, but Firefox prefers to show nothing. There will be the place for the icon and on source code it will be showen, but it seems that firefox doesnt render it.
I include the svg and call the icom by this way
<svg class="icon icon-spoon-knife" viewBox="0 0 16 16">
<use xlink:href="/adminCSS/pic/sprite.svg#icon-spoon-knife">
</svg>
Again, chrome and IE show it, firefox wont...
Hope you can help!
Thank you
Try adding a width and height to your svg tag or CSS. I believe Firefox's table-cell sizing algorithm sets it to 0px × 0px if it's not declared.
<svg class="icon icon-spoon-knife" width="16px" height="16px" viewBox="0 0 16 16">
I have a javascript app (CAD like) build in SVG that have tools (objects build in SVG with Inkscape) that are inserted with the use tag. Everything works fine on Chrome and Safari (never tested in IE), but in Firefox, all objects that fill with gradients did not render. Like image below:
Firefox
Chrome
The tools are loaded like this (using external files)
<use
id="SvgjsUse1448"
xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="assets/images/neomap/tools/armchair.svg#armchair">
</use>
The gradients are defined in a separate svg inside the html page
...
<linearGradient xmlns="http://www.w3.org/2000/svg" id="armchair_SVGID_1_" y2="1911.6" gradientUnits="userSpaceOnUse" x2="1201.2" gradientTransform="matrix(1.0799475,0,0,1.2039969,15.269894,2.997636)" y1="467.91" x1="1201.7">
and apply like this
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" height="100%" width="100%" version="1.1" >
<defs>
<symbol id="armchair" viewBox="0 0 72000 54000">
<path style="stroke:#000000;stroke-width:6.84171867;stroke-miterlimit:10;fill:url(#armchair_SVGID_1_);" d="m2234.8,743.7s168.9,1406.4,0,1487.4c-188.77,90.42-1655.6,92.708-1844.3-0.4817-168.8-83.316,0-1488.9,0-1488.9v-182.09h1841l3.2398,184.09z"/>
...
</symbol>
</defs>
</svg>
It's a bug on Firefox? How can I workaround?
I had a similar problem and it turned out that mine was a real edge case, so I'm posting my solution here for the benefit of others.
My goal was to define a set of icons for later reuse in the document. I had defined the icons as nested svg documents inside a defs element:
<svg id="icons">
<defs>
<g id="atom-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<defs>
<linearGradient id="atom-41-a" x1="50%" x2="50%" y1="3.961%" y2="100%">
<stop offset="0%" stop-color="#FDFDFD"/>
<stop offset="100%" stop-color="#CBCBCB"/>
</linearGradient>
<linearGradient id="atom-41-b" x1="50%" x2="50%" y1="3.961%" y2="100%">
<stop offset="0%" stop-color="#B2E198"/>
<stop offset="100%" stop-color="#04A171"/>
</linearGradient>
</defs>
<g fill="none">
<circle cx="128" cy="128" r="127.858" fill="url(#atom-41-a)"/>
<circle cx="127.858" cy="128.142" r="116.907" fill="url(#atom-41-b)"/>
<path fill="#F2F8F6" d="M100.453 110.097a221.783 221.783 0 0 0-3.988 6.382 164.44 164.44 0 0 1-3.684-11.377c3.73-.535 7.695-.957 11.874-1.249a224.886 224.886 0 0 0-4.202 6.244zm103.138 7.475c-4.132-3.967-10.04-7.602-17.558-10.804-14.926-6.356-34.918-10.474-56.295-11.595a234.82 234.82 0 0 0-7.529-.277C138.53 75.415 154.292 65.05 163.472 64.7c1.944-.074 3.576.31 4.854 1.141 4.296 2.792 5.488 11.453 3.189 23.166a4.267 4.267 0 0 0 8.373 1.644c3.953-20.137-1.576-28.497-6.911-31.965-2.785-1.81-6.093-2.655-9.83-2.513-14.12.536-33.904 15.592-51.956 38.803-7.148.247-14.038.864-20.483 1.827a106.106 106.106 0 0 1-1.625-9.522c-1.619-13.344.367-22.816 5.312-25.337.794-.405 1.662-.639 2.654-.713 4.418-.332 10.652 2.637 17.542 8.359a4.267 4.267 0 0 0 5.452-6.565c-8.85-7.35-16.8-10.817-23.633-10.303-2.112.158-4.095.703-5.892 1.62-4.593 2.342-7.732 6.828-9.33 13.331-1.368 5.57-1.562 12.513-.576 20.636.39 3.213.96 6.556 1.695 9.998-5.04 1.062-9.71 2.356-13.897 3.869-18.316 6.616-22.544 15.337-22.866 21.488-.308 5.876 2.7 14.62 18.775 22.91a4.267 4.267 0 0 0 3.911-7.583c-9.247-4.77-14.41-10.193-14.165-14.88.346-6.605 11.417-13.596 30.274-17.535 1.747 6.309 3.99 12.861 6.68 19.505-6.777 12.723-11.722 25.262-14.286 36.416-1.833 7.97-2.369 14.89-1.592 20.567.906 6.63 3.558 11.418 7.881 14.228 2.205 1.433 5.176 2.553 9.079 2.553 5.658 0 13.275-2.357 23.343-9.538a4.267 4.267 0 1 0-4.955-6.948c-9.925 7.08-18.454 9.613-22.816 6.778-4.652-3.023-5.633-12.642-2.624-25.728 1.995-8.678 5.555-18.296 10.383-28.21a220.995 220.995 0 0 0 3.283 6.731c9.717 19.087 21.612 35.694 33.494 46.762 5.984 5.573 11.708 9.497 17.011 11.663 3.218 1.314 6.24 1.971 9.045 1.971 2.596 0 5.008-.563 7.216-1.69 4.43-2.259 7.511-6.52 9.157-12.665 1.41-5.263 1.726-11.827.942-19.512-1.543-15.11-7.253-33.539-16.077-51.891a4.267 4.267 0 0 0-7.69 3.697c8.407 17.485 13.833 34.908 15.278 49.06 1.27 12.447-.78 21.31-5.486 23.71-4.942 2.52-13.756-1.438-23.58-10.588-11.17-10.404-22.43-26.168-31.706-44.388a210.555 210.555 0 0 1-5.851-12.483 210.936 210.936 0 0 1 7.143-11.836 213.301 213.301 0 0 1 7.877-11.333c.7-.01 1.405-.017 2.115-.019 3.664-.012 7.592.09 11.688.305 20.404 1.07 39.368 4.95 53.399 10.925 12.34 5.256 19.534 11.704 19.244 17.25-.246 4.708-5.967 9.575-15.696 13.352a4.267 4.267 0 0 0 3.088 7.955c16.905-6.563 20.821-14.967 21.13-20.861.27-5.151-2.04-10.111-6.865-14.743v.001z"/>
<path fill="#F1F8F3" d="M119.194 129.133c0 5.153 4.174 9.33 9.323 9.33s9.323-4.177 9.323-9.33c0-5.154-4.174-9.331-9.323-9.331s-9.323 4.177-9.323 9.33"/>
</g>
</svg>
</g>
</defs>
</svg>
Which I used elsewhere in the document like so:
<li title="Atom">
<svg><use xlink:href="#atom-icon"/></svg>
</li>
In order to prevent the big list of icons references from rendering on screen, I had applied the following styles:
#icons {
display: none;
}
This caused, of all things, the url references to linearGradients to stop working. Probably the browsers removed them from the DOM tree because of display: none or some such effect.
The solution was the change the styles:
#icons {
height: 0;
}
That's a Chrome/Safari bug you're relying on.
url(#armchair_SVGID_1_);
is actually shorthand for
url(<this file>#armchair_SVGID_1_);
but there's no gradient in the armchair.svg file.
The definition of what a base URI is is in RFC3986 section 5 which says
Within certain media types, a base URI for relative references can be
embedded within the content itself so that it can be readily obtained
by a parser.
There's a note in the CSS specification referring to this which I think makes a clearer statement (at least for CSS since this is the CSS specification):
For CSS style sheets, the base URI is that of the style sheet, not that of the source document.
The file armchair.svg defines a base URI the same as any SVG document or CSS stylesheet does, it's the absolute URL used to access it.
Webkit browsers get this wrong. There's this bug for the CSS stylesheets case of this issue.
Use an absolute url or put the gradient in the use file (but not in the symbol part).
It's really a Chrome/Safari bug.
I figured out, that the problem goes away if you remove all the hyphens from the linearGradient elements' IDs. Simple as that. SVG then works with groups too ().
I would be glad, if that helps somebody...
Firefox is behaving correctly according to the spec for the SVG <symbol> element. With SVG any element that are nested inside a <symbol> element or <defs> element are not directly rendered with CSS, even with a <use> element. Only their attributes are. You are using the style attribute, which is CSS inside the <symbol> element.
You must use the SVG fill attribute directly to have it work inside a <symbol> element. Even though you are using a SVG <use> element. It is referencing SVG graphical elements inside a SVG <symbol> element with the CSS style attribute, which will not be rendered according to the spec, since the CSS display property does not even apply to the SVG <symbol> element.
This is not a bug in Firefox, Firefox honors the spec whereas Chrome and Safari which use webkit, do not follow the spec and allow it for now. But they will soon follow the SVG spec.
See these references and the spec:
W3C <symbol> spec: http://www.w3.org/TR/SVG11/struct.html#SymbolElement
‘symbol’ elements are never rendered directly; their only usage is as something that can be referenced using the ‘use’ element. The ‘display’ property does not apply to the ‘symbol’ element; thus, ‘symbol’ elements are not directly rendered even if the ‘display’ property is set to a value other than none, and ‘symbol’ elements are available for referencing even when the ‘display’ property on the ‘symbol’ element or any of its ancestors is set to none.
MDN Firefox <symbol> element reference: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/symbol
The symbol element is used to define graphical template objects which can be instantiated by a element. The use of symbol elements for graphics that are used multiple times in the same document adds structure and semantics. Documents that are rich in structure may be rendered graphically, as speech, or as braille, and thus promote accessibility. note that a symbol element itself is not rendered. Only instances of a symbol element (i.e., a reference to a symbol by a element) are rendered.
The spec states that SVG elements inside the <symbol> element are not directly rendered. In that case you need to change the actually attributes of those elements inside a <symbol> element or <defs> elements. So just change the SVG fill attribute instead on those elements inside the <symbol> element.
Ok, this is a bug, but also an interpretation from the W3 Spec. In this section is specified two types of IRI local, and non-local.
local IRI references, where the IRI reference does not contain an or and thus only contains a fragment identifier
non-local IRI references, where the IRI reference does contain an <absoluteIRI> or <relativeIRI> and thus represents a reference to an element within the current document.
What I see, is that Chrome/Safari are more flexible when dealing with the specification, allowing the local IRI to reference an external document, if it not exist in the current document.
The point is, Chrome/Safari doesn't render the gradients of an external SVG file (loaded by reference, in a use tag) that are at the same external file, only if the gradients are loaded in the current main html/xml document.
So, I create two files for each SVG tool, one for Firefox, and one for other browsers. And now another problem as came up, for low values of transform: scale() in a g element, or small SVG elements, the gradient disappear (transparent), and this I believe is a bug.
I am constructing an svg using D3.js. Inside it I am using <image> to place two types of images img1 and img2 where both have same width W but img1 is shorter than img2 i.e. H1<H2.
They should be placed within the outer svg in a rectangle with dimensions WxH2 at position (x,y) and the shorter one (img1) should be aligned vertically at the bottom of this rectangle like this:
This sounds like a job for viewBox & preserveAspectRatio so I tried creating a nested <svg> element with dimensions WxH2 (the larger of the 2 heights) at position (x,y) and depending on the image dynamically added each time, the layout (here shown with both images) would be:
Sample code with W=35, H1=19, H2=88, x=100, y=200:
```
<svg...> <!--outer SVG-->
<svg width="35" height="88" x="100" y="200" viewBox="0 0 35 88" preserveAspectRatio="xMidYMax meet"> <!-- nested SVG-->
<image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="img1_OR_img2" width="35" height="CORRESPONDING_img_HEIGHT"></image>
</svg> <!-- end of nested SVG-->
</svg> <!-- end of outer SVG-->
```
The problem is that the height of the nested svg is ignored and it's the height of the <image> that defines the height of the rectangle. So no matter what vertical alignment I ask for through preserveAspectRatio in the nested svg, in the case of the shorter image img1 it will not make a difference since the rectangle is already the height of the img1. If I have <image> always have the larger height H2, then the smaller image img1 appears vertically aligned in the middle.
Should I be using a whole different substructure instead of a nested svg or am I misusing the viewBox/preserveAspectRatio combo?
Note: regarding the topic viewBox & preserveAspectRatio, I used this article which is the best I've found online so far (kudos to Sara for an amazing article).
Your problem is that you are changing the heights. In both cases you should be using 88 for "CORRESPONDING_img_HEIGHT". You need to use the same viewport for both images and let SVG position the image within the viewport according to the preserveAspectRatio setting.
In fact, you don't need to be using nested SVGs. The <image> element also has a preserveAspectRatio attribute.
<svg xmlns:xlink="http://www.w3.org/1999/xlink">
<image x="100" y="200" width="35" height="88" xlink:href="img1" preserveAspectRatio="xMidYMax meet"/>
<image x="100" y="200" width="35" height="88" xlink:href="img2" preserveAspectRatio="xMidYMax meet"/>
</svg>
I embedded an SVG object in an HTML page as follows:
<embed id="svgImg" src="bo5rkbgs5vtsmv053regld2t14.svg"
type="image/svg+xml" />
However, the resulting image (both on Firefox and Chrome) is trimmed and it look like that:
(Notice how "Step Response" and "Time" do not appear properly). I have checked the file on the server side and it is fine. Any ideas?
Having had a second look at your code your svg image is still too small.
You need to set the height to 100% and the image height to 500px.
<embed id="svgImg" height="100%" type="image/svg+xml" src="s1d5ckv8bojltpturlonh1uap5.svg">
<svg width="576" height="500" viewBox="0 0 576 432" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
....
This fixes the problem in firefox v8.0
Just tweak your viewBox attribute so that it fits your image.
For example, you could try this:
viewBox="-10 -10 596 452"
Update:
To generate the viewBox dynamically with JS, something like this should work:
var bbox = document.documentElement.getBBox();
var viewbox = document.documentElement.viewBox.baseVal;
viewbox.x = bbox.x;
viewbox.y = bbox.y;
viewbox.width = bbox.width;
viewbox.height = bbox.height;
Note that this needs to be done on the svg document, so you may need to reach into it from the html document that embeds it, if so have a look at this example.