So, with that, let's take a deep and thorough dive into all of the SVG elements that are available to us as well as the CSS properties for them. We'll also look at various styling approaches, including general presentational styles and animations.
SVG 2
While presentation attributes can be used as CSS properties to style SVG, what about controlling the coordinates and dimensions of SVG elements using CSS? SVG 2, which is in Candidate Recommendation at the time of this writing, makes it is possible to style and animate these properties.
The SVG 2 specification states:
Some styling properties can be specified not only in style sheets and 'style' attributes, but also in presentation attributes. These are attributes whose name matches (or is similar to) a given CSS property and whose value is parsed as a value of that property."
Not only does it mean that SVG properties can be styled using CSS as presentation attributes or in style sheets, but this also can be applied to CSS pseudo-classes such as :hover
or :active
.
SVG 2 also introduces more presentation attributes that can be used as styling properties. These attributes can be found in SVG 2 specification.
Element-specific properties
It is important to note that not every SVG element will support the same CSS properties. Much like how there are CSS properties that can be applied to certain SVG elements, there are specific properties that are supported by certain SVG elements.
For example, the <circle>
or <ellipse>
elements support the cx
and cy
properties as coordinates of the center of the shape. The <ellipse>
element also supports the rx
and ry
properties as the radius, but the <circle>
element cannot use these properties.
Geometry properties
In SVG 2, properties such as rx
and ry
are defined as geometry properties. Geometry properties can be used as CSS properties, just like presentation attributes such as fill
or stroke
properties. These CSS properties and the corresponding SVG elements include:
SVG Element |
Geometry Property |
<circle> |
cx
cy
r |
<ellipse> |
cx
cy
rx
ry |
<rect> |
rx
ry
height
width
x
y |
<path> |
path |
<image> |
height
width
x
y |
<foreignObject> |
height
width
x
y |
<svg> |
code>height
width
x
y |
Positioning SVG elements
SVG 2 also makes it is possible to position SVG elements using CSS. Let’s begin with drawing a rectangle shape having the following SVG:
<svg width="170" height="170">
<rect x="10" y="10" width="150" height="150" />
</svg>
And the following CSS:
rect {
fill: #6e40aa;
}
See the Pen
QPeNGj by Geoff Graham (@geoffgraham)
on CodePen.
This will produce a rectangle shape with its coordinates set to 10, 10. With SVG 2, x
and y
can be applied as CSS properties:
/* This will work with SVG 2 */
rect {
x: 10;
y: 10;
...
}
The SVG code would be reduced to this:
<svg width="170" height="170">
<rect width="150" height="150" />
</svg>
You can even set the width
and height
for the <rect>
element using CSS like so:
rect {
...
width: 150px;
height: 150px;
...
}
That leaves us with just the following for SVG markup:
<svg width="170" height="170">
<rect />
</svg>
See the Pen
Positioning SVG elements by Katherine Kato (@kathykato)
on CodePen.
At the time of writing, the following demos will work in Blink (e.g. Chrome and Opera) and WebKit (e.g. Safari) browsers as these browsers support SVG 2 features. Until then, let’s dive into how to override SVG properties using CSS.
SVG shape morphing
The <path>
element can be overridden with CSS to create shape morphing.
The SVG paths that morph one into the other must have the same number of points or else the morphing will not work.
Let’s start with drawing a <path>
element in the shape of a triangle. Using the d
property will specify the shape of the <path>
element:
<svg height="220" width="300">
<path d="M150 10 L40 200 L260 200Z" />
</svg>
To get the triangle to morph into a different shape, let’s override the SVG <path>
element with the d
property with CSS:
path {
d: path("M150, 10 L40, 200 L260, 200Z");
fill: #4c6edb;
}
Let’s also add a :active
pseudo-class to the <path>
property so when the element is clicked, the shape will morph into a square and change its fill
color. Let’s also add a transition
property to make the shape morphing action appear smooth. Here is the CSS:
path:active {
d: path("M150, 10 L40, 200 L260, 200 L260, 200Z");
fill: #4c6edb;
transition: all 0.35s ease;
}
And the SVG would be:
<svg height="220" width="300">
<path />
</svg>
See the Pen
SVG shape morphing by Katherine Kato (@kathykato)
on CodePen.
Want another demo? Here is a cool demo from Chris Coyier demonstrating SVG shape morphing on hover!
See the Pen
Simple Path Examples by Chris Coyier (@chriscoyier)
on CodePen.
Animating SVG properties
SVG properties can be animated using CSS through CSS animations and transitions.
In this demo, we will draw various SVG <circle>
elements and create a wave animation. Start by drawing five <circle>
elements:
<svg width="350" height="250">
<circle class="shape" />
<circle class="shape" />
<circle class="shape" />
<circle class="shape" />
<circle class="shape" />
</svg>
We’ll be using CSS variables and :nth-child()
CSS pseudo-class to define each .shape
class. The .shape
class will have a cy
of 50 and a r
of 20. Each of the .shape
classes will have their own cx
and fill
CSS properties set:
:root {
--color-1: #6e40aa;
--color-2: #4c6edb;
--color-3: #24aad8;
--color-4: #1ac7c2;
--color-5: #1ddea3;
}
.shape {
cy: 50;
r: 20;
}
.shape:nth-child(1) {
cx: 60;
fill: var(--color-1);
}
.shape:nth-child(2) {
cx: 120;
fill: var(--color-2);
}
.shape:nth-child(3) {
cx: 180;
fill: var(--color-3);
}
.shape:nth-child(4) {
cx: 240;
fill: var(--color-4);
}
.shape:nth-child(5) {
cx: 300;
fill: var(--color-5);
}
Here is how it should look so far.
See the Pen
Animating SVG properties: Pre-animation by Geoff Graham (@geoffgraham)
on CodePen.
Now it’s time to animate! Start by using @keyframes
rule to define the moveCircle
animation:
@keyframes moveCircle {
50% {
cy: 150;
r: 13;
}
}
This will get each <circle>
element to change their cy
coordinates from 50 to 150 and r
from 20 to 13. Add the following to the CSS to the .shape
class get the animation running infinitely:
.shape {
...
animation: moveCircle 1250ms ease-in-out both infinite;
}
Finally, add an animation-delay
to each of the .shape
classes to the CSS with the exception of .shape:nth-child(1)
like this:
.shape:nth-child(2) {
...
animation-delay: 100ms;
}
.shape:nth-child(3) {
...
animation-delay: 200ms;
}
.shape:nth-child(4) {
...
animation-delay: 300ms;
}
.shape:nth-child(5) {
...
animation-delay: 400ms;
}
See the Pen
Animating SVG properties by Katherine Kato (@kathykato)
on CodePen.
Shapes in SVG <pattern>
elements can also be animated using CSS. Here is a cool demo by Dudley Storey showcasing that!
See the Pen
Screen by Dudley Storey (@dudleystorey)
on CodePen.
Wrapping up
As SVG 1.1 is the current standard, few browsers currently support SVG 2 features. It is not recommended to put these techniques into production yet. SVG 2 implementation is currently at Candidate Recommendation stage, thus support for styling SVG geometry properties with CSS should improve in the future.
The post SVG Properties and CSS appeared first on CSS-Tricks.