Usage
- Select icon and download svg at https://icomoon.io/app/#/select/image
- save svg file. Etc. map.svg
- Use it
<!-- https://jonathantneal.github.io/svg4everybody/demo.svg -->
<script src="https://jonathantneal.github.io/svg4everybody/svg4everybody.legacy.min.js"></script>
<script>
if (location.hash !== '#nofill') {
svg4everybody();
}
</script>
<svg style="display:none" xmlns="http://www.w3.org/2000/svg">
<!-- icomoon.io -->
<symbol id="codepen" viewBox="0 0 64 64">
<title>CodePen</title>
<path etc.../>
</symbol>
<symbol id="youtube" viewBox="0 0 64 64">
<title>YouTube</title>
<path etc.../>
</symbol>
<symbol id="twitter" viewBox="0 0 64 64">
<title>Twitter</title>
<path etc.../>
</symbol>
<symbol id="eye" viewBox="0 0 512 512">
<path d="M256 96c-111.659 0-208.441 65.021-256 160 47.559 94.979 144.341 160 256 160 111.657 0 208.439-65.021 256-160-47.558-94.979-144.343-160-256-160zm126.225 84.852c30.081 19.187 55.571 44.887 74.718 75.148-19.146 30.261-44.638 55.961-74.719 75.148-37.797 24.109-81.445 36.852-126.224 36.852-44.78 0-88.428-12.743-126.225-36.852-30.08-19.187-55.57-44.887-74.717-75.148 19.146-30.262 44.637-55.962 74.717-75.148 1.959-1.25 3.938-2.461 5.929-3.65-4.979 13.664-7.704 28.411-7.704 43.798 0 70.691 57.308 128 128 128 70.692 0 128-57.309 128-128 0-15.387-2.725-30.134-7.704-43.799 1.99 1.189 3.969 2.401 5.929 3.651zm-126.225 24.148c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48z"/>
</symbol>
</svg>
<svg title="Pencil" role="img">
<use xlink:href="demo.svg#pencil"/>
</svg>
<svg role="presentation">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#eye"></use>
</svg>
<svg role="img" title="CodePen">
<img src="map.svg.codepen.png">
</svg>
<svg role="img" title="YouTube">
<img src="map.svg.youtube.png">
</svg>
<svg role="img" title="Twitter">
<img src="map.svg.twitter.png">
</svg>
SVG for Everybody adds SVG External Content support to all browsers.
To use it now, include the script in your document.
<script src="/path/to/svg4everybody.js"></script>
<script>svg4everybody(); // run it now or whenever you are ready</script>
To support Internet Explorer 6-8, include the legacy script instead.
<script src="/path/to/svg4everybody.legacy.js"></script>
<script>svg4everybody(); // run it now or whenever you are ready</script>
As of v2.0.0, you must manually call svg4everybody()
. If you are using an AMD/CommonJS dependency loader then you may call it within the callback closure.
IE 6-8 require you to put the script in the <head>
in order to shiv <svg>
and <use>
elements. For best results in IE, set X-UA-Compatible to ie=edge
. This can be done with a response header from the server or the following HTML in the <head>
.
<meta http-equiv="x-ua-compatible" content="ie=edge">
Create an SVG image.
map.svg:
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="codepen" viewBox="0 0 64 64">
<title>CodePen</title>
<path etc.../>
</symbol>
<symbol id="youtube" viewBox="0 0 64 64">
<title>YouTube</title>
<path etc.../>
</symbol>
<symbol id="twitter" viewBox="0 0 64 64">
<title>Twitter</title>
<path etc.../>
</symbol>
</svg>
This spritemap displays fine in Chrome, Safari 7.1+, Firefox, and Opera. SVG for Everybody polyfills the experience in Safari 6, IE 6+, and Edge 12.
<svg role="img" title="CodePen">
<use xlink:href="map.svg#codepen"/>
</svg>
<svg role="img" title="YouTube">
<use xlink:href="map.svg#youtube"/>
</svg>
<svg role="img" title="Twitter">
<use xlink:href="map.svg#twitter"/>
</svg>
IE 6-8 requires a trailing slash /
when using a self-closing <use/>
element.
Browsers not supporting SVG fallback to images.
<svg role="img" title="CodePen">
<img src="map.svg.codepen.png">
</svg>
<svg role="img" title="YouTube">
<img src="map.svg.youtube.png">
</svg>
<svg role="img" title="Twitter">
<img src="map.svg.twitter.png">
</svg>
By default, fallback images point to a PNG file in the same location as the SVG, only with the #
hash replaced by a .
dot and then appended with a .png
extension. If you want to change this behavior, you can define your own fallback.
svg4everybody({
fallback: function (src, svg, use) {
// src: current xlink:href String
// svg: current SVG Element
// use: current USE Element
return 'fallback.png'; // ok, always return fallback.png
}
});
All <use>
elements that are descendants of an <svg>
are checked for external content. If you want to change this behavior, you can define your own validator.
svg4everybody({
validate: function (src, svg, use) {
// src: current xlink:href String
// svg: current SVG Element
// use: current USE Element
return true; // ok, everything is valid
}
});
You can override whether the script polyfills External Content at all (polyfill
), or whether SVG should even be used over fallback images (nosvg
).
svg4everybody({
nosvg: true, // shiv <svg> and <use> elements and use image fallbacks
polyfill: true // polyfill <use> elements for External Content
});
Use of the nosvg
option will requires you to use the legacy version of SVG for Everybody.
Modern browsers support external content in SVGs, except Edge. No frets; we can shim it.
OS | Browser | SVG | External Content | Shimmed |
---|---|---|---|---|
* | Chrome 21+ | ✔ | ✔ | — |
* | Chrome 14-20 | ✔ | ✖ | ✔ |
* | Firefox 4+ | ✔ | ✔ | — |
* | Opera 23+ | ✔ | ✔ | — |
* | Opera Mini 8+ | ✔ | ✔ | — |
And | And. Browser 40+ | ✔ | ✔ | — |
And | And. Browser 4.1+ | ✔ | ✖ | ✔ |
iOS | iOS 8.1+ | ✔ | ✔ | — |
iOS | iOS 6-7 | ✔ | ✖ | ✔ |
OSX | Saf 7.1+ | ✔ | ✔ | — |
OSX | Saf 6 | ✔ | ✖ | ✔ |
Win | Edge 13 | ✔ | ✔ | — |
Win | Edge 12 | ✔ | ✖ | ✔ |
Win | IE 9 - 11 | ✔ | ✖ | ✔ |
Win | IE 6 - 8 | ✖ | ✖ | ✔ |
As you can see, all major browsers support external content.
We had been waiting on Edge, previously, but David Storey, Edge’s project manager assured us that native support for external content in SVGs was high on their checklist. We would track progress and vote for attention to this issue. Then, just as I predicted...
I have complete faith in the Microsoft Edge team and absolutely expect support to arrive within the next few months.
— Jon Neal (August, 2015)
All of our dreams came true.
SVGs are compelling to use for many reasons, and one of them is their ease of accessibility.
Within your spritemap, have each sprite use a <title>
element to identify itself.
<symbol id="codepen">
<title>CodePen</title>
<path etc.../>
</symbol>
When this sprite is used, its title will be read aloud in JAWS and NVDA. Then, within your document, each sprite may use a title
attribute to identify itself.
<svg title="CodePen">
<use xlink:href="map.svg#codepen"/>
</svg>
That title will be read aloud in VoiceOver and NVDA. At present, the title
attribute is the only way to properly read aloud an SVG in VoiceOver. I’ll let you know if this changes.
All together, use the title
attribute in your document and the title
element in your SVG.
ARIA roles may also be used to provide even more information to assistive technology.
When a sprite is merely decoration, use role="presentation"
.
<a href="//twitter.com/jon_neal"><svg role="presentation">
<use xlink:href="map.svg#twitter"/>
</svg> Find me on Twitter</a>
Otherwise, use role="img"
and remember to add a description.
<a href="//twitter.com/jon_neal"><svg title="Find me on Twitter" role="img">
<use xlink:href="map.svg#twitter"/>
</svg></a>
- Tips for creating accessible SVG
- Using ARIA to enhance SVG accessibility
- SVG symbol a good choice for icons
- Implementing inline SVG Icons
SVG files, especially exported from vector tools, often contain tons of unnecessary data such as editor metadata, comments, hidden elements, and other stuff that can be safely removed without affecting SVG rendering result.
Use a tool like SVGO to optimize SVG spritemaps.
$ [sudo] npm install -g svgo
$ svgo spritemap.svg