6 Common SVG Fails (and How to Fix Them) | CSS-Tricks

Someone recently asked me how I approach debugging SVGs. Because it is part of the DOM, we can inspect any inline SVG in any browser DevTools. And because of that, we have the ability to scope things out and uncover any potential problems or opportunities to optimize SVG.

But sometimes we can’t see our SVGs at all. In these cases, there are six specific things I look for when debugging.

1. The one viewBox values

That viewBox is a common point of confusion when working with SVG. It’s technically fine to use inline SVG without it, but we’d lose one of its main benefits: scaling with the container. At the same time, it can work against us when it is incorrectly configured, resulting in unwanted clipping.

The elements are there when clipped – they’re just in a part of the coordinate system that we can’t see. If we were to open the file in a graphics editor, it could look like this:

Cat line art with part of the drawing outside the art area in Illustrator.
Screenshot of SVG opened in Illustrator.

The easiest way to fix this? Add overflow="visible" to SVG, whether it’s in our stylesheet, inline on style attribute or directly as an SVG presentation attribute. But if we also apply a background-color to SVG, or if we have other elements around it, things can look a little wonky. In this case, the best option would be to edit viewBox to show the part of the coordinate system that was hidden:

Demo applicant overflow="hidden" and editing the viewBox.

There are a few extra things about viewBox which are worth covering while we’re on the subject:

How works viewBox occupation?

SVG is an infinite canvas, but we can control what we see and how we see it through the viewport and viewBox.

That viewport is a window frame on the infinite canvas. Its dimensions are defined by width and height attributes, or in CSS with the corresponding ones width and height properties. We can specify any unit of length we want, but if we provide numbers with no unit, they default to pixels.

That viewBox is defined by four values. The first two are the starting point in the upper left corner (x and y values, negative numbers allowed). I edit these to frame the image. The last two are the width and height of the coordinate system inside the viewport – this is where we can edit the scale of the grid (which we’ll get into in the Zooming section).

Here is simplified markup showing SVG viewBox and width and height attributes both set to <svg>:

<svg viewBox="0 0 700 700" width="700" height="700">
  <!-- etc. -->
</svg>

Reframing

Then this:

<svg viewBox="0 0 700 700">

…short for this:

<svg viewBox="start-x-axis start-y-axis width height">

The view we see starts where 0 on the x-axis and 0 on the y-axis meet.

By changing this:

<svg viewBox="0 0 700 700">

…For this:

<svg viewBox="300 200 700 700">

…the width and height remain the same (700 units each), but the start of the coordinate system is now at 300 point on the x-axis and 200 on the y-axis.

In the following video I add a red <circle> to SVG centered at 300 point on the x-axis and 200 on the y-axis. Note how you change viewBox coordinates to the same values ​​also change the position of the circle to the upper left corner of the frame, while the rendered size of the SVG remains the same (700×700). All I did was “reframe” things with viewBox.

Zooming

We can change the last two values ​​inside viewBox to zoom in or out of the image. The larger the values, the more SVG units are added to fit the viewport, resulting in a smaller image. If we want to keep a ratio of 1:1, ours is viewBox width and height must match our viewport width and height values.

Let’s see what happens in Illustrator when we change these parameters. The drawing board is viewport which is represented by a white 700px square. Everything else outside of this area is our infinite SVG canvas and will be clipped by default.

Figure 1 below shows a blue dot at 900 along the x-axis and 900 along the y-axis. If I change the last two viewBox values ​​from 700 to 900 like this:

<svg viewBox="300 200 900 900" width="700" height="700">

…then the blue dot is almost completely visible again, as can be seen in Figure 2 below. Our image is scaled down because we increased the viewBox values, but the SVG’s actual width and height dimensions remained the same, and the blue dot came back closer to the unclipped area.

Figure 1.
figure 1
Figure 2

There is a pink square as evidence of how the grid scales to fit the viewport: the unit becomes smaller and more grid lines fit into the same viewport area. You can play with the same values ​​in the following pen to see how it works:

2. Missing width and height

Another common thing I look at when debugging inline SVG is whether the markup contains width or height properties. This isn’t a big deal in many cases, unless the SVG is inside an absolute positioning container or a flexible container (as Safari calculates the SVG width value with 0px instead of auto). Exclusive width or height in these cases prevents us from seeing the full picture, which we can see by opening this CodePen demo and comparing it in Chrome, Safari and Firefox (click images for larger view).

The solution? Add a width or height, either as a presentation attribute, inline in the style attribute, or in CSS. Avoid using height alone, especially when it is set to 100% or auto. Another solution is to set the right one and left values.

You can play with the following Pen and combine the different options.

3. Unintentional fill and stroke colors

It may also be that we use color <svg> tag, whether it’s an inline style or comes from CSS. That’s fine, but there may be different color values ​​throughout the selection or styles that conflict with the color set of <svg>causing parts to be invisible.

That’s why I usually look for it fill and stroke attributes in the SVG’s selection and delete them. The following video shows an SVG I styled in CSS with a red fill. There are a few instances where parts of the SVG are filled in white directly in the selection, which I removed to reveal the missing pieces.

4. Missing IDs

This one might seem super obvious, but you’d be surprised how often I see it pop up. Let’s say we made an SVG file in Illustrator and were very diligent about naming our layers so that you get nice matching IDs in the markup when you export the file. And let’s say we plan to style that SVG in CSS by hooking in those IDs.

