SVG and CSS: a guide to styling and animating SVG elements
SVG icons can be easily customized using CSS when imported inline in an HTML document.
In this article, we'll show how to stylize SVGs in CSS and the advantages of using CSS compared to inline attributes.
Styling SVG icons with CSS
SVG elements support a wide range of attributes that can be adjusted directly within the HTML to change their appearance. Consider the example below, where attributes like viewBox
, width
, height
, fill
, and d
are defined inline within the <svg>
and <path>
elements:
<svg viewBox="0 0 18 18" width="18" height="18">
<path fill="#f0a2a2" d="..." ></path>
</svg>
However, many of these attributes can also be customized using CSS. Attributes such as height and width can be modified just like any CSS property:
svg {
height: 24px;
width: 24px;
}
Given SVGs are vector files, adjusting their size through CSS doesn't compromise their quality. Using CSS classes for resizing provides a practical method for controlling SVG dimensions:
<style>
.icon-sm {
height: 24px;
width: 24px;
}
.icon-md {
height: 32px;
width: 32px;
}
</style>
<svg viewBox="0 0 18 18" class="icon-sm">
<!-- ... -->
</svg>
This makes your icon system easier to maintain: updating your icon sizes is a matter of modifying one CSS class, rather than the height and width inline attributes of each of your icons.
Working with SVG icons?Take your designs to the next level with the Nucleo icons →If you want to read more about changing SVG sizes, check our article on resizing SVG icons.
SVG-only attributes
Some SVG attributes are standard CSS properties (like height and width); some others are specific to SVG.
For example, to control the background color of an SVG, you can use the fill
and the stroke
attributes. Fill controls the SVG content's color, while the stroke changes the outline color (you can imagine it as the color of the SVG border).
svg {
fill: #6C43E8;
stroke: #6C43E8;
}
Below is an example of SVG icons from the Nucleo library: the first row features icons with only fill color, while the second row shows icons with only a stroke color.
Additionally, you can control the SVG color opacity using the fill-opacity
and stroke-opacity
attributes, as well as the outline width using the stroke-width
attribute:
.icon {
stroke-width: 2px;
fill-opacity: 0.5;
stroke-opacity: 0.5;
}
It's important to note that CSS styles will override inline SVG attributes. Consider the following example:
<svg class="icon" fill="red" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
<!-- svg content here -->
</svg>
<style>.icon {fill: yellow;}</style>
The SVG fill color will be yellow - CSS style values overwrite the inline fill attribute.
This precedence makes CSS an ideal solution for maintaining the style of inline SVG icons, with easy updates through CSS class modifications without altering the SVG code.
For the complete list of SVG attributes that can be manipulated with CSS, check out the following links:
Animating SVG with CSS
There are several JavaScript libraries designed for animating SVG elements, like Lottie and Rive, among others.
However, CSS Animations and Transitions often provide all that's needed to craft animations without relying on additional JavaScript. SVG loaders are a great example.
Take a look at this SVG animation:
In this animation, the <svg>
is rotated and scaled using a CSS Animation:
svg {
transform-origin: 50% 50%;
animation: nc-loop-dots-anim 1s infinite cubic-bezier(.645,.045,.355,1)
}
@keyframes nc-loop-dots-anim {
0% {transform: scale(1)}
50% {transform: scale(.7) rotate(90deg)}
100% {transform: scale(1) rotate(180deg)}
}
There are cases when it's necessary to animate different elements within an SVG, such as with the following loader:
To achieve this loader effect, you can animate the clock hour and minute hands separately:
.nc-loop-clock-anim-icon-f > * {
transform-origin: 50% 50%;
}
.nc-loop-clock-anim-icon-f > :nth-last-child(2) {
/* this is the minutes hand */
animation: nc-loop-clock-anim-m 0.5s infinite linear;
}
.nc-loop-clock-anim-icon-f > :nth-last-child(1) {
/* this is the hours hand */
animation: nc-loop-clock-anim-h 1s infinite linear;
}
@keyframes nc-loop-clock-anim-h {
0% {transform:rotate(90deg)}
100% {transform:rotate(450deg)}
}
@keyframes nc-loop-clock-anim-m {
0% {transform:rotate(0)}
100% {transform:rotate(360deg)}
}
If you are using an icon manager like Nucleo to manage all your icons, you can store your animations right within the SVG icon code:
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<g>
<!-- svg content here -->
</g>
<style>
/* CSS animation here */
</style>
</svg>
The application displays a play button for icons that contain an animation that can be triggered with a click:
The ability to animate distinct elements within a single SVG opens up a vast array of animation possibilities using just CSS. Below are a few more examples of animations:
The end! Check our documentation tutorials page for more articles on working with icons.