Most efficient way to add inline SVG? - html

I have a webpage with lots of SVG icons that will be in the HTML. Rather than include them as an IMG tag and possibly slow the page with those HTTP requests, I'm placing the SVG code like this:
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="9" viewBox="0 0 9 9"><path fill="#C5C2BD" fill-rule="nonzero" d="M4.5 3.435L1.286.22A...LOTS OF CODE HERE..."/></svg>
Note: where it says "lots of code here", there is a huge string of numbers/letters that make up the path for this SVG.
The issue this creates is it's very ugly when not easily maintainable in the HTML (to the point where my editor bogs own because these SVG strings are so long).
Is there a cleaner, simpler way to include these SVG icons in my HTML while still eliminating the extra HTTP requests?
Thanks for your time.

The most proven way is to collect all the icons SVG in one file - the sprite SVG
Creating a Sprite and connecting it to HTML
The action plan is as follows:
Creating a Sprite
Connecting it to HTML
Calling SVG images from the sprite
Styling icons
Creating a Sprite
The main task of the sprite is to be a repository for icons that before the call to a specific place HTML pages should be invisible.
To do this,the code for each icon is wrapped with <symbol id =" .. "> ... </ symbol> tags with a unique identifier, which will be followed by the <use>
Template Sprite:
<div id="container">
<svg version="1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 126 126" >
<symbol id="picasa">
<path d="M113.5 57.... 72.8z" />
</symbol>
<symbol id="wordpress" viewBox="0 0 126 126">
<path stroke ="black" d="M113.5 57.7l-8.5-11.4 .. 86.1 62.9z"/>
</symbol>
<symbol id="twitter">
<path d="M113.5 57.6l-8.5-11.4.... 7.4-2.4V85.4z"/>
</symbol>
<symbol id="apple">
<path d="M113.5 57.7l-8.5-11.4... 78.5 78.7 82z"/>
</symbol>
</div>
As you can see, all <path> attributes are removed for later styling of icons from an external CSS file.
Adding a sprite file to HTML
There are several ways to add SVG files to HTML, but the most reliable way is to add it using the <object>
<object type="image/svg+xml" data="Sprite.svg" width="200" height="200">
Your browser does not support SVG
</object>
Adding icons from the sprite
<div id="container">
<svg viewBox="0 0 126 126" >
<use xlink:href="#apple"></use>
</svg>
</div>
The viewBox attributes should be like thesvg icon or change the scaling inside HTML if necessary.
Icons as links
For this, in SVG, unlike HTML, its own form of record
<svg viewBox="0 0 126 126" >
<a xlink:href="https://www.apple.com/ru/"><use xlink:href="#apple"></use></a>
</svg>
Styling icons
When using the <use> command, the icon falls into the shadow DOM and its attributes behave strangely, - there is an icon of the icon, but it can not be controlled from the outside.
In addition, the icon attributes for example: style = "fill: gray; stroke: crimson;" have the highest priority. Therefore, we deleted these attributes. see the example of the sprite above.
To solve the problem of inheritance of parental properties by objects in shadow DOM, you must use forced inheritance
svg path{
fill:inherit;
stroke:inherit;
}
and then to the icons you can already apply CSS rules from the external table
svg path:hover{fill:yellow;}
#picasa{fill:black;}
#apple{fill:purple;}
#twitter{fill:black;}
#wordpress{fill:blue;}
If you go for the first time along this path, then inevitably there will be many questions.
Ask, do not be shy.
All sooner or later it turned out to be done and customized sprite.
The main recommendation is to do everything yourself manually for the first time, to understand how it is arranged, and then you can already openly use special utilities to automatically create sprites.

You should convert all your .svg files to one font file, here is how:
How to convert .svg files to a font?

Related

Relative path in SVG to embed <image> when loaded from HTML [duplicate]

