This article is all about SVGs: how and why to use SVGs in WordPress, including how to allow SVG file uploads in WordPress. Whether you love, fear, or simply don’t understand this image format, we’ve got you covered.
What is an SVG?
SVG stands for Scalable Vector Graphics. It’s a file format for 2D graphics which uses XML.
According to Mozilla Developer Network, SVG is essentially to graphics what HTML is to text.
What are the benefits of SVGs?
As a vector format, SVGs have infinite resolution: you can zoom in forever and they stay completely crisp.
As SVG is a vector format, SVG files are scalable without the loss of quality. In other words, unlike PNGs or JPGs, SVGs have infinite resolution: you can zoom in forever and they stay completely crisp. (Try it on one of the SVGs in this article!)
SVGs also have generally, though not always, smaller file sizes than other image formats.
In addition, SVGs can be animated.
Finally, SVGs can be more accessible than other formats like icon fonts, because you can add additional markup to them which helps screen readers understand their purpose.
What are the drawbacks of SVGs?
SVGs are subject to the same attack vectors as XML.
SVGs are a not such a suitable format for photographs. While you can covert JPG files to SVG, the results are less than stellar.
The main downside of using SVGs is security. Because SVG is a document format and XML-based, it is subject to the same attack vectors as XML.
Fortinet’s post explains the types of attacks SVGs could be vulnerable to.
This video explains the anatomy of a malicious SVG:
Does this mean that SVGs are unsafe to use?
No, but you do need to exercise some caution.
Create your own SVGs
You can make your own SVGs using any vector graphic software.
Traditionally that’s been with Adobe Illustrator, but there are free alternatives.
Two are the Inkscape program or Vectr website.
SVGs may contain lines, polygons, freehand drawn shapes or text. Colored SVGs have one or both of stroke (the shape’s outline) and fill (a solid color or gradient).
A simple rectangle created with Inkscape. The SVG is 0.76Kb compared to 1.33Kb (75% more) for a PNG of the same image.
When you’ve made your SVG, run it through an optimizer to remove any code bloat that may be added by your graphics program.
Here are two:
How are SVGs added to web pages?
There are a few different methods of adding SVGs to HTML code.
First, you can add an <img>
tag and add the path to the SVG file in it.
e.g.
<img src="target.svg" alt="target" height="200" width="200" />
Second, you can add SVGs inline. That means adding the SVG’s code directly to the page, rather than referencing it in a file.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="189.297 142.366 233.703 233.703" width="200" height="200"><defs><path d="M420 258.22c0 63.39-51.46 114.85-114.85 114.85-63.39 0-114.85-51.46-114.85-114.85 0-63.39 51.46-114.85 114.85-114.85 63.39 0 114.85 51.46 114.85 114.85z" id="a"/><path d="M382.38 258.22c0 42.62-34.61 77.23-77.23 77.23-42.62 0-77.23-34.61-77.23-77.23 0-42.63 34.61-77.23 77.23-77.23 42.62 0 77.23 34.6 77.23 77.23z" id="b"/><path d="M343.27 260.2c0 21.04-17.08 38.12-38.12 38.12s-38.12-17.08-38.12-38.12 17.08-38.12 38.12-38.12 38.12 17.08 38.12 38.12z" id="c"/></defs><use xlink:href="#a" fill="#3498db"/><use xlink:href="#b" fill="#f4d03f"/><use xlink:href="#c" fill="red"/></svg>
Third, you can add an SVG as a background image with CSS.
HTML:
<div class="background"></div>
CSS:
.background {
background-image: url(img/target.svg);
background-repeat: no-repeat;
background-size: 200px;
width: 200px;
height: 200px;
}
In each case, the SVG displays exactly the same on the page. Notice that the width and height are the same values each time.
The SVG viewport, viewBox and SVG size
SVGs don’t behave like other images when it comes to size. That’s because they’re really documents.
The SVG viewport shows the visible area of the SVG. That’s defined by the width and height attributes in the <svg>
element.
If you don’t specify a unit for width or height, it’s assumed that you are using pixels.
Otherwise, you can use several other measurements including em, %, mm, cm and inches.
When no units are used, the viewBox attribute can define where the SVG sits within the viewport and how much of it is seen. It is composed of 4 parameters: x
, y
, width
and height
.
I found it tricky to get to grips with the way the co-ordinate system works, until I came across Amelie Wattenberger’s Scaling SVG Elements, which has a brilliant interactive demo.
Amelie compares viewBox
to a telescope, with the x and y coordinates used to pan and the width and height to zoom.
Here is the code for an SVG square which I added to a page inline to experiment with viewBox
.
<svg width="900" height="180" xmlns="http://www.w3.org/2000/svg"><rect x="50" y="20" width="150" height="150" style="fill:yellow; stroke:red;" stroke-width="5"/></svg>
See what happens to the square when different viewBox
values are set:
Here are two other good blogs on this subject:
- How to Scale SVG
- Understanding SVG Coordinate Systems and Transformations (Part 1) — The viewport, viewBox, and preserveAspectRatio
The most predictable way I’ve found to control the size of an SVG and its responsiveness is to make it quite large in the graphics program you use. It seems much easier to scale down an SVG than scale up.
WordPress and SVG uploads to the Media Library
WordPress does not allow SVG uploads to the Media Library, for the aforementioned security reasons.
If you try, you’ll see a message like this:
“example.svg” has failed to upload.
Sorry, this file type is not permitted for security reasons.
So how can you get around this?
The answer is with plugins.
Plugins for SVG uploads in WordPress
Two plugins which promise safe SVG use are SVG Support and Safe SVG.
Both have file sanitization built-in to scan SVG files and remove any malicious code.
Since no sanitizer software is perfect, be careful about downloading and using SVGs from untrusted sources. You could open the file up in a code editor first just to check.
Once you enable SVG uploads, anyone with the Author role or above on your site will have permission to add SVGs to your site – unless you have enabled upload restrictions via your plugin. It comes down to how much you trust your users!
SVG Support
SVG Support is what we used to add SVGs to this article.
SVG Support is free and has some powerful features:
- Add SVGs in
<img>
tags or inline - Add a class for styling or animating your SVGs: SVG Support uses
style-svg
but you can change this - Restrict uploads to admins only
- Force all SVGs to display inline (necessary for some page builders like Divi)
SVG Support is what we used to add SVGs to this article. It works great out of the box. For security, we made sure to enable its “Restrict to Administrators?” option, allowing only WPShout Administrator users to upload SVGs to the site:
At the time of writing, adding your own class to a SVG in a Gutenberg image block to make it inline doesn’t work as expected because of the way the block is marked up. This is a known issue and should be addressed in a future release.
Safe SVG
Safe SVG has both a free and a premium version.
The free version sanitizes SVGs and shows previews in the Media Library.
For the full feature suite you need to upgrade. Prices start at £39 for a single site.
The Pro version lets you:
- Choose who can upload SVGs by user
- Scan previously uploaded SVGs
- Add SVGs inline, including in Gutenberg
- Optimize SVGs on upload
- View a sanitization log
- Access premium support
There’s an online demo of Safe SVG’s sanitizer if you want to test it out.
Elementor
If you’re a user of the Elementor plugin you can enable SVG support to upload SVGs for the plugin’s Icon widgets. The option is not enabled by default.
Elementor will attempt to sanitize your SVGs but warns you about the potential risk of allowing SVG uploads.
SVG appearance in WordPress
In the Twenty Twenty theme, the following style affects images, including SVGs, when you use the Classic Editor:
svg, img, embed, object {
display: block;
height: auto;
max-width: 100%;
}
I haven’t verified this with many other themes, but it looks as if they also use height: auto;
and max-width: 100%;
for images.
If you use the Block Editor, regardless of theme this style applies (to all images):
.wp-block-image img {
max-width: 100%;
}
You can resize your SVG by switching to one of the preset media sizes, or by setting the width or height in pixels.
I found that trying to use a % size for an SVG in the Block Editor didn’t work – it caused the SVG to vanish completely.
WordPress SVG animations
You can animate SVGs with CSS or JS.
Jackie d’Elia has a nice tutorial on this topic, Using SVG Animation in WordPress, which includes a fix for Firefox’s different display behavior.
There are several tools for making animations. I tried out SVGator, which is free on a 14-day trial.
There are special instructions for adding an SVG animation from SVGator to WordPress as it’s somewhat fiddly. I’ve had most success with method 2.
Other ways of using SVGs in WordPress
Some themes and plugins include SVG icons in one of the theme or plugin’s folders so there is no upload issue.
They are an easy and safe way to use SVGs.
WordPress “Twenty” themes
Since Twenty Seventeen, the default WordPress themes have a Social Links menu which uses SVGs.
A single icon has this code:
<svg class="icon icon-twitter" aria-hidden="true" role="img"> <use href="#icon-twitter" xlink:href="#icon-twitter"></use> </svg>
If you are familiar with image sprites, the #icon-twitter
references the Twitter icon in the file svg-icons.svg
, which contains all the icons.
The Twitter icon code draws the shape:
<symbol id="icon-twitter" viewBox="0 0 30 32">
<path class="path1" d="M28.929 7.286q-1.196 1.75-2.893 2.982 0.018 0.25 0.018 0.75 0 2.321-0.679 4.634t-2.063 4.437-3.295 3.759-4.607 2.607-5.768 0.973q-4.839 0-8.857-2.589 0.625 0.071 1.393 0.071 4.018 0 7.161-2.464-1.875-0.036-3.357-1.152t-2.036-2.848q0.589 0.089 1.089 0.089 0.768 0 1.518-0.196-2-0.411-3.313-1.991t-1.313-3.67v-0.071q1.214 0.679 2.607 0.732-1.179-0.786-1.875-2.054t-0.696-2.75q0-1.571 0.786-2.911 2.161 2.661 5.259 4.259t6.634 1.777q-0.143-0.679-0.143-1.321 0-2.393 1.688-4.080t4.080-1.688q2.5 0 4.214 1.821 1.946-0.375 3.661-1.393-0.661 2.054-2.536 3.179 1.661-0.179 3.321-0.893z"></path>
</symbol>
Font Awesome
The Font Awesome plugin brings their popular icon set to WordPress.
In the plugin’s Advanced Settings there is the option to choose SVG icons in the Method dropdown.
Font Awesome SVG effects
The SVG option of Font Awesome lets you do some things you can’t do with icon fonts.
Rotation, masking and layering
You can rotate an icon by degrees.
<div class="fa-4x">
<i class="fas fa-car-side" data-fa-transform="rotate-45"></i>
</div>
You can also do some cool masking effects.
<div class="fa-4x">
<i class="fas fa-music" style="color:#3f58f4;" data-fa-transform="shrink-3" data-fa-mask="fas fa-square"></i>
</div>
Plus you can layer multiple icons.
<div class="fa-4x">
<span class="fa-layers fa-fw">
<i class="fas fa-bed"></i>
<span class="fa-layers-counter" style="background:red">6</span>
</span>
</div>
Rotation animation
You can also use the fa-spin
class to rotate an icon continously.
<div class="fa-3x">
<i class="fas fa-basketball-ball fa-spin"></i>
<i class="fas fa-compact-disc fa-spin"></i>
</div>
SVG accessibility
Making an SVG image accessible depends on the purpose of the image, and how you include it.
Decorative SVGs
If the image is decorative and added via an <img>
tag, it should have a null alt attribute.
<img src="example.svg" alt="">
If the SVG is used inline, add aria-hidden="true"
to the <svg>
tag.
<svg aria-hidden="true">
</svg>
Semantic (meaningful) SVGs
For SVGs with a meaning using an <img>
tag, add role="img"
and alt text representing what the image stands for.
<img src="img/raincloud.svg" role="img" alt="Rain falls from a grey cloud" />
Here’s a code sample for a meaningful inline SVG.
<svg xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="raincloud" width="625.323" height="828.362" viewBox="0 0 165.45 219.171">
<title id="raincloud">Rain falls from a grey cloud</title>
<g fill="#666" transform="translate(-19.212 -24.913)"><ellipse cx="103.297" cy="81.287" rx="71.547" ry="48.647"/><ellipse cx="44.369" cy="78.936" rx="25.156" ry="21.518"/><ellipse cx="65.535" cy="105.394" rx="25.156" ry="21.518"/><ellipse cx="62.512" cy="56.258" rx="25.156" ry="21.518"/><ellipse cx="94.262" cy="46.43" rx="25.156" ry="21.518"/><ellipse cx="129.791" cy="49.454" rx="25.156" ry="21.518"/><ellipse cx="91.994" cy="114.466" rx="25.156" ry="21.518"/><ellipse cx="120.72" cy="111.442" rx="25.156" ry="21.518"/><ellipse cx="151.714" cy="103.127" rx="25.156" ry="21.518"/><ellipse cx="153.226" cy="83.472" rx="25.156" ry="21.518"/><ellipse cx="149.446" cy="59.281" rx="25.156" ry="21.518"/><ellipse cx="159.506" cy="81.554" rx="25.156" ry="21.518"/></g><g fill="#00b4f4" transform="translate(-19.212 -24.913)"><circle cx="73.705" cy="180.961" r="6.426"/><circle cx="83.911" cy="154.125" r="6.426"/><circle cx="55.94" cy="150.345" r="6.426"/><circle cx="46.113" cy="176.048" r="6.426"/><circle cx="34.774" cy="200.994" r="6.426"/><circle cx="25.702" cy="225.94" r="6.426"/><circle cx="62.744" cy="205.53" r="6.426"/><circle cx="50.271" cy="230.854" r="6.426"/><circle cx="113.015" cy="154.503" r="6.426"/><circle cx="103.187" cy="181.717" r="6.426"/><circle cx="91.092" cy="208.932" r="6.426"/><circle cx="75.217" cy="236.146" r="6.426"/><circle cx="137.205" cy="154.503" r="6.426"/><circle cx="127.378" cy="182.473" r="6.426"/><circle cx="117.551" cy="210.443" r="6.426"/><circle cx="102.432" cy="237.658" r="6.426"/>
</g>
</svg>
Note that:
- The
<svg>
tag hasrole="img"
andaria-labelledby
attributes. - The
<title>
tag comes right after<svg>
and has anid
with a value matching thearia-labelledby
value (raincloud). - The contents of the
<title>
tag represent the image.
Linked SVGs
It gets more complicated if your SVGs are linked! For guidance, read the following:
- Creating Accessible SVGs by Carie Fisher
- Accessible SVGs by Heather Migliori
Accessible SVG animations
If you want your animated SVGs to be accessible, your animations shouldn’t autoplay for longer than 5 seconds without a pause control. Also, you should avoid using images that flash or blink 3 times a second or faster.
Font Awesome SVG accessibility
Font Awesome’s Accessibility page has advice for making SVG icons accessible.
If the image is decorative, you just need to add the icon’s HTML code.
<i class="fas fa-arrow-right"></i>
Font Awesome automagically adds the correct markup to identify the icon as an image but hide it from a screen reader.
This is the output code on the page:
<svg class="svg-inline--fa fa-arrow-right fa-w-14" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="arrow-right" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" data-fa-i2svg=""><path fill="currentColor" d="M190.5 66.9l22.2-22.2c9.4-9.4 24.6-9.4 33.9 0L441 239c9.4 9.4 9.4 24.6 0 33.9L246.6 467.3c-9.4 9.4-24.6 9.4-33.9 0l-22.2-22.2c-9.5-9.5-9.3-25 .4-34.3L311.4 296H24c-13.3 0-24-10.7-24-24v-32c0-13.3 10.7-24 24-24h287.4L190.9 101.2c-9.8-9.3-10-24.8-.4-34.3z"></path></svg>
If the image has a meaning, copy the code for the icon you want and add a title
attribute to it with the icon’s meaning, like so:
<i title="Accessible" class="fab fa-accessible-icon fa-2x"></i>
This is the output:
<svg title="Accessible" class="svg-inline--fa fa-accessible-icon fa-w-14 fa-2x" aria-labelledby="svg-inline--fa-title-mVQUTxhc8E1E" data-prefix="fab" data-icon="accessible-icon" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" data-fa-i2svg=""><title id="svg-inline--fa-title-mVQUTxhc8E1E">Accessible</title><path fill="currentColor" d="M423.9 255.8L411 413.1c-3.3 40.7-63.9 35.1-60.6-4.9l10-122.5-41.1 2.3c10.1 20.7 15.8 43.9 15.8 68.5 0 41.2-16.1 78.7-42.3 106.5l-39.3-39.3c57.9-63.7 13.1-167.2-74-167.2-25.9 0-49.5 9.9-67.2 26L73 243.2c22-20.7 50.1-35.1 81.4-40.2l75.3-85.7-42.6-24.8-51.6 46c-30 26.8-70.6-18.5-40.5-45.4l68-60.7c9.8-8.8 24.1-10.2 35.5-3.6 0 0 139.3 80.9 139.5 81.1 16.2 10.1 20.7 36 6.1 52.6L285.7 229l106.1-5.9c18.5-1.1 33.6 14.4 32.1 32.7zm-64.9-154c28.1 0 50.9-22.8 50.9-50.9C409.9 22.8 387.1 0 359 0c-28.1 0-50.9 22.8-50.9 50.9 0 28.1 22.8 50.9 50.9 50.9zM179.6 456.5c-80.6 0-127.4-90.6-82.7-156.1l-39.7-39.7C36.4 287 24 320.3 24 356.4c0 130.7 150.7 201.4 251.4 122.5l-39.7-39.7c-16 10.9-35.3 17.3-56.1 17.3z"></path></svg>
Summing up
SVGs can be very useful for their smaller file size, better accessibility and animation potential. They are particularly useful as icons.
You need to balance those pros against adding one or more plugins to use them, maintaining your site’s security and learning the SVG way of doing things.
But overall, I think including SVGs in WordPress is worth it.
Thanks for reading! We’d love to hear your questions or thoughts about SVGs in the comments below, or in our Facebook group.
Researched this same topic today, because I wanted to add a SVG logo to a WordPress. So a bit of synchronicity to see the topic the same day in your newsletter.
I also found my way to the SVG Support plugin and I like that you can limit SVG upload to specific user roles.