Make your website dazzle with CSS filters

Alex Danilo demonstrates how to use CSS filters combined with SVG filter components to help make your website stand out from the crowd.

Using CSS filters to enhance your content makes your site really sizzle. What's less well known is that you can build amazing primitives by combining SVG filter components into a fancy CSS filter that will make your site stand out from the crowd. This tutorial walks you through construction of a multi-stage filter combining lighting, blur and noise to create a stunning 3D effect on your text content.

CSS filters are a great tool for changing the way your content is displayed on your site. The pre-canned effects are built up from simple building blocks and are great for blurs, colour manipulation amongst many other effects. Each of these building blocks is like a brick that, when combined together, construct a beautiful house. Even better, you can stack these bricks together yourself and make your own CSS filter effects! How? Well, we're about to dive in and build a couple of effects that you can use as inspiration for your future projects.

We'll start by looking at SVG. SVG is a vector graphics language that's built into all modern HTML5 browsers. One of its nicest features is filters. SVG includes a <filter> element and a bunch of different filter primitives. The SVG filter primitives are the bricks in our construction set. We're going to stack a bunch of them together and then use them on our web page content.

Once we've piled up our bricks into the filter effect we want to use, we can simply reference the markup from CSS and use CSS selectors to apply it to our content. So let's start with a fairly simple example, then later on we'll try something a bit more complex.

Building a glow filter

In this first example, we're going to construct a filter that we can use to create a glow. We're going to use four different filter primitives to build our glow filter - feGaussianBlur (which creates a blurring effect), feFlood (which fills an area with a solid colour), feComposite (which mixes pixels together) and feMerge (which merges the filtered content with our original text to produce the final result).

