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.

An SVG filter to cut out black pixels

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.

⚫ Here's some black text ◾
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!

A natural shadow SVG 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. 🤷‍♂️

A fancy noise / dither SVG filter

I found this effect on Robin Rendle's blog, and I love the rough and artsy feeling of added SVG noise.

hello world!
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.

Color channel-dependent text shadow

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. 😲

hello world!
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!

If you enjoyed this article...

Join 5.4k readers and learn something new every week with Web Weekly.

Web Weekly — Your friendly Web Dev newsletter
Stefan standing in the park in front of a green background

About Stefan Judis

Frontend nerd with over ten years of experience, freelance dev, "Today I Learned" blogger, conference speaker, and Open Source maintainer.

Related Topics

Related Articles