I’ve been thinking about writing an article about SVG filters for a long time. SVG filters make CSS even more powerful. Take your CSS/HTML/SVG authoring to the next level. CodePen Demo — Cloud (SVG filter + CSS)

What is an SVG filter

SVG filters, similar to CSS filters, are a mechanism used in SVG to create complex effects. Many people are put off by the complex syntax of SVG filters. This article is trying to get you to understand how SVG filters work in the simplest way possible.

This article assumes that the reader is already familiar with the basic concepts and usage of SVG.

Types of SVG filters

SVG filters include:

feBlend
feColorMatrix
feComponentTransfer
feComposite
feConvolveMatrix
feDiffuseLighting
feDisplacementMap
feFlood
feGaussianBlur
feImage
feMerge
feMorphology
feOffset
feSpecularLighting
feTile
feTurbulence
feDistantLight
fePointLight
feSpotLight
Copy the code

It looks a lot like the different functions in CSS filters: blur(), contrast(), drop-shadow().

Syntax for SVG filters

We need to define an SVG filter using the

and

tags.

In general, all SVG filter elements need to be defined within the

tag.

Now, basically, modern browsers can define an SVG filter without wrapping

around

.

The

tag is an abbreviation of definitions, and can contain many other tags, including filters.

Second, the

tag is used to define the SVG filter. The

tag requires an ID attribute, which identifies the filter. SVG graphics use this ID to reference filters.

Take a look at a simple DEMO:

<div class="cssFilter"></div>
<div class="svgFilter"></div>

<svg>
    <defs>
        <filter id="blur">
            <feGaussianBlur in="SourceGraphic" stdDeviation="5" />
        </filter>
    </defs>