The first thing we want for our glowing text is to take a snapshot of the text and convert it to white (since later on we'll use the white text to create the glow effect). The SVG filter code to create the white text is this:

<filter id=”white”>
  <feFlood flood-color=”white” />
  <feComposite in2=”SourceAlpha” operator=”in” result=”white”/>
</filter>

This filter contains two building blocks. The first is the feFlood filter effect which fills the area affected by the filter with white (filters use a rectangular off-screen image area to create each effect in the filter chain). The second is the feComposite filter effect, which is used to combine the pixels from the original content and the output from another filter effect using some sort of combination rule.

It's important to note here that the SVG filters work in a fixed order, so they're chained together in a sequence. When we apply that filter to our content, the feFlood filter effect runs first, then the feComposite effect uses the output from feFlood as its input. In the case of feComposite, it's using the 'in' operator. That's the combination rule that says 'create an image from my input using only pixels that are inside the original content'. So it's creating an intersection in maths terminology. The result of this filter is our white flooded rectangular image masked by anything it's applied to.

In this case, we get a masked result of white text. The way in which we apply this filter to our web content is to use a CSS selector to choose content that we want to be affected. An example of this could be something like:

.white {
  -webkit-filter: url(#white);
  filter: url(#white);
}

This would apply the filter to anything with a CSS class of 'white'. Of course if we tried to apply that to a blank page we'd paint white on a white background (not very useful), so let's add some background colour to see what we get:

.bluebg {
  background-color: lightblue;
}
<div class=”bluebg”>
<h1 class=”white”>WHITE GLOW FILTER</h1>
</div>

Now that we've gone through the foundation steps to build a two-stage filter and apply it to our web page text content, it's time to add some more effects.

Creating a blurred effect

To make our text glow effect, we need to grab the white text from our filter chain above and blur it. That'll become the basis for the glow around the text. To create the blurred version, we use:

<filter id=”whiteblur”>
  <feFlood flood-color=”white” />
  <feComposite in2=”SourceAlpha” operator=”in” />
  <feGaussianBlur stdDeviation=”4” />
</filter>

As you can see, we've used an additional effect - feGaussianBlur. That effect takes the white text that we created with our previous filter and makes it look fuzzy by using this markup:

.whiteblur {
  -webkit-filter: url(#whiteblur);
  filter: url(#whiteblur);
}
<div class=”bluebg”>
  <h1 class=”whiteblur”>WHITE GLOW FILTER</h1>
</div>

We need to enhance the blurred result to be a bit brighter. To do so, we'll use the feComponentTransfer effect. That's a filter effect that lets us play with the colour and alpha channels in our offscreen image in all sorts of ways.

Four filter blocks combine to produce a halo-like effect

We're going to brighten up the blurred image by modifying the alpha channel. So now our filter chain looks like:

<filter id=”whitetransfer”>
  <feFlood flood-color=”white” />
  <feComposite in2=”SourceAlpha” operator=”in” />
  <feGaussianBlur stdDeviation=”4” />
  <feComponentTransfer>
  <feFuncA type=”linear” slope=”3” intercept=”0” />
  </feComponentTransfer>
</filter>

You'll notice that we've used the feFuncA effect, which is modifying the alpha channel by multiplying its value by three (the slope argument).

We then apply that filter by using the markup as shown below:

whitetransfer {
  -webkit-filter: url(#whitetransfer); filter: url(#whitetransfer);
}
<div class=”bluebg”>
<h1 class=”whitetransfer”>WHITE GLOW FILTER</h1>
</div>

All we need to do is combine the results of our filter effect with the original text we applied it to by use of the feMerge filter effect.

The final version of our filter chain ends up looking like:

<filter id=”whiteglow”>
  <feFlood flood-color=”white” />
  <feComposite in2=”SourceAlpha” operator=”in” />
  <feGaussianBlur stdDeviation=”4” />
  <feComponentTransfer>
  <feFuncA type=”linear” slope=”3” intercept=”0” />
  </feComponentTransfer>
  <feMerge>
  <feMergeNode />
  <feMergeNode in=”SourceGraphic” />
  </feMerge>
  </filter>

And then we can apply it to our markup:

.whiteglow {
  -webkit-filter: url(#whiteglow);
  filter: url(#whiteglow);
}
<div class=”bluebg”>
<h1 class=”whiteglow”>WHITE GLOW FILTER</h1>
</div>

Building a chiselled effect

This second example uses a whole slew of filter effects to create a 3D looking chiselled effect from our text content. The SVG filter effects used here include random noise, morphology, lighting and more. Don't worry, they sound daunting but are really easy to use.

Lighting and bump maps combine to create a 3D-like look

The way this filter works is by combining three functional steps, each of which uses a number of different filter effects. To make it work we simply do the following:

  1. Convert an image into a 'bump map' (see the page opposite for more information).
  2. Create an embossed look from our original text.
  3. Create a drop shadow that enhances our 3D look.

Creating the bump map

Bump maps are used in 3D games. Think of them as a rough texture like cloth or a mountain range, where each pixel represents a different height.

To create the bump map, we put together a whole slew of filter effects. Here's the example code:

<filter id=”bumps”>
  <feTurbulence type=”turbulence” baseFrequency=”0.1” numOctaves=”2” result=”texture”/>
  <feMerge result=”textureAndGraphic”>
    <feMergeNode />
    <feMergeNode in=”SourceGraphic” />
  </feMerge>
  <feColorMatrix type=”luminanceToAlpha” in=”texture” result=”textureMap”/>
  <feGaussianBlur in=”SourceAlpha” stdDeviation=”6” result=”blur”/>
  <feDiffuseLighting in=”textureMap” surfaceScale=”2” lighting-color=”white” diffuseConstant=”1” result=”backgroundDiff”>
    <feSpotLight id=”spotLight” x=”50” y=”50” z=”150” pointsAtX=”150” pointsAtY=”150” pointsAtZ=”0” specularExponent=”8” />
  </feDiffuseLighting>
  <feDiffuseLighting in=”blur” surfaceScale=”6” lightingcolor=” white” diffuseConstant=”1.2” result=”foregroundDiffAll”>
    <feDistantLight id=”distantLight” azimuth=”-135” elevation=”40” />
  </feDiffuseLighting>
  <feComponentTransfer>
    <feFuncR type=”gamma” amplitude=”1” exponent=”3” offset=”0”/>
    <feFuncG type=”gamma” amplitude=”1” exponent=”3” offset=”0”/>
    <feFuncB type=”gamma” amplitude=”1” exponent=”3” offset=”0”/>
  </feComponentTransfer>
  <feComposite operator=”in” in2=”SourceAlpha”/>
  <feConvolveMatrix order=”3” kernelMatrix=”0.0625 0.0625 0.0625 0.0625 0.5 0.0625 0.0625 0.0625 0.0625” result=”foregroundDiff”/>
</filter>

We've added a few new building blocks: feTurbulence, feColorMatrix, feDiffuseLighting and feSpotLight. The exact details of all the parameters to these filters are a bit beyond this tutorial, but you'll have a good idea of how you can tweak effects.

Try taking this filter and applying it to this markup:

.bumps {
-webkit-filter: url(#bumps);
filter: url(#bumps);
}
<div class="bumps"> <h1>CHISELLED EFFECT</h1>
</div>

Creating a gold embossed look

To make a nice gold coloured version of our styled text with a nice 3D look, we use some more filter effects by use of the feComponentTransfer effect along with some more feComposite and feBlend effects.

The feBlend effect applies colour mixing modes that are used in a lot of desktop applications like Photoshop and Inkscape, which allow complex colour mixing effects to be used for all sorts of nice results. In the case of the gold filter we start by changing the fill colour of our original text to be gold using the CSS colour property. Then we apply feBlend using 'screen' and 'multiply' , which lets us combine the colours from each layer and multiply the colour values of the pixels in each of the filter input images. The code to generate the gold embossed look is available to download here.

Creating the drop shadow

Finally to give our styled text a really nice 3D look we can create a drop shadow using filter effects. To create the shadow we use feMorphology (which dilutes or erodes the input image), feGaussianBlur (which we used for the glow example), feOffset (which shifts an intermediate image around) and our trusty feComposite to put it all together again.

The filter effect code for the drop shadow can be downloaded here. Then we apply the result to our markup:

.bumps {
  -webkit-filter: url(#bumps); filter: url(#bumps);
}
<div class=”bumps”>
  <h1>CHISELLED EFFECT</h1>
</div>

What's great about filter effects is they're only limited by your imagination. Try all of the SVG filter effect building blocks and combine them in any way you like to create all sorts of filter chains that you can use through CSS.

Using CSS filters can make you stand out from the crowd with stunning, eye-catching visual effects to get your site noticed.

Words: Alex Danilo

This article originally appeared in net magazine issue 250.