Fancy SVG filters
- Published at
- Updated at
- Reading time
- 2min
The CSS filter
property provides two hands full of handy filters.
filter: blur(5px);
filter: brightness(0.4);
filter: contrast(200%);
filter: drop-shadow(16px 16px 20px blue);
filter: grayscale(50%);
...
And that's cool, but filter
really shines when you apply custom SVG filters with the url()
function.
filter: url("filters.svg#filter-id");
SVG is such a secret powerhouse for creating custom filters. This post is my SVG filter bookmark, which I'll extend over time.
Artur Bień's post "Using HTML elements as CSS masks" triggered this post because he shared a very fancy SVG filter to mask out black pixels.
SVG filter code
<svg width="0" height="0">
<filter id="black-filter" colorInterpolationFilters="sRGB">
<feColorMatrix
type="matrix"
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -255 -255 -255 0 1"
result="black-pixels"
></feColorMatrix>
<feMorphology
in="black-pixels"
operator="dilate"
radius="0.5"
result="smoothed"
></feMorphology>
<feComposite
in="SourceGraphic"
in2="smoothed"
operator="out"
></feComposite>
</filter>
</svg>
If you play around with it, you'll discover that it only masks "real black" pixels. Still — it's a wild filter!
I love a good box-shadow
, but one problem with CSS shadows is that they only displays a single color. Wouldn't it be nice if you could create shadows that pick up a DOM elements color?
Guess what? SVG can do natural lighting shadows, too!
SVG filter code
<svg width="0" height="0">
<filter id="natural-shadow-filter" x="0" y="0" width="2" height="2">
<feOffset in="SourceGraphic" dx="3" dy="3" />
<feGaussianBlur stdDeviation="12" result="blur" />
<feMerge>
<feMergeNode in="blur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</svg>
Unfortunately, it looks like Safari still has issues with this filter, but hey... the world won't go down if Safari users won't see a colorful shadow. 🤷♂️
I found this effect on Robin Rendle's blog, and I love the rough and artsy feeling of added SVG noise.
SVG filter code
<svg width="0" height="0">
<defs>
<filter id="filters-noise" x="0%" y="0%" width="150%" height="150%">
<feTurbulence baseFrequency="0.01 0.01" numOctaves="1" result="noise"></feTurbulence>
<feDisplacementMap in="SourceGraphic" in2="noise" scale="10" xChannelSelector="R" yChannelSelector="R"></feDisplacementMap>
</filter>
<filter id="filters-little-noise" x="0%" y="0%" width="150%" height="150%">
<feTurbulence baseFrequency="0.02 0.02" numOctaves="1" result="noise"></feTurbulence>
<feDisplacementMap in="SourceGraphic" in2="noise" scale="10" xChannelSelector="R" yChannelSelector="R"></feDisplacementMap>
</filter>
<filter id="filters-extreme-noise" x="0%" y="0%" width="150%" height="150%">
<feTurbulence baseFrequency="0.8 2.7" numOctaves="1" result="noise"></feTurbulence>
<feDisplacementMap in="SourceGraphic" in2="noise" scale="10" xChannelSelector="R" yChannelSelector="R"></feDisplacementMap>
</filter>
</defs>
</svg>
Note that this effect combines three SVG filters that are rotated via a @keyframes
animation.
Nathan pointed me to a filter he created and look at this beauty. This SVG filter applies a text shadow only to the colors with a promiment red color channel. 😲
SVG filter code
<svg width="0" height="0">
<filter id="color-shadow-filter">
<!-- Inner shadow -->
<feFlood class="inner-shadow" flood-color="#d099ffd4"></feFlood>
<feComposite operator="out" in2="SourceAlpha"></feComposite>
<feMorphology operator="dilate" radius="0.5"></feMorphology>
<feBlend class="inner-shadow" mode="lighten" in2="SourceGraphic" result="inner-shadow"></feBlend>
<!-- Outer glow -->
<feColorMatrix in="SourceGraphic" type="matrix" values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
1 0 0 0 -.1"></feColorMatrix>
<feGaussianBlur result="glow" stdDeviation="3.5"></feGaussianBlur>
<!-- Composite everything -->
<feComposite operator="atop" in="inner-shadow" in2="SourceGraphic"></feComposite>
<feComposite operator="over" in2="glow"></feComposite>
</filter>
</svg>
If you have other SVG in your toolbox, shoot them my way! I'd love to extend this list!
Join 5.5k readers and learn something new every week with Web Weekly.