</svg>
Copy the code
div {
    width: 100px;
    height: 100px;
    background: # 000;
}
.cssblur {
    filter: blur(5px);
}
.svgFilter{
    filter: url(#blur);
}
Copy the code

Here, we use SVG’s feGaussianBlur filter, also known as blur filter, in the filter tag of DEFS. The filter has two attributes in and stdDeviation. The in=”SourceGraphic” attribute indicates that the blur effect should be applied to the entire image, and the stdDeviation attribute defines the degree of blur. Finally, in THE CSS, filter: URL (#blur) is used to call the filter with the ID blur defined in the HTML.

To make it easier to understand, a similar CSS filter filter: blur(5px) is also used for comparison. The result is shown below:

CodePen Demo-SVG filter

Hey, you can see that the SVG blur filter achieves the same effect as the CSS blur filter.

Url mode of CSS filter

The example above uses filter: Url (#blur) this mode introduces an SVG filter effect. Url is one of the keywords in the CSS filter property. Url mode is one of the capabilities provided by CSS filters, allowing us to introduce specific SVG filters, which greatly enhances the ability of CSS filters.

All SVG filters can be quickly introduced with one click through the CSS filter URL mode.

Work with multiple filters

Like CSS filters, SVG filters can be mixed with multiple filters.

So it’s not uncommon to see a

tag with a lot of code in it. It’s easy to get confused

Here’s a simple example:

<div></div>

<svg>
    <defs>
        <! -- Filter declaration -->
        <filter id="MyFilter">

            <! -- offsetBlur -->
            <feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur" />
            <feOffset in="blur" dx="10" dy="10" result="offsetBlur" />

            <! -- merge SourceGraphic + offsetBlur -->
            <feMerge>
                <feMergeNode in="offsetBlur" />
                <feMergeNode in="SourceGraphic" />
            </feMerge>
        </filter>
    </defs>
</svg>
Copy the code
div {
    width: 200px;
    height: 200px;
    background: url(xxx);
    filter: url(#MyFilter);
}
Copy the code

Let’s take a look at the final result of the entire filter, which looks like this:

SVG takes so much code to do what CSS might do in one line. (Of course, CSS is also difficult to implement here, not simple container shadow, but PNG image shape outline shadow)

Decomposition steps

First look at this passage:

<! -- offsetBlur -->
<feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur" />
<feOffset in="blur" dx="10" dy="10" result="offsetBlur" />
Copy the code

First of all,
, as we mentioned above, will generate a blur effect, and there is a new attribute result=’blur’, This is one of the features of SVG. Results can be used to produce an intermediate result (primitives), and other filters can use the in attribute to import results from different filters and continue operations.

Next, the

filter is easy to understand, using in to get the result of the previous step, result = ‘blur’, and then do a simple shift.

Here’s an important point: using the Result and IN attributes in different filters allows you to create an operation on top of the first basic transformation operation, such as adding a blur and then a shift effect in our example.

Combining the two filters produces a graphic effect that actually looks like this:

The original image also appears in the actual effects, so here we also use the

tag to merge multiple effects. This is the code above:

<! -- merge SourceGraphic + offsetBlur -->
<feMerge>
    <feMergeNode in="offsetBlur" />
    <feMergeNode in="SourceGraphic" />
</feMerge>
Copy the code

The feMerge filter allows filter effects to be applied simultaneously rather than sequentially. You can do this by storing the output of another filter with Result, and then accessing it in an

child element.

  • <feMergeNode in="offsetBlur" />Represents the final output of the above two filtersoffsetBlur That’s the shaded part
  • <feMergeNode in="SourceGraphic" />In thein="SourceGraphic"Keywords indicate that the graphic element itself will act as<filter>The raw input to the primitive

The whole then follows the principle that the higher the level of the input is, and the above results are finally obtained. The schematic flow chart is as follows:

At this point, you have a basic understanding of how SVG filters work and how to use multiple filters together. Next, you just need to understand what effects different filters can produce and what different attributes they have to get a basic understanding of SVG filters!

Something else to know about SVG filters

This section Outlines how to use an SVG filter. Some attributes are mentioned, but some attributes are missing.

Filter tag general properties

There are some properties that can be set on every filter TAB.

attribute role
x, y Provides the coordinates in the upper left corner to define where to render the filter effect. (Default: 0)
width, height Draws the height and width of the filter container box (both default to 100%)
result The output name used to define one filter effect so that it can be used as the input to another filter effect (in)
in Specifies the input source for the filter effect, which can be exported from a filterresult, can also be the following six values

Six values for the in attribute

The in attribute in SVG filter, which specifies the input source for the filter effect, can be the result of a filter export, or can have the following six values:

inThe values role
SourceGraphic This keyword indicates that the graphic element itself will act as<filter>The raw input to the primitive
SourceAlpha This keyword indicates that the graphic element itself will act as<filter>The raw input to the primitive.SourceAlpha 与 SourceGraphicHas the same rules exceptSourceAlphaUse only the opaque parts of the element
BackgroundImage Similar to SourceGraphic, but can be used on backgrounds. Explicit Settings are required
BackgroundAlpha Similar to SourceAlpha, but available in the background. Explicit Settings are required
FillPaint Place it on an infinite plane using fill paint
StrokePaint Place it on an infinite plane and draw with a stroke

The last four are basically useless

The last four are not used very often.

More on SVG filters

We’ve already mentioned a few filters, so let’s review them briefly:

  • <feGaussianBlur >– Blur filter
  • <feOffset >– Displacement filter
  • <feMerge>– Multi-filter overlay filter

Here are some of the more common and interesting SVG filters.

FeBlend filter


is a blend mode filter, similar to the blend mode in CSS.

In CSS, we have mix-blending-mode and background-blending-mode. I’ve written a number of articles about the use of CSS hybrid modes. If you’re not familiar with CSS blending, check out these articles:

  • Incredible mix mode mix-blending-mode
  • Incredible blend mode background-blending-mode
  • CSS whimsy – Use background to create all kinds of beautiful backgrounds

SVG has a smaller variety of hybrid modes than CSS, with only 5, which are exactly the same as CSS hybrid modes:

  • Normal, normal
  • Multiply – Multiply
  • Screen – screen
  • Darken – dimmed
  • Lighten – brighten

In a simple Demo, we have two graphs. Different mixing results can be obtained by using different mixing modes:

<div></div>

<svg>
    <defs>
        <filter id="lighten" x="0" y="0" width="200" height="250">
            <feImage width="200" height="250" xlink:href="image1.jpg" result="img1" />
            <feImage width="200" height="250" xlink:href="image2.jpg" result="img2" />
            <feBlend mode="lighten" in="img1" in2="img2"/>
        </filter>
    </defs>
</svg>
Copy the code
.container {
    width: 200px;
    height: 250px;
    filter: url(#lighten);
}
Copy the code

A

filter is also used, which provides pixel data as output, and if the external source is an SVG image, the image will be rasterized.

We’ve been working hard to lighten the load with mode=”lighten” in feBlend.

Take a look at the effects of all 5 blend modes:

CodePen Demo — SVG Filter feBlend Demo

feColorMatrix

The

filter is also one of the most interesting SVG filters. As its name implies, it includes the word matrix in its name, which means that the filter transforms colors based on a transformation matrix. The color value of each pixel (a vector denoted by red, green, blue, transparency) is a new color calculated by matrix multiplation.

This filter is a little bit more complicated, so let’s go through it step by step.

The

filter has two private attributes, type and values. Type supports four different types: Saturate | hueRotate | luminanceToAlpha | matrix, some of them are similar to some of the CSS Filter Filter effects.

typetype role valuesValue range of
saturate Convert image saturation 0.0-1.0
hueRotate Convert image hue 0.0-360.
luminanceToAlpha Alpha channel brightness There is only one effect, without changing the value of values
matrix Color transformation using matrix functions I need to apply a 4 by 5 matrix

Here, I made a simple about < feColorMatrix > before three attributes saturate | hueRotate | luminanceToAlpha indicated the effect of the DEMO – CodePen – feColorMatrix DEMO, To get a feel for their specific effects:

Saturate and hueRotate filters work exactly the same as saturate and Hue-Rotate in the FILTER in the CSS.

The type = feColorMatrix matrix

The type=matrix in feColorMatrix is a little more complicated to understand, with values passed in as a 4×5 matrix.

Something like this:

<filter id="colorMatrix">
  <feColorMatrix type="matrix" values="1 0 0 0 0 0 0, 0 1 0 0 0, 0 0 1 0 0, 0 0 0 1 0 0"/>
</filter>
Copy the code

To understand how to use these fill-in matrices, we have to confront another problem — the representation of images.

The essence of digital image is a multidimensional matrix. When the image is displayed, we put the R component of the image into the red channel, the B component into the blue channel, and the G component into the green channel. After a series of processing, what appears on the screen is the color image we see.

The matrix matrix in feColorMatrix is used to represent the values of different channels, and the values of each component are finally calculated to get the well-known RGBA () value.

The calculation logic is:

/* R G B A 1 */ 
1 0 0 0 0 // R = 1*R + 0*G + 0*B + 0*A + 0 
0 1 0 0 0 // G = 0*R + 1*G + 0*B + 0*A + 0 
0 0 1 0 0 // B = 0*R + 0*G + 1*B + 0*A + 0 
0 0 0 1 0 // A = 0*R + 0*G + 0*B + 1*A + 0
Copy the code

Chinese articles, the best explanation of the matrix of feColorMatrix should be the one written by Da Mo teacher — a detailed explanation of feColorMatrix. Those who are interested in the specific representation can have a look.

Just for use, there is also a visual DEMO of codepen-fecolormatrix to help you understand the memory:


So far, most SVG filters have been demonstrated with CSS’s existing capabilities. What makes SVG filters unique and attractive? Is there anything CSS capabilities can’t do? Let’s take a look at some other interesting SVG filters.

FeSpecularLighting/feDiffuseLighting light filters

FeSpecularLighting and feDiffuseLighting both mean light filters that can illuminate a source image with them. The difference is that feSpecularLighting is specular lighting while feDiffuseLighting is scattered light.

  • FeDiffuseLighting: lighting from an external light source, suitable for simulating sunlight or lighting
  • FeSpecularLighting: Specifies the secondary light reflected from the reflector

Looking briefly at one of the demos, the code looks a bit long, but it’s easy to understand step by step:

<div></div>
<div class="svg-filter"></div>
<svg>
    <defs>
        <filter id="filter">
            <! --Lighting effect-->
            <feSpecularLighting in="SourceGraphic" specularExponent="20" specularConstant="0.75" result="spec">
              <fePointLight x="0" y="0" z="200" />
            </feSpecularLighting>
            <! --Composition of inputs-->
            <feComposite in="SourceGraphic" in2="spec" operator="arithmetic" k1="0" k2="1" k3="1" k4="0" />
        </filter>
    </defs>
</svg>
Copy the code
div {
    background: url(avator.png);
}
.svg-filter {
    filter: url(#filter);
}
Copy the code

On the left is the original image, and on the right is the effect after applying the light filter.

CodePen – feSpotLight SVG Light Source

FeMorphology filter

FeMorphology is a morphologic filter whose input source is usually the alpha channel of the graph, and its two operations can make the source graph corroded (thinner) or expanded (thicker).

Use the property operator to determine whether you want to corrode or expand the effect. Use the attribute RADIUS to indicate the extent of the effect, which can be interpreted as the size of the stroke.

  • Operator:erodeCorrosion mode,dilateThe default value is expansion modeerode
  • Radius: The size of the stroke. It accepts a number indicating the degree of effect in this mode. The default is 0

Let’s simply apply this filter to text to see what it looks like:

<div class="g-text">
    <p>Normal Text</p>
    <p class="dilate">Normal Text</p>
    <p class="erode">Normal Text</p>
</div>

<svg width="0" height="0">
    <filter id="dilate">
        <feMorphology in="SourceAlpha" result="DILATED" operator="dilate" radius="3"></feMorphology>
    </filter>
    <filter id="erode">
        <feMorphology in="SourceAlpha" result="ERODE" operator="erode" radius="1"></feMorphology>
    </filter>
</svg>
Copy the code
p {
    font-size: 64px;
}
.dilate {
    filter: url(#dilate);
}
.erode {
    filter: url(#erode);
}
Copy the code

The text on the left is normal, the text in the middle is expanded, and the text on the right is corroded.

Of course, we can also apply this to images, where instead of just making the strokes thicker or thinner,

  • forerodeMode, which changes each pixel of the image in a darker and more transparent direction,
  • whiledilateMode, which changes each pixel in a brighter and less transparent direction around it

We have two graphs with operator=”erode” and operator=”dilate” to dynamically change the RADIUS. The code for one of the graphs looks like this:

<svg width="450" height="300" viewBox="0 0 450 300">
    <filter id="morphology">
        <feMorphology operator="erode" radius="0">
            <animate attributeName="radius" from="0" to="5" dur="5s" repeatCount="indefinite" />
        </feMorphology>
    </filter>

    <image xlink:href="image.jpg" width="90%" height="90%" x="10" y="10" filter="url(#morphology)"></image>
</svg>
Copy the code

Expansion mode on the left and erosion mode on the right:

CodePen Demo — SVG feMorphology Animation

FeTurbulence filter

The SVG

filter can achieve translucent smoky or wavy images. Usually used to implement special textures. The filter creates an image using the Perlin noise function. Noise is very useful in simulating the effects of cloud and fog, which can produce very complex textures. It can be used to achieve the synthesis of artificial textures such as moire and marbling.

With feTurbulence, we can use SVG to create texture shapes as displacement diagrams without resorting to external texture effects to create complex graphics.

This filter, I personally think, is one of the most interesting SVG filters because it allows us to create our own textures and overlay them on top of other effects to produce very interesting animations.

Three feTurbulence attributes need special attention: Type, baseFrequency and numOctaves:

  • Type: Optional filter type to implementfractalNoiseFractal noise, orturbulenceTurbulent noise.
    • FractalNoise: fractalNoise is smoother and produces a noise texture closer to cloud
    • Turbulence: Turbulent noise
  • BaseFrequency: indicates the basic frequency of a noise function. The lower the frequency, the larger the pattern. The higher the frequency, the more complex the noise, the smaller and more refined the pattern
  • NumOctaves: Indicates the fineness of the noise function, the higher the value, the more detailed the noise generated. The default value is 1

There is a very good site showing the effects of two kinds of noise produced by feTurbulence: apike.ca/ -feturbul…

The code of the two kinds of noise is basically the same, but the type of type is different:

<filter id="fractal" >
  <feTurbulence id="fe-turb-fractal" type="fractalNoise" baseFrequency="0.00025" numOctaves="1"/>
</filter>
<filter id="turbu">
  <feTurbulence id="fe-turb-turbulence" type="turbulence" baseFrequency="0.00025" numOctaves="1"/>
</filter>
Copy the code

Let’s change the baseFrequency and numOctaves parameters to see the actual effects of two kinds of noise:

Also, baseFrequency allows us to pass in two values. We can only change the frequency in one direction. You can poke this Demo to see: CodePen — feTurbulence baseFrequency & numOctaves

A

filter alone is difficult to understand what the filter is trying to do. You need to use this filter as a texture or input and use it with other filters to achieve some effects. Let’s take a look at the following:

Use feTurbulence to create text flow

First, try to combine the texture produced by feTurbulence with the text.

The simple code is as follows:

<div>Coco</div>
<div class="turbulence">Coco</div>

<svg>
    <filter id="fractal" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
        <feTurbulence id="turbulence" type="fractalNoise" baseFrequency="0.03" numOctaves="1" />
        <feDisplacementMap in="SourceGraphic" scale="50"></feDisplacementMap>
    </filter>
</svg>
Copy the code
.turbulence {
    filter: url(#fractal);
}
Copy the code

On the left is the normal effect, and on the back is the effect with

. You can click on the Demo and change the baseFrequency and numOctaves parameters. You can see different effects:

CodePen Demo — feTurbulence text demo

FeDisplacementMap map displacement filter

The above Demo also uses the feDisplacementMap filter, which also needs to be explained briefly.

FeDisplacementMap replaces filters for maps. It is not easy to use this filter and requires a lot of knowledge about PhotoShop texture creation or graphic color. This filter replaces the image’s in input value with the pixel value from the in2 input value to the space from the image.

FeDisplacementMap is actually used to change the pixel positions of elements and graphics. The filter forms a new image by iterating through all the pixels of the original image and remapping it to a new location using feDisplacementMap.

In the combination of the above feTurbulence filter and text, we obtained the noise graph through feTurbulence noise, and then deformed, distorted and liquefied the noise graph generated by feDisplacementMap filter. To get the final result.

There is a formula for this filter transformation in MDN:

P '(x, y) please P (x + scale * (XC (x, y) - 0.5), y + scale * (YC (x, y) - 0.5))Copy the code

Use feTurbulence filter to achieve pleated paper texture

Ok, let’s move on to feTurbulence. Using this filter, we can generate various textures. We can try to use feTurbulence with light filter to achieve a crumpled paper texture with very little code:

<div></div>
<svg>
    <filter id='roughpaper'>
        <feTurbulence type="fractalNoise" baseFrequency='0.04' result='noise' numOctaves="5" />

        <feDiffuseLighting in='noise' lighting-color='#fff' surfaceScale='2'>
            <feDistantLight azimuth='45' elevation='60' />
        </feDiffuseLighting>
    </filter>
</svg>
Copy the code
div {
    width: 650px;
    height: 500px;
    filter: url(#roughpaper);
}
Copy the code

The effect is as follows:

CodePen Demo — Rough Paper Texture with SVG Filters

You can find a tutorial on how to make SVG Filters Crash Course on Youtube in Sara Soueidan’s post on SVG Filters Crash Course

Hover button effect with feTurbulence

Using the feTurbulence filter with the feDisplacementMap filter, you can also make some very interesting button effects.

Try implementing some fail-style buttons, one of which has the following code:

<div class="fe1">Button</div>
<div class="fe2">Button</div>

<svg>
    <defs>
        <filter id="fe1">
            <feTurbulence id="animation" type="fractalNoise" baseFrequency="0.00001 9.9999999" numOctaves="1" result="warp">
                <animate attributeName="baseFrequency" from="0.00001 9.9999" to="0.00001 0.001" dur="2s" repeatCount="indefinite"/>
            </feTurbulence>
            <feOffset dx="90" dy="90" result="warpOffset"></feOffset>
            <feDisplacementMap xChannelSelector="R" yChannelSelector="G" scale="30" in="SourceGraphic" in2="warpOffset"></feDisplacementMap>
        </filter>
    </defs>
</svg>
Copy the code
.fe1 {
    width: 200px;
    height: 64px;
    outline: 200px solid transparent;
}

.fe1:hover {
    filter: url(#fe1);
}
Copy the code

When hover button is passed, add a filter to the button and the filter itself has an infinite loop animation:

CodePen Demo-SVG Filter Button Effects

Use feTurbulence to create clouds

Finally, we returned to the cloud effect in the picture. Using the feTurbulence filter, we could simulate the real cloud effect in SVG very realistically.

Firstly, a graph is realized by randomly generating multiple box-shadow:

<div></div>
Copy the code
div {
    width: 1px;
    height: 1px;
    box-shadow: rgb(240 255 243) 80vw 11vh 34vmin 16vmin.rgb(17 203 215) 33vw 71vh 23vmin 1vmin.rgb(250 70 89) 4vw 85vh 21vmin 9vmin.rgb(198 241 231) 8vw 4vh 22vmin 12vmin.rgb(198 241 231) 89vw 11vh 31vmin 19vmin.rgb(240 255 243) 5vw 22vh 38vmin 19vmin.rgb(250 70 89) 97vw 35vh 33vmin 16vmin.rgb(250 70 89) 51vw 8vh 35vmin 14vmin.rgb(17 203 215) 75vw 57vh 40vmin 4vmin.rgb(250 70 89) 28vw 18vh 31vmin 11vmin.rgb(250 70 89) 8vw 89vh 31vmin 2vmin.rgb(17 203 215) 13vw 8vh 26vmin 19vmin.rgb(240 255 243) 98vw 12vh 35vmin 5vmin.rgb(17 203 215) 35vw 29vh 27vmin 18vmin.rgb(17 203 215) 67vw 58vh 22vmin 15vmin.rgb(198 241 231) 67vw 24vh 25vmin 7vmin.rgb(17 203 215) 76vw 52vh 22vmin 7vmin.rgb(250 70 89) 46vw 86vh 26vmin 20vmin.rgb(240 255 243) 50vw 20vh 25vmin 1vmin.rgb(250 70 89) 74vw 14vh 25vmin 16vmin.rgb(240 255 243) 31vw 100vh 29vmin 20vmin
}
Copy the code

This job, which you can hand over to SASS, LESS, or JavaScript with looping capabilities, looks something like this:

Then, the fractal noise graph is generated through feTurbulence, and the feDisplacementMap is used for mapping displacement. Finally, the filter effect is superimposed on the graph.

<svg width="0">
  <filter id="filter">
    <feTurbulence type="fractalNoise" baseFrequency=". 01" numOctaves="10" />
    <feDisplacementMap in="SourceGraphic" scale="240" />
  </filter>
</svg>
Copy the code
div {
    filter: url(#filter);
}
Copy the code

To get this cloud effect:

Full code, you can poke here to Yuan Chuan teacher’s CodePen to watch: Cloud (SVG filter + CSS)

To summarize

This article briefly introduces the use of SVG filters and some common SVG filters and gives some of the simplest effects. I hope you can have a simple understanding of SVG filters after reading them.

The filter effects listed in this article are mostly single effects or a few combined effects. The actual use or application to application scenarios will actually be a combination of more filters.

Later articles will explore the effects of multiple SVG filter combinations in more detail and explore more complex permutations.

The title of this article is SVG Filters from Getting Started to Giving up because SVG filters are really hard to learn and it’s not as easy to learn as CSS filters or blending modes. It’s also because SVG filters are powerful, customizable and have been around for so long. SVG filters are also very compatible, and they actually predate some of the special effects of CSS3.

CSS has been converging on some of THE special capabilities of SVG, making it easier to use with a simpler syntax, but SVG filters still have their own appeal. More on SVG filters will follow. Also hope that the students reading here do not give up!

The resources

  • Rounding feColorMatrix
  • In-depth understanding of SVG feDisplacementMap filters and practical applications
  • SVG tutorialspoint
  • apike.ca – SVG Filter
  • FILTER EFFECTS
  • Youtube – SVG Filter Effects | feTurbulence
  • Youtube – SVG Filters Crash Course
  • DistortedButtonEffects

The last

Well, the end of this article, I hope to help you πŸ™‚

More interesting CSS technology articles are summarized in my Github — iCSS, constantly updated, welcome to click on the star subscription favorites.

Want to Get the most interesting CSS information, do not miss my public account – iCSS front-end interesting news πŸ˜„

If there are any questions or suggestions, you can exchange more original articles, writing is limited, talent and learning is shallow, if there is something wrong in the article, hope to inform.