Edit: this questions is irrelevant in case you're using Font Awesome v. >= 5.8.0 because its maintainers (after a long discussion:)), agreed that the "title" should be removed from the svg files and it's done in v. 5.8.0 : https://github.com/FortAwesome/Font-Awesome/issues/14595
Now, back to the original question:
I just tried the Font Awesome (5) in its 'svg sprites' version, following the official, pretty simple tutorial: https://fontawesome.com/how-to-use/on-the-web/advanced/svg-sprites
Everything's working as expected, except I can see a title popping up when I hover on the image (which is bad). I mean the one we see when we have e.g. <div title = "blah"></div>.
So, in compliance with the docs (I guess), I have copied the 'sprites/regular.svg' file to my server and:
<svg class = 'fa-svg-icon' title = 'my failed attempt to overwrite the title'>
<use xlink:href="icons/font-awesome/sprites/solid.svg#user"></use>
</svg>
The '.fa-svg-icon' class, for the sake of completeness:
.fa-svg-icon{
width:1em;
height:1em;
}
What I see, when hoovering the image, is a title "User" showing up. That's is because this is what is declared in the svg file, in "our" fragment:
<symbol id="user" viewBox="0 0 448 512">
<title id="user-title">User</title>
<path d="M224 256c70.7 0 ......"></path>
</symbol>
I tried adding title = 'something' to both the svg element, and the <use> one, but nothing works o.O
This happens on both FX and Chrome.
Edit 1: I made a test page: https://kpion.github.io/stuff/font-awesome-issue/
I'm pretty sure I'm missing something obvious here, because apparently I'm the only one in this world having this problem 😮 Or google is broken. One or the other :)
Edit 2:
To answer a question from comments, here is what my dev tools -> elements in chrome shows (after 'importing' the svg symbol):
<svg class="fa-svg-icon" title="my -not-working-title for user">
<use xlink:href="icons/font-awesome/sprites/solid.svg#user" title="blah - doesn't work either"></use>
#shadow-root (closed)
<svg id="user" viewBox="0 0 448 512" width="100%" height="100%">
<title id="user-title">User</title>
<path d="M224 256c70.7 0 128-57.3 128-..."></path>
</svg>
</svg>
And no, it does not change when hovering, please bear in mind there is no js involved, either mine or from font awesome.
I'm not able to recreate your code environment in a fiddle to try it myself, but you may try the following CSS code, to get the pointer-events only when the icon has a link:
.fa-svg-icon{
pointer-events: none;
}
.fa-svg-icon a {
pointer-events: auto;
}
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.
I am planning to use inline svg concept to create svg spritesheet for a project.
There are actually many ways to create svg spritesheet. I preferred two methods (because of performance) to create spritesheet. they are as follows:
Group all the svgs to single svg by wrapping each svg's content using symbol tag with unique ID, so that later we can refer this using use tag in HTML.
Generate a css file having all the svgs referred through css background-image property. each svg will have a unique class name.
Now, I am in dilemma of which method to use exactly. FYI, this is not opinion-based question because I am not looking for opinions but considering performance and optimal solution.
PS: I can generate the svg sprite sheets using gulp task runner.
Pre-Information
Performance within a browser is something very difficult to test for and gauge, simply because of the amount of variables which can cause changes, spikes or differences between browsers, hardware or other things which could be bottle-necking the performance.
The below test's I have run on a Dell laptop with the following hardware and browser
Intel Core i5-3320M CPU # 2.60GHz
8GB DDR3 Ram (unsure of timing's etc)
Windows 8.1 Enterprise - 64Bit
Google Chrome v45.0.2454.101 m
I've only ran 3 of the test's I would have liked to due to time constraints but may come back to continue with the tests and also rerun them on different browsers and machines.
The SVG I Used
I created an SVG element which uses 5 icons layered on top of each other.
All of these icons are from iconmonstr.com which provides free to use SVG icons.
CodePen
The Tests
Inline - <use>
The Code
<svg height="100px" width="100px" viewBox="0 0 512 512">
<use xlink:href="#menu-icon"></use>
</svg>
<svg height="100px" width="100px" viewBox="0 0 512 512">
<use xlink:href="#user-icon"></use>
</svg>
<svg height="100px" width="100px" viewBox="0 0 512 512">
<use xlink:href="#home-4-icon"></use>
</svg>
<svg height="100px" width="100px" viewBox="0 0 512 512">
<use xlink:href="#phone-icon"></use>
</svg>
<svg height="100px" width="100px" viewBox="0 0 512 512">
<use xlink:href="#globe-4-icon"></use>
</svg>
Full Codepen Example
The Results
1 Request - 221B Transfer
Results
Average
Finish: 10.3ms - DOMContentLoaded: 22.8ms - Load: 22.3ms
Inline - Individual <svg>'s
The Test
This file is too large so only giving CodePen Example
Full Codepen Example
The Results
1 Request - 221B Transfer
Results
Average
Finish: 9.7ms - DOMContentLoaded: 20.6ms - Load: 19.9ms
External File - <use>
The Test
<svg height="100px" width="100px" viewBox="0 0 512 512">
<use xlink:href="svg.svg#menu-icon"></use>
</svg>
<svg height="100px" width="100px" viewBox="0 0 512 512">
<use xlink:href="svg.svg#user-icon"></use>
</svg>
<svg height="100px" width="100px" viewBox="0 0 512 512">
<use xlink:href="svg.svg#home-4-icon"></use>
</svg>
<svg height="100px" width="100px" viewBox="0 0 512 512">
<use xlink:href="svg.svg#phone-icon"></use>
</svg>
<svg height="100px" width="100px" viewBox="0 0 512 512">
<use xlink:href="svg.svg#globe-4-icon"></use>
</svg>
Use this with the base file given at the top of the page
The Result
2 Requests - 440B Transfer
Results
Average
Finish: 57.5ms - DOMContentLoaded: 41.3ms - Load: 58.4ms
Conclusion
As we can see from the above tests and results, using an inline SVG and referencing it is much quicker than using an external file; cached or not.
Neither of the two inline SVG methods seem to have that many speed differences, but I would personally go for the <use> method, simply because it is easier to use in the long run and helps keep your body code clean.
Now, as I have stated, these results are entirely dependant on an infinite amount of variables, to name a few:
Browser
Hardware
Internet Connection
SVG File Size
Bottle-neck Software (Anti-virus etc)
I would personally use whatever you feel most comfortable with.
I hope these results are somewhat useful or satisfactory and help you with what you require.
View all the tests and results here!
I've had the most success with SVGs in a single sprite file with unique ids. Most of the svg minification and concatenation scripts will simply name each Id after the individual file name, which is easy enough.
Then, for the best chance of proper scaling and such, I included the SVGs via the HTML tag:
<svg viewBox="0 0 50 50"
class="svgIcon" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<use xlink:href="#myIconIdHere"></use>
</svg>
If you're lucky, the viewBox value will be the same, if not, you may need to provide that with a view helper of some sort.
In my past works, I've stored the individual viewBox values in a config for later dynamic generation. Of course you could also just generate each SVG tag in a file somewhere as a string. Here is a sample config we used on one project:
config = {
"arrow": {
"viewBox" :"0 0 50 49.999360957030746",
}
,
"close": {
"viewBox" :"0 100 50 49.999360957030746",
}
...
}
Performance-wise, I can only speak a small amount.
This solution worked in IE9+, Chrome, Firefox, and mobile devices. We have animations across the board that involve these SVGs, and scale them for each breakpoint. The CSS animations applied to elements didn't have any major lagging issues except for IE9. I did look over this analysis for more help.
I'd be happy to show you the high traffic page using these SVGs, but would prefer if you private messaged me.
I have replicated my problem in the following simple example
I have a simple webpage like the following:
<html>
<head></head>
<body>
<img src="icons.svg#close"></img>
<br>
<img src="icons.svg#error"></img>
</body>
</html>
Viewing this page locally in Safari, the page renders correctly:
where the close icon appears above the error icon.
However, when I serve the file with NodeJS webapp (or use the python SimpleHTTPServer command) and view it in Safari, then the images are in each other's places:
even though the dom still looks correct, and the src attributes of each img tag hold the correct paths.
Here is the icons.svg file:
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<style>:root>svg{display:none}:root>svg:target{display:block}</style>
<svg viewBox="0 0 12 12" enable-background="new 0 0 12 12" id="close">
<path d="M7.2 6l4.5-4.4c.4-.4.4-.9 0-1.3s-.9-.4-1.3 0L6 4.7 1.6.3C1.2-.1.7-.1.3.3s-.4.9 0 1.3L4.7 6 .3 10.4c-.4.4-.4.9 0 1.3.2.2.4.3.6.3s.5-.1.7-.3L6 7.3l4.4 4.4c.2.2.4.3.7.3.2 0 .5-.1.7-.3.4-.4.4-.9 0-1.3L7.2 6z" opacity=".3" enable-background="new"/>
</svg>
<svg viewBox="0 0 58 46" enable-background="new 0 0 58 46" id="error">
<style type="text/css">.st0{fill:#ff9141}.st1{fill:#fff}</style>
<path class="st0" d="M30.6 1c-.9-1.4-2.3-1.4-3.2 0L.4 43.5C-.5 44.9.2 46 1.8 46h54.4c1.7 0 2.3-1.1 1.4-2.5L30.6 1z"/>
<path class="st1" d="M26.3 15.2h5.5V30h-5.5zM26.3 33.5h5.5v5.3h-5.5z"/>
</svg>
</svg>
The page is rendered correctly in all of the other browsers, regardless of if the file is being loaded locally or served through a server.
This is due to incomplete/buggy SVG fragment CSS support in Safari. Browser support for this technique is still relatively patchy - see https://css-tricks.com/svg-fragment-identifiers-work/
Current versions of Chrome/Safari/Opera (38/8/25) handle all the HTML techniques well, but none of the CSS techniques, including the background-position one.
Here's how my Safari 8 (left) and Chrome (right) render the test page - note that the icons should go every time:
Some experiments with your content follow:
If I repeat the pair of images a second time, the fourth image is somehow a composite of the two (below left). No interpretation of your svg should ever be able to produce an image like this. Interestingly, I get exactly the same split if you use different styling properties, e.g. opacity (below right):
If I zoom in and out with cmd++ and cmd+-, the overlaps and partial images change.
Resizing the page also has an effect.
Speculating that the styling of the images might somehow be interacting with one another, I tried having four different copies of the image (icons1.svg#close, icons2.svg#error etc.) and referring to them separately. This mostly fixed the problem, but the fourth image was missing the bottom three quarters. However, as soon as I resized the window, the missing part of the image appeared.
Bottom line: incomplete/buggy svg fragment identifier/CSS handling.
I'm having problem showing SVG logo image for my website project:
I can see slight thin dark line around the edge(border) of the vector object.
It seems to be prevalent around curves.
There's no border, at least when it's created on Illustrator,
nor any other dark-colored object hidden beneath.
As far as I have tested, it seems to be fine on Firefox, Safari, IE11,
but not for Chrome(v43) and Android-Stock-Browser(v4.2).
edit:
I made a sample here.
It has 'S' shaped orange object on square background object with the exact same color. No object here has border.
This is made on Illustrator CS3, and I created SVG file with the same, as how it originally was done for my project.
Here's screenshot comparison:
And fiddle:
http://jsfiddle.net/alexklaus80/tp0adzqn/
Here's the code of SVG file that used in this example:
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<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"
width="100px" height="100px" viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<g id="Layer_copy">
<rect x="-30.987" y="-30.357" style="fill:#EF8200;stroke:#EF8200;stroke-width:0.2;" width="156.636" height="156.634"/>
<g>
<path style="fill:#EF8200;stroke:#EF8200;stroke-width:0.2;" d="M70.966,51.515c1.779,1.968,3.086,4.138,3.934,6.476
c0.854,2.356,1.277,5.081,1.277,8.194c0,7.416-2.74,13.531-8.225,18.345c-5.482,4.812-12.287,7.218-20.413,7.218
c-3.745,0-7.49-0.587-11.239-1.748c-3.747-1.164-6.98-2.575-9.703-4.227l-2.544,4.314h-4.735l-0.832-28.755h4.795
c0.982,3.548,2.134,6.755,3.454,9.612c1.327,2.861,3.067,5.539,5.24,8.019c2.048,2.333,4.449,4.18,7.19,5.562
c2.737,1.385,5.924,2.075,9.552,2.075c2.726,0,5.099-0.363,7.132-1.069c2.031-0.71,3.674-1.72,4.936-3.023
c1.266-1.302,2.203-2.83,2.814-4.599c0.605-1.755,0.912-3.781,0.912-6.064c0-3.356-0.945-6.488-2.838-9.396
c-1.895-2.9-4.721-5.099-8.463-6.603c-2.561-1.023-5.502-2.151-8.816-3.393c-3.315-1.238-6.173-2.407-8.577-3.504
c-4.736-2.127-8.412-4.915-11.037-8.368c-2.621-3.454-3.935-7.958-3.935-13.514c0-3.195,0.652-6.169,1.954-8.935
c1.298-2.756,3.155-5.228,5.559-7.392c2.283-2.052,4.988-3.663,8.106-4.82c3.115-1.167,6.367-1.748,9.758-1.748
c3.865,0,7.328,0.592,10.387,1.778c3.055,1.18,5.85,2.565,8.365,4.138l2.432-4.022h4.729l0.473,27.869h-4.785
c-0.867-3.198-1.844-6.255-2.934-9.172c-1.082-2.916-2.496-5.56-4.227-7.927c-1.697-2.288-3.768-4.115-6.219-5.475
c-2.441-1.358-5.437-2.04-8.987-2.04c-3.748,0-6.941,1.203-9.585,3.609c-2.645,2.408-3.971,5.347-3.971,8.815
c0,3.633,0.856,6.635,2.552,9.024c1.692,2.387,4.156,4.352,7.396,5.886c2.877,1.38,5.706,2.578,8.495,3.58
c2.776,1.004,5.469,2.081,8.071,3.229c2.365,1.022,4.645,2.187,6.834,3.487C67.448,48.261,69.354,49.776,70.966,51.515z"/>
</g>
</g>
</svg>
So it supporsed to look like just an orange square, but on Chrome, it shows the letter S with slight brownish bordering.
I have been searching for similar issue on web but I got no clue.
I'm guessing that it's generator (Illustrator CS3)'s problem??
I found the solution, but I got much more semantic solution thanks to #PaulLeBeau in comment section, so I put this first.
Sample code: Before
<path style="fill:#EF8200;stroke:#EF8200;stroke-width:0.2;" .. />
1. Remove stroke:#EF8200;, and change the value of stroke-width from 0.2 to none
<path style="fill:#EF8200;stroke-width:none;" .. />
Or.. there were other solutions which I found by myself.
It doesn't look as good as the one above, but I'll lay it here just for the reference to say that it indeed does solve it.
2. Change the value of stroke-width from 0.2 to 0
<path style="fill:#EF8200;stroke:#EF8200;stroke-width:0;" .. />
3. removing stroke:#EF8200;stroke-width:0.2;
<path style="fill:#EF8200;" .. />
I do not understand why Illustrator adds width to the object that doesn't originally have stroke.
Maybe this is bug for the both Illustrator CS3 and Chrome/Browser?
When editing on Illustrator, check that there is no stroke added (see image) on the background you are using
Double click the background and "Stroke" value change it to zero
That's the way I easily removed the stroke that appeared in one of the logos createdenter image description here