How to move svg path out of html - html

I am using this example from Chris Coyer
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" mlns:xlink="http://www.w3.org/1999/xlink" style="display: none;">
<defs>
<g id="icon-image">
<path class="path1" d="M0 4v26h32v-26h-32zM30 28h-28v-22h28v22zM22 11c0-1.657 1.343-3 3-3s3 1.343 3 3c0 1.657-1.343 3-3 3-1.657 0-3-1.343-3-3zM28 26h-24l6-16 8 10 4-3z"></path>
</g>
</defs>
</svg>
<h1>
<svg viewBox="0 0 32 32">
<use xlink:href="#icon-phone"></use>
</svg>
Call me
However, I would like the path definitions to NOT be in the html as they will be used throughout the app.
Is this possible? (Note: I have read the answer that suggests javascript to manually inject the svg into the html. I don't want to do that either.)
I know there are many ways of embedding/linking SVG paths and files. And I have tried them all. In particular, I need to be able to style it to the currentColor. As covered in detail in this blog post, this cannot be done with external SVG files which are then used in an img tag.
So the closest thing I have found is this example above. However, I still don't want the path embedded in the html. If I could somehow get it in an external file of some type so it is reusable, that would be great.

Another option would be to convert SVG to a font
Searching the internet for "convert SVG to font" will give you a lot of sites/tools doing that, like:
https://icomoon.io/app/#/select
https://glyphter.com/
http://fontastic.me/
Also "HTML entities" have some reusable icons etc.
https://dev.w3.org/html5/html-author/charref

There's only one remaining option here. You don't want to embed the svg manually, you don't want to inject it with javascript and you don't want to use it in an img tag since you want to modify the properties with css. The only remaining solution would be to use your server-side language to inject it.
If you're using php, you can simply echo the content of your svg file where you want:
<?php echo file_get_contents(file_path); ?>

Another option I found is SVG Sprites, explained in detail by Chris Coyier
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8"/>
<style>
.icon {
width: 125px;
height: 125px;
background: #eee;
fill: currentColor;
}
body {
padding: 20px;
}
</style>
</head>
<body>
<div style="color: red">
<svg class="icon"><use xlink:href="menu.svg#beaker"/></svg>
</div>
<div style="color: brown">
<svg class="icon"><use xlink:href="menu.svg#fish" /></svg>
</div>
</body>
</html>
And then this in a separate file called menu.svg:
<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
<symbol id="fish" viewBox="0 26 100 48">
<path d="M98.5,47.5C96.5,45.5,81,35,62,35c-2.1,0-4.2,0.1-6.2,0.3L39,26c0,4.5,1.3,9,2.4,12.1C31.7,40.7,23.3,44,16,44L0,34
c0,8,4,16,4,16s-4,8-4,16l16-10c7.3,0,15.7,3.3,25.4,5.9C40.3,65,39,69.5,39,74l16.8-9.3c2,0.2,4.1,0.3,6.2,0.3
c19,0,34.5-10.5,36.5-12.5S100.5,49.5,98.5,47.5z M85.5,50c-1.4,0-2.5-1.1-2.5-2.5s1.1-2.5,2.5-2.5s2.5,1.1,2.5,2.5
C88,48.9,86.9,50,85.5,50z" />
</symbol>

Related

svg external stylesheet not work

I am new svg learner and try to animate svg file with external style sheet but fail fail to style my object 'Cube'.
[index.html file]
<head>
<link rel="stylesheet" type="text/css" href="cube.css">
</head>
<body>
<img src="cube-motion.svg" height="350px" />
<div class="logo">
<h1>SVG Cube Animation</h>
</div>
[cube-motion.svg file]
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="cube.css" ?>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" xml:space="preserve">
<g>
<polygon id="l1" class="st0" points="105.3,92.7 86.3,103.3 67.3,92.9 67.1,71.9 86,61.2 105.1,71.6 "/>
<polyline id="l2" class="st1" points="67.1,71.9 86.2,82.5 86.3,103.3 67.1,93.1 66.9,71.9 "/>
<animateTransform
attributeName="transform"
type="translate"
from="0 0"
to="0 75"
begin="0s"
dur="3s"
repeatCount="indefinite"
/>
</g>
</svg>
[external stylesheet file cube.css]
.st0 {
fill:#FF00FF;
stroke:#000000;
stroke-miterlimit:10;
}
.st1 {
fill:#23D83C;
stroke:#000000;
stroke-miterlimit:10;
}
.logo {
position: absolute;
left: 400;
top: 150;
}
You are on the right track with the inclusion of the external stylesheet inside the SVG:
<?xml-stylesheet type="text/css" href="cube.css" ?>
The reason it doesn't work is because the SVG is loaded in the HTML as an <img> which - rightfully - does not allow additional external assets to be processed.
If you're adamant on having the CSS from an external file, you have two options, either embed the SVG inside the html or use <object data=file.svg type=image/xml+svg></object>.
Depending on your use case, you basically have three ways to use CSS for styling:
<img src="my.svg">
Images are not interactive and are not allowed to load any other assets within themselves. Simple presentation of the referenced image file only.
It does allow to use CSS, but only from a <style>-element inside the SVG.
<object data="my.svg" type="image/svg+xml"></object>
Objects can do more than images, such as loading additional assets and even include isolated (within the loaded SVG) interactions (e.g. the CSS :hover-pseudoclass)
Loading an external CSS file is done as you have it in the example code, the <?xml-stylesheet...?>-instruction goes before the <svg>-tag
<svg...>...</svg>
Fully embedded in the HTML document, this is allows for full integration within the page (this may have benefits on the interaction side and downsides on the CSS side, as you'll then have to take style isolation into consideration), but also the least re-usable as you'd basically have to repeat the entire SVG, which doesn't matter if used once on a page.
Note that in order to embed the SVG inside the HTML document, you cannot put any of the SVG doctype and/or xml declarations in the HTML (<?xml...?>, <!DOCTYPE svg...> and <?xml-stylesheet...?>).
With embedded SVG, you can simply import (or inline) the style using the usual HTML <link> or <style> nodes, where the <style> element may also still be inside the <svg>-element.
Here's a quick sample of the difference between <img> and <object>

Is there a way to have SVG as data URL that contains an image with source from a non-data URL? [duplicate]

I have a page, that includes several SVG files. To synchronize the styling of those SVG files I wanted to create a single stylesheet to hold all styling information.
However, when including the SVG like below, the CSS wont get applied. Anybody having a solution to this or is it just not possible to link to other (CSS) files in an SVG referenced by <img src="..." />?
See the example code below. When loading pic.svg directly in the browser, all styles get applied and one can see a green rectangle. But when opening page.htm all there is to see is a black rectangle. So obviously none of the defined styles was applied.
page.htm
<!DOCTYPE html>
<html>
<body>
<img src="pic.svg" style="width: 100px; height: 100px;" />
</body>
</html>
pic.svg
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<?xml-stylesheet type="text/css" href="styles.css" ?>
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100"
>
<rect x="10" y="10" width="80" height="80" />
</svg>
styles.css
rect {
stroke: black;
fill: green;
}
EDIT
From an answer, that for a short time appeared here, I got this link to the spec and the following citation. In my opinion this states, that the above code should work!
Stand-alone SVG document embedded in an HTML or XML document with the ‘img’, ‘object’ (HTML) or ‘image’ (SVG) elements
[...]
Citing from your link "Style sheets defined anywhere within the referenced SVG document (in style elements or style attributes, or in external style sheets linked with the style sheet processing instruction) apply across the entire SVG document, but do not affect the referencing document (perhaps HTML or XHTML)."
An alternative is to use the <object> tag in your html :-
<object type="image/svg+xml" data="pic.svg" width="100" height="100"></object>
It's a BIG shame the <img> tag won't work. I don't want to mess about hacking with converting the SVG to a data URI. It's to do with cross-site vulnerabilities on indirectly loading resources and the use of an "Open Redirector".
Note that in my testing lastnight, the <img> tag method DOES work in IE10, but neither Chrome nor FireFox.
I don't know why <object> is allowed and <img> isn't. An oversight?
For privacy reasons images must be standalone files. You can use CSS if you encode the stylesheet as a data uri. E.g.
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<?xml-stylesheet type="text/css" href="data:text/css;charset=utf-8;base64,cmVjdCB7IA0KICAgIHN0cm9rZTogYmxhY2s7DQogICAgZmlsbDogZ3JlZW47DQp9" ?>
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100"
>
<rect x="10" y="10" width="80" height="80" />
</svg>
There are various online converters for data URIs.
The answers above are great. I found it simplest, though, to just embed the raw SVG tag itself on my webpage. This allowed the SVG to inherit font-family styles declared in my page's CSS without issue...

SVG use external source not working on firefox

I'm trying to make a SVG icon sprite, something like in this fiddle
http://jsfiddle.net/8ke8nsft/6
Only difference is on my app I use a relative URL "../images/svg-sprite.svg#home-icon" this works great on chrome and safari, but doesn't show up on firefox.
<svg class="home-icon">
<use xlink:href=../images/svg-sprite.svg#home-icon"/>
</svg>
Firefox works perfectly when I add the svg sprite inline on top of the page then use it
<svg class="home-icon">
<use xlink:href=#home-icon"/>
</svg>
and this is my SVG file
<svg>
<symbol id="home-icon" viewBox="0 0 512 512">
<title>Home Icon</title>
<path d="M512,296l-96-96V56h-64v80l-96-96L0,296v16h64v160h160v-96h64v96h160V312h64V296z"/>
</symbol>
</svg>
am I missing something here?
In order to better protect your security, Firefox only allows files to refer to other files if they are in the same directory or a sub-directory of the original file.
If you access content via a web-server then this restriction does not apply, however the web-server may impose other restrictions on file location.
I found my self troubled with this issues. I just realised that I'm missing xmlns="http://www.w3.org/2000/svg" from external svg file. So try to:
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="home-icon" viewBox="0 0 512 512">
<title>Home Icon</title>
<path d="M512,296l-96-96V56h-64v80l-96-96L0,296v16h64v160h160v-96h64v96h160V312h64V296z"/>
</symbol>
</svg>
And I think you would be fine
Please make sure you're running html in webserver. Directly it will not work.
Example:
Running it in webserver will work:
http://localhost/test/home/home.svg.html
Running without webserver will not work:
file:///C:/wamp64/www/test/home/home.svg.html
Further, please use "href" tag instead of "xlink:href". href tag is being deprecated with SVG2.
https://www.w3.org/TR/SVG2/linking.html
So new tag would be:
<svg>
<use href="home.svg#home-icon"> </use>
</svg>
In my document, I was missing a closing SVG tag. Worked in other browsers, but not Firefox. Fixing the problem SVG tag solved the issue, so check your source document to make sure it's valid SVG.
The attribute xlink:href is missing the first ' " '.

Reference an svg embedded in html in html document in same folder

I would like to reference an svg embedded in one html document in another html document in the same folder. I don't need a fallback, but I would prefer one. I have seen: HTML - pick images of Root Folder from Sub-Folder, and How to link html pages in same or different folders?, and Do I use <img>, <object>, or <embed> for SVG files?.
I have one html document with the svg that I would like to reference here: (this document is called "pd_unit_red_fighter_v.0.0" and is located in the same folder)
<!doctype html>
<html>
<head>
<title>Title</title>
</head>
<body>
<svg id="red_fighter" width="480" height="480" viewBox="0 0 24 24">
<g stroke-width=".25" stroke="#000" fill="#ccc" >
<circle cx="12" cy="12" r="11.5" fill="#800" />
</g>
</svg>
</body>
</html>
I have another html document and I would like this document to reference the svg in the other one:
<!doctype html>
<html>
<head>
<title>test</title>
</head>
<body>
<object data="red_fighter.svg" type="image/svg+xml">
<img src="./pd_unit_red_fighter_v.0.0.html" />
<a href="#./pd_unit_red_fighter_v.0.0.html" >
<img class="logo" src="red_fighter.svg" width="240" height="240"/>
</a>
</object>
</body>
</html>
I have tried both the object tag and but I cannot get it to work. Is there another tag I should use or am I using the wrong information? I am new to this so I apologize for my lack of knowledge.
When you reference an SVG file using an object or image tag it must actually be an SVG file and not svg data embedded in an html file so you want red_fighter.svg to be
<svg xmlns="http://www.w3.org/2000/svg" id="red_fighter" width="480" height="480" viewBox="0 0 24 24">
<g stroke-width=".25" stroke="#000" fill="#ccc" >
<circle cx="12" cy="12" r="11.5" fill="#800" />
</g>
</svg>
Note the namespace attribute which is mandatory for standalone SVG files.
Then you can reference it using an object or img tag.
Take care that the svg file is served with the correct mime-type (try viewing it directly to check it works first).

SVG <use> elements in Chrome not displayed

Chrome seems not to display <use> elements in inline svg. Here is an example (code below or view it at http://www.bobwyttenbach.com/chromeuse.html):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Chrome use-tag bug?</title>
</head>
<body>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="200px" height="200px" viewBox="0 0 200 200">
<defs>
<g id="test1">
<circle cx="100" cy="100" r="50" fill="red"/>
</g>
</defs>
<g>
<rect x="0.5" y="0.5" width="199" height="199" stroke="black" fill="none"/>
<use xlink:href="#test1" x="0" y="0"/>
</g>
</svg>
<p>Above is inline svg with a use tag; below is the same svg linked through an object tag. Below is correct.</p>
<object data="chromeuse.svg" width="200" height="200"></object>
</body>
</html>
The red circle does not appear in the inline svg but does appear when the same svg is linked through an object tag. Safari, Firefox, Opera, and Internet Explorer 9 all display the inline svg correctly.
Am I doing something wrong? Is this a known Chrome bug (I haven't found it listed)? Any workarounds?
Don't know if this question is still relevant, but I've met such a case recently and I pretty sure that somebody else will meet the case (especially those who tries to make use of SVG sprites for the first time).
In my case I've joined 16 SVG icons in one sprite manually into sprite.svg, and in this file I've omitted important meta information:
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
I had no first line at all, and all I had on the second line was an opening <svg> tag with no meta attributes (xmlns and xmlns:xlink). As soon as I brought back all this omitted meta information, my graphics from sprite.svg started to display properly.
Hope it helps someone.
Ok so I deleted my last post as I incorrectly tried to figure out why the use element was working for me and not for you. What I can say is that I am using a modified version of this source, https://code.google.com/p/svg-edit/ , so in short, my answer is to walk through and see how they do it. I believe its demonstrated when you insert an image from their library.
I spent a long time debugging inline svg use elements not showing up. The chrome bug discussed by BobW seems fixed at this time. To eliminate the same issue caused by something else entirely, try commenting out the <base href="somethingsomethingsomething" /> tag from your HTML.
Of course, this will likely break every relative link on your site, but the <use> elements now show up. One step forward, half a step back :)
Related info here:
Using base tag on a page that contains SVG marker elements fails to render marker