It’s a nice way of doing things. But there are plenty of times where I’ve seen the same SVG file exported a second time to the same location and the IDs are different, usually when you copy/paste the vectors directly. Maybe a new layer was added or one of the existing ones was renamed or something. Either way, the CSS rules no longer match the IDs in the SVG markup, causing the SVG to render differently than you’d expect.

Underlines with numbers after the element IDs
Inserting Illustrator’s exported SVG file into SVGOMG.

In large SVG files, finding these IDs can be difficult. This is a good time to open DevTools, inspect the part of the graphics that isn’t working, and see if those IDs still match.

So I’d say it’s worth opening an exported SVG file in a code editor and comparing it to the original before switching things out. Apps like Illustrator, Figma, and Sketch are smart, but that doesn’t mean we’re not responsible for investigating them.

5. Clipping and Masking Checklist

If an SVG is unexpectedly clipped, and the viewBox checking out ok i usually look at css too clip-path or mask characteristics that may disturb the image. It’s tempting to keep looking at the inline markup, but it’s good to remember that an SVG’s styling can happen elsewhere.

CSS clipping and masking allow us to “hide” parts of an image or element. In SVG, <clipPath> is a vector operation that cuts parts of an image without halfway results. That <mask> tag is a pixel operation that allows transparency, semi-transparency effects, and blurred edges.

This is a small checklist for debugging cases where clipping and masking are involved:

  • Make sure the clipping path (or mask) and the graphic overlap. The overlapping parts are what will be shown.
  • If you have a complex path that doesn’t intersect your graphic, try applying transformations until they match.
  • You can still inspect the internal code with DevTools though <clipPath> or <mask> is not reproduced, use it!
  • Copy the marking inside <clipPath> and <mask> and insert it before closing </svg> roof. Then add a fill to these shapes and check the SVG’s coordinates and dimensions. If you still can’t see the image, try adding overflow="hidden" to <svg> roof.
  • Check that a unique ID is used for <clipPath> or <mask>, and that the same ID is applied to the shapes or group of shapes that are clipped or masked. An incorrect ID will spoil the appearance.
  • Check for typos in the selection between <clipPath> or <mask> tags.
  • fill, stroke, opacityor some other styles applied to the elements inside <clipPath> are useless — the only useful part is the fill area geometry of these elements. That’s why if you use one <polyline> it will behave as one <polygon> and if you use one <line> you will not see any clipping effect.
  • If you can’t see your image after applying a <mask>make sure that fill of the masking content is not completely black. The luminance of the mask element determines the opacity of the final graphic. You will be able to see through the lighter parts and the darker parts will hide the content of your image.

You can play with masked and clipped elements in this pen.

6. Namespaces

Did you know that SVG is an XML-based markup language? Well, that’s it! The SVG namespace is set to xmlns attribute:

<svg xmlns="http://www.w3.org/2000/svg">
  <!-- etc. -->
</svg>

There’s a lot to know about namespacing in XML, and MDN has a good primer on it. Suffice it to say that the namespace provides context to the browser and informs it that the markup is specific to SVG. The idea is that namespaces help prevent conflicts when more than one type of XML is in the same file, such as SVG and XHTML. This is a much less common problem in modern browsers, but it can help explain SVG rendering problems in older browsers or browsers like Gecko that are strict when defining doctypes and namespaces.

The SVG 2 specification does not require namespaces when using HTML syntax. But it’s essential if legacy browser support is a priority – and it doesn’t hurt to add it. In that way, when <html> elements xmlns attribute is defined, it will not conflict in the rare cases.

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
  <body>
    <svg xmlns="http://www.w3.org/2000/svg" width="700px" height="700px">
      <!-- etc. -->
    </svg>
  </body>
</html>

This also applies when using inline SVG in CSS, such as setting it as a background image. In the following example, a check icon appears on the input after successful validation. This is what the CSS looks like:

textarea:valid {
 background: white url('data:image/svg+xml,\
    <svg xmlns="http://www.w3.org/2000/svg" width="26" height="26">\
    <circle cx="13" cy="13" r="13" fill="%23abedd8"/>\
    <path fill="none" stroke="white" stroke-width="2" d="M5 15.2l5 5 10-12"/>\
    </svg>') no-repeat 98% 5px;
}

When we remove the namespace inside the SVG in the background property, the image disappears:

Another common namespace prefix is xlink:href. We use it a lot when referring to other parts of SVG like: patterns, filters, animations or gradients. The recommendation is to start replacing it with href as the other is becoming obsolete since SVG 2, but there may be compatibility issues with older browsers. In that case, we can use both. Just remember to include the namespace xmlns:xlink="http://www.w3.org/1999/xlink" if you are still using xlink:href.

Upgrade your SVG skills!

I hope these tips help you save a lot of time if you find yourself troubleshooting incorrectly rendered inline SVGs. These are just the things I’m looking for. Maybe you have different red flags you’re watching out for – if so, let me know in the comments!

The bottom line is that it pays to have at least a basic understanding of the different ways SVG can be used. CodePen Challenges often incorporate SVG and offer good practice. Here are a few more resources for leveling up:

There are a few people I suggest following for SVG related goodness:

William

Leave a Reply

Your email address will not be published. Required fields are marked *