This question already has an answer here:
How many levels of recursion does SVG support?
(1 answer)
Closed 1 year ago.
i have created an SVG which has an image embedded.
I did this because i want the descriptions to be scalable.
The problem is, when i load the SVG only in chrome, the image is displayed.
When the svg is embedded in an img tag in the html though, i dont see the image.
When i write the svg code in the html file on the other hand the image is displayed.
I think the problem might be a pathing issue but im not sure as i dont get any errors displayed.
The SVG and IMG are in the same folder.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1189.851"
height="539.932">
<image overflow="visible" width="1190" height="540" href="/pics/mashup/e-55211-10-piww-000.png"
transform="translate(0 -.034) scale(.9999)"/>
<g stroke="#1D1D1B" stroke-width="4.693" stroke-miterlimit="10">
<path fill="#FFF" d="M998.689 395.155l-10.44 21.628-67.39-33.204 10.454-21.633z"/>
<path fill="#FFF" d="M911.808 448.549l-22.247-8.621 26.866-70.699 22.247 8.625zM889.081
449.676h23.832v36.11h-23.832z"/>
<path fill="#FFF" d="M920.424 447.646c-2.273 10.825-12.828 17.741-23.553 15.44-10.729-2.301-17.576-12.942-
15.299-23.79 2.283-10.839 12.828-17.75 23.563-15.45 10.715 2.305 17.572 12.952 15.289 23.8zM1012.159
414.767c-4.812 9.959-16.71 14.093-26.559 9.24-9.863-4.854-13.955-16.857-9.148-26.825 4.804-9.959 16.696-
14.089 26.555-9.239 9.858 4.857 13.951 16.861 9.152 26.824zM946.415 380.806c-3.928 10.345-15.413 15.514-
25.66 11.55-10.229-3.969-15.34-15.577-11.417-25.917 3.933-10.34 15.422-15.514 25.656-11.545 10.248 3.968
15.362 15.564 11.421 25.912z"/>
<path fill="none" stroke-linecap="round" d="M980.243 420.437c-6.976 7.153-6.77 18.754.453 25.931M1009.065
446.372c6.972-7.159 6.774-18.75-.444-25.94"/>
</g>
I tried both and they dont work when loaded from an img tag, but do work when opened in browser or inspecting the element:
href="/pics/mashup/e-55211-10-piww-000.png"
href="e-55211-10-piww-000.png"
Thats how i want it to work.
<li class="c-linkedarea" data-content="img2 img" data-display="flex">
<img src="/pics/mashup/e-55211-10-piww-000.svg" alt="Microwall VPN Funktionsgrafik">
</li>
Thanks in advance
The solution to your question has been perfectly addressed by Erik Dahlström in his post here
Here is what CSS tricks has to say about it:
If “inline” SVG just isn’t your jam (remember it does have some legit drawbacks like being hard to cache), you can link to an SVG file and retain the ability to affect its parts with CSS by using .
Basically, you need to put your svg source inside the html <object> element like below:
<object data="pathToYourSVG.svg" type="image/svg+xml">
<img src="backUpImgFileIfSVGDoesNotWork.jpg" />
</object>

How to use the whole SVG with a <use> tag?

I have an SVG file freshly exported from Figma.
I don't want to inline it because it's used on multiple places.
I can't specify it as <img src="..."> because I need to style its parts.
So, I tried to include it like this:
<svg>
<use xlink:href="http://example.com/myshape.svg"></use>
</svg>
But it doesn't work. MDN states:
The <use> element takes nodes from within the SVG document, and duplicates them somewhere else.
It takes nodes from the document. With SVG sprites, you have <symbol> tags with id attributes and you reference them with <use> by adding xlink:href="mysprite.svg#symbolid". However, here I need to use the whole document, I.E. the root node. Is there a way to do that?
It would also be great if I don't have to edit the source SVG file, as it's uploaded via an admin panel by the user. It's just a file exported from any vector graphics program.
SVG 2 (when implemented in browsers) will allow to reference another SVG file without any fragment identifier:
New in SVG 2: An href without a fragment allows an entire SVG document to be referenced without having to ensure that it has an ID on its root element.
Before:
<!-- my-vector.svg -->
<svg id="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<circle r="10" cx="12" cy="12" />
</svg>
<use href="my-vector.svg#icon"></use>
After (there will be no need to define id="..." on the svg):
<!-- my-vector.svg -->
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<circle r="10" cx="12" cy="12" />
</svg>
<use href="my-vector.svg"></use>
SVG 2 seems to be in the process of development in major browsers (see this Chrome feature and specifically this Chromium issue: Issue 366545: [SVG2] Allow to reference entire files).

