I have a sprite of SVGs and a list of icons/logos in my database.
I loop through all of them and use a templating engine to generate my icons, such as:
<div class="partsvg__container">
<svg class="partsvg__wt-icon partsvg__wt-icon--{{icon}}">
<use xlink:href="svg/icons.svg#wt-icon-{{icon}}"></use>
</svg>
</div>
I might not have a SVG for every item in the database, and in that case the template renders an empty space.
How do I do so that if (for instance) svg/icons.svg#wt-icon-stackoverflow is not present in the spite, to still show a default one (ie: svg/icons.svg#wt-icon-default)?
I found a solution!
You can insert a symbol in your svg for the "not found case". In this way, if the symbol isn't found, a placeholder will be draw in the background.
<div class="partsvg__container">
<svg class="partsvg__wt-icon partsvg__wt-icon--{{icon}}">
<use xlink:href="svg/icons.svg#wt-icon-{{'Placeholder'}}"></use>
<use xlink:href="svg/icons.svg#wt-icon-{{icon}}"></use>
</svg>
</div>
Related
I have an svg sprite and I import icons using <svg> and <use>.
I'm wondering if it's generally better to put the title in the import point or in the svg sprite.
If I think one title assigned to an svg icon in a sprite can semantically fit all use cases, is it ok to leave it in the sprite?
And what if I have one title in the sprite and add a second more accurate title at the point of import - is that still acceptable? If not, I would end up with some icons having a title only in the sprite and some only in the import point.
Svg import point:
<svg>
<title>Call us</title> // PUT TITLE RATHER HERE?
<use href="../resources/icons/sprite-all.svg#call"></use>
</svg>
Svg sprite:
<svg width="0" height="0">
<symbol id="call">
<title>Call us</title> // OR PUT TITLE RATHER HERE?
<path d="M39.977 (...other values)"></path>
</symbol>
</svg>
It is a question of the semantics of your use case where you define a <title>. There is only one thing you should be very carefull about: if you define a title in the symbol and where the icon is quoted, the result could very easily not be what you expect.
The symbol, at the time of being inserted, is treated as a (shadow) child element of its <use> element. This means, the icon together with its title, is a child of the surrounding <svg> element and its title. The "child" title is triggered to be shown when a pointer hovers over the icon shape (the black circle), but the "parent" title is active when over the content box of the parent (the yellow square).
If the <title> is defined for the <use> element (black circle over green square), the "parent" title would also only be triggered over the icon shape, but is overridden by the "child" title, and it's never shown.
In both cases, the generalized point of definition title overrides the specialised point of use title. There is only one way to avoid this, and that is to suppress the "child" title by setting pointer-events to none. But be careful, the "parent" title then must be set on the <svg> element (the red square).
Even more, as a CSS operation, this has no effect on assistant technologies. For them, you have to explicitely hide the icon with aria-hidden="true".
<svg width="0" height="0">
<symbol id="icon" viewBox="0 0 50 50">
<title>Point of definition</title>
<circle cx="25" cy="25" r="20" />
</symbol>
</svg>
<!-- conflicting titles -->
<svg width="100" height="100" style="background:yellow">
<title>Point of use</title>
<use href="#icon"></use>
</svg>
<!-- specialized title overridden by the generalized -->
<svg width="100" height="100" style="background:lightgreen">
<use href="#icon">
<title>Point of use</title>
</use>
</svg>
<!-- generalized title hidden in favor of the specialized -->
<svg width="100" height="100" style="background:lightpink">
<title>Point of use</title>
<use href="#icon" style="pointer-events:none" aria-hidden="true"></use>
</svg>
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>
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?
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>
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?