What if we need a shadow for the shape in SVG? If we use CSS box-shadow
on SVG elements, it won't have any effect.
As you may know, we have filter
and backdrop-filter
properties in CSS, and they are actually a subset of SVG filters! We can use SVG filters externally by using this property like this: filter: url(#filterId)
.
Table of contents
Embedded image
If we embed an image inside SVG, we will be able to clip, mask and apply filter on it.
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
x="5"
y="5"
width="90"
height="90"
href="https://picsum.photos/id/33/400"
/>
Basic structure of SVG filter
Let's look at how to apply a filter effect on some SVG shape (for example circle
):
xmlns="..." viewBox="...">
id="filterId">
filter="url(#filterId)" />
The filter effect can consist of multiple filter primitives. All filter primitives names start with fe
, which stands for "filter effect".
Filter primitives
We won't discuss every filter primitive, only stopping at the most needed ones. The full list can be found here.
Filter primitive attributes
All filter primitives can have the following attributes:
-
x
,y
(default 0, 0) are the minimum coordinates for the subregion of the filter primitive; -
width
,height
define dimensions for the subregion of the filter primitive; -
result="
assigns a name for the filter primitive, which can be referenced by an" in
attribute on another filter primitive.
Most filter primitives can take other ones as input with the following attribute:
-
in="
. If no value is specified," in
takesSourceGraphic
(original image) as one.
feDisplacementMap
This effect allows us to change the texture of the image by taking it from another image or effect.
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
id="morph">
baseFrequency="0.05" numOctaves="2" result="turbulence" />
in="SourceGraphic" in2="turbulence" scale="20" />
width="180" href="https://picsum.photos/id/33/200" filter="url(#morph)" />
Here, we used another filter effect feTurbulence to get the texture.
-
scale
(default 0) defines the amount of displacement; -
in="SourceGraphic"
specifies what image needs to be changed; -
in2
is used to displace the pixels in the image from thein
attribute.
feDropShadow
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
id="shadow">
/>
points="10,50 40,60 50,90 60,60 90,50 60,40 50,10 40,40"
fill="teal"
filter="url(#shadow)"
/>
-
dx
,dy
(default is 2) set offset of the drop shadow; -
stdDeviation
(default is 2) sets blur of the drop shadow.
feGaussianBlur
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
id="blur">
stdDeviation="1" />
href="https://picsum.photos/id/33/100"
filter="url(#blur)"
/>
-
stdDeviation
(default 0) defines the amount of blur. It can be equal to two numbers forx
andy
axes.
We can achieve the same output by defining a filter in SVG and applying it in CSS:
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="0" height="0">
id="blur">
stdDeviation="2" />
src="https://picsum.photos/id/33/100" />
/* style.css */
img {
filter: url(#blur);
}
feMorphology
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400">
id="morph">
operator="dilate" radius="10" />
href="https://picsum.photos/id/33/400" filter="url(#morph)" />
-
operator
takes values:-
erode
(default) makes the source graphic thinner; -
dilate
makes it fatter.
-
-
radius
(default 0) regulates the impact of the operator. It can be equal to two numbers forx
andy
axes.
feTurbulence
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
id="morph">
baseFrequency="0.05" numOctaves="2" />
href="https://picsum.photos/id/33/200" filter="url(#morph)" />
-
type
:-
turbulence
(default) performs turbulence function; -
fractalNoise
performs noise function.
-
-
baseFrequency
(default 0) specifies frequency for the noise function. It can take two values for x and y axes. -
numOctaves
(default 1) is the parameter for the noise function. The higher the value is, the more noise you get.