How to use SVG for icons properly / best practices

I'm looking for an advice about work with SVG images, respectively icons.
What I've tried
If I'm using PNG icons, the CSS is like:
elem:after {background: url('icon.png'); ...}
I've tried the same way
elem:after {background: url('icon.svg'); ...}
but it isn't what I'm looking for. This solution lose advantages of SVG icons (they're small and blured, fuzzy).
What I have
I've generated this code online using Icomoon app.
<svg aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="icon-love" viewBox="0 0 33 32">
<title>love</title>
<path d="M32.916 15.597c0.604-0.66 ..."></path>
</symbol>
<symbol id="icon-shop" viewBox="0 0 34 32">
<title>shop</title>
<path d="M17.148 27.977c-..."></path>
</symbol>
</defs>
</svg>
<svg class="icon icon-shop">
<use xlink:href="#icon-shop"></use>
</svg>
My question
Is it semantically correct to put icons into HTML markup, instead of putting them into CSS?
Across whole website there is about 60 icons, any unique, any are repeated more times. Generated markup above has about 50kB.
Can I put all icons into general layout template and load them all in whole website, or include just icons I use in the page?
Here I've found How to change color of SVG image using CSS (jQuery SVG image replacement)? (3 years ago), but don't know if it's the right way.
How to cache SVG properly? Is it posible when I use it like I'm writing above?
I read many articles, but not definitely sure how to do that best way.
Thanks for advice.

How to <use> the <svg> element correctly for loading external sources?

I've followed many guides to adding external SVGs to a page... like this one : http://wearejh.com/design/inline-svg-use-element/
The code is like this:
<svg>
<use xlink:href="https://upload.wikimedia.org/wikipedia/commons/5/53/Skull_and_crossbones.svg"></use>
</svg>
It just does not load, example here: http://jsbin.com/cipacitovo/edit?html,output
What am I doing wrong?
Per the SVG specification
Unlike ‘image’, the ‘use’ element cannot reference entire files.
You need to add a fragment identifier to the URL to indicate which item within the image you are trying to display.
Why dont you use svg in img tag.Because you are not generating anything instead you are loading.
Check the example
You forgot to add xmlns:xlink="http://www.w3.org/1999/xlink" in <svg>.
This is how it should be:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<use xlink:href="https://upload.wikimedia.org/wikipedia/commons/5/53/Skull_and_crossbones.svg"></use>
</svg>

How to create hoverstates with svg <use> tag

So I recently found this svg technique on csstricks and decided to use it in conjunction with the grunt task grunt-svgstore. I thought this was the perfect thing since you have access to the actual svg with css and javascript without pasting the whole svg code in the html. But I found one major problem I can't solve which is hoverstates (and similar). The problem is the following. If that's my html body (with the svg on top)
<body>
<svg>
<symbol id="arrow">
<path ... />
</symbol>
</svg>
<svg id="icon-arrow">
<use xlink:href="#arrow"></use>
</svg>
</body>
I can access the #icon-arrow svg or the #arrow symbol but neither will give me the ability to create a hoverstate. When doing #icon-arrow I can get a hoverstate but I can't access the actual shape because it is not actually a child of the #icon-arrow so doing #icon-arrow #arrow:hover won't work. On the other hand directly selecting the shape doesn't work because the shape is not actually there but it's only a reference. Is it actually possible to do hoverstates using this technique? Or are there any other solutions?