Why Can't We Style External SVGs Directly?
When an SVG is embedded via an <img>
tag, it is treated as an external resource, like a photograph or raster image. This means:
- No Access to SVG Contents: You cannot target or manipulate its internal elements with CSS.
- Limited Customization: The only styles you can apply affect the
<img>
tag itself (e.g., dimensions, borders).
To overcome this, we can use CSS masking, which treats the SVG as a stencil for dynamic styling.
Benefits of CSS Masks Over Filters?
CSS masks (and their -webkit-mask
counterpart for better browser support) allow you to use an SVG as a mask for an HTML element. This effectively turns the SVG into a stencil through which the background color of the element shows. Masks offer:
- Dynamic Filling: Apply any background color, gradient, or pattern to the SVG.
- Non-Intrusive Styling: Keep your HTML clean and avoid inline SVGs or JavaScript.
Alternative Approach: CSS Filters
You might have come across techniques that use CSS filters to recolor an SVG, such as those generated by tools like CSS Color Filter Generator. While this method works, it has limitations:
- Lack of Precision: Achieving an exact color match can be tricky and requires fine-tuning filter values.
- Limited Control: Filters affect the entire image and don't offer the same flexibility as masks.
Here is an example of what this looks like when trying to turn a black SVG into the color #1e293b:
filter: brightness(0) saturate(100%) invert(13%) sepia(32%) saturate(813%) hue-rotate(177deg) brightness(89%) contrast(90%);
Why this isn't ideal
When we use a color picker to test the resulting color, we find out that the closest color that could be created here is in fact #1f2a3c- not ideal if we have brand guidelines to adhere to.

For scenarios where precise control and clean visuals are critical, CSS masks are a more robust choice.
Step-by-Step Guide
1. Create the HTML Structure
Let's start with a simple <div>
element to act as our container:
<div class="svg-mask"></div>
This will serve as the box where the masked SVG will be displayed.
2. Add Basic Styling
Use the mask
and -webkit-mask
properties to apply an external SVG as a mask:
.svg-mask {
width: 100px;
height: 100px;
background-color: red; /* The color you want to fill the SVG with */
-webkit-mask: url('https://website.com/path-to-your-svg.svg');
-webkit-mask-size: contain;
mask: url('https://website.com/path-to-your-svg.svg');
mask-size: contain;
}
3. Fix Positioning
This does the job of changing the color, however, you might notice that the masked SVG repeats within the container, and it is also off-center. To fix this, we can use the mask-position
and mask-repeat
properties:
.svg-mask {
width: 100px;
height: 100px;
background-color: #1e293b;
-webkit-mask: url('https://website.com/path-to-your-svg.svg');
-webkit-mask-size: contain;
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center;
mask: url('https://website.com/path-to-your-svg.svg');
mask-size: contain;
mask-position: center;
mask-repeat: no-repeat;
}
Putting It All Together: Final CSS Snippet
Let's tidy this up - we can use shorthand here, and put a few of these properties within the single mask
property. That looks like this:
<div class="svg-mask"></div>
<style>
.svg-mask {
width: 100px;
height: 100px;
background-color: #1e293b;
-webkit-mask: url('https://website.com/path-to-your-svg.svg') center / contain no-repeat;
mask: url('https://website.com/path-to-your-svg.svg') center / contain no-repeat;
}
</style>
I used this trick to fill the skill SVG's on my homepage, which are being pulled from my CMS:

Browser Compatibility
CSS masking is widely supported, but be sure to include the -webkit-
prefix for compatibility with WebKit-based browsers (e.g., Chrome, Safari). Check Can I Use for the latest support details.
Use Cases
This technique is perfect for scenarios where you:
- Pull SVGs dynamically from a CMS.
- Need to fill SVGs with specific colors or patterns without editing the file.
- Want a clean, JavaScript-free solution for styling external SVGs.
By leveraging CSS masks, you can dynamically style external SVGs efficiently and flexibly. This approach eliminates the need for JavaScript while maintaining clean, accessible code. Happy styling!