SVG Blend Modes With The feBlend Filter Primitive

You’ve probably used an image editor to combine two images together using one of the different blend modes available in your editor of choice to create some very interesting images. Did you know SVG has a filter that lets you do the same thing?

I’ve been talking about the details of SVG filters primitives as part of a larger series about SVG filter effects. I began with an overview of SVG filters and then walked through the filter element before talking about filter primitives and their input and output. Since then I’ve covered a few simple filter primitives, some for working with external images, and the last few weeks I’ve talked about how you can combine the results of multiple primitives into a single graphic for display using either feMerge or feComposite.

Today I want to continue with one more primitive that can combine the results of other primitives. I want to talk about feBlend, which lets you blend two images just like your favorite image editor.

Note: Firefox doesn’t support svg fragments inside an feImage filter primitive, which means the examples in this post won’t work in Firefox. I’ll see if I can come up with another way to show the examples, but until then you’ll need to view this post in another browser. Sorry for any inconvenience.

The feBlend Filter Primitive

The feBlend filter primitive is similar to feComposite in that it takes two images or SVG fragments and composites them into a single graphic. Unlike feComposite, feBlend uses blend modes that you would commonly find in image editing software, though it doesn’t offer quite as many blend modes.

Like feComposite, it requires an in and in2 value that set the graphics to be combined, but instead of an operator you set a mode that determines how the images will be blended together. There are five possible values of mode or five possible blend modes when using feBlend.

mode = normal | multiply | screen | darken | lighten

You might already know what each of these blend modes does, but here’s a brief definition in case you don’t.

  • normal—The same as setting operator=“over” using feComposite where in2 sits on top of in.
  • multiply —The resulting value is the product of the in and in2 value, which weakens light colors.
  • screen —Adds the color values together, then subtracts their product, which strengthens light colors more than dark colors.
  • darken —Displays the minimum of in and in2, which is the darker color.
  • lighten—Displays the maximum of in and in2, which is the lighter color.

You use feBlend the same way use feComposite, though please note that for blending in2 is the image on top and in is the image on the bottom.

<feBlend mode="normal" in="A" in2="B" />

Here’s an example so you can see how feBlend works in practice. I created a rectangle inside <defs> and set its dimensions to be 100% of the viewport in both the x and y directions. I filled the rectangle with a shade of purple.

Next I referenced the rectangle inside an feImage primitive and I referenced an external image inside another feImage filter primitive.

I set feBlend to mode=“normal” and have the rectangle as the value for in and the image as the value of in2. Finally I referenced the filter in an empty group, <g>, which exists only for the reference as everything for display is inside the filter.

<svg width="100%" height="495px" style="outline: 1px solid red">
   <rect id="overlay" width="100%" height="100%" fill="#939" />
   <filter id="blend" x="0" y="0" width="100%" height="100%">
     <feImage xlink:href="#overlay" result="rectangle" />
     <feImage xlink:href="" width="100%" height="100%" result="strawberry" />
     <feBlend mode="normal" in="rectangle" in2="strawberry" />
 <g filter="url(#blend)"></g>

Here’s the result. The “in” image, in this case a purple rectangle sits on top of the “in2” image, which is my photograph of Strawberry Fields in Central Park.

That isn’t the most interesting result as the purple rectangle completely obscures the image. Here’s how the example looks with a single change to mode=“multiply” and everything else exactly the same. A little dark perhaps, but definitely more interesting.

Here’s the result with mode set to screen.

With mode set to darken.

And finally with mode set to lighten, which is my favorite using the purple rectangle and this particular image.

Which mode works best will depend a lot on the specifics of what your trying to blend, but hopefully the example and the results from using the different blend modes will give you an idea how the feBlend primitive works.

Blending an Image with a Gradient

I chose to use blend an image with a rectangle filled with color in order to keep the example simple, but you aren’t limited to simple color fills.

Here’s another example. I’m using the same Strawberry Fields image, but this time instead of filling the rectangle with purple, I filled it with a linear gradient that transitions from red to green to blue.

<svg width="100%" height="495px" style="outline: 1px solid red">
   <linearGradient id="linear">
     <stop offset="0" stop-color="#ff0000" />
     <stop offset="0.33" stop-color="#00ff00"/>
     <stop offset="0.67" stop-color="#0000ff"/>
     <stop offset="1" stop-color="#ff0000" />
   <rect id="overlay-linear" width="100%" height="100%" fill="url(#linear)" />
   <filter id="blend" x="0" y="0" width="100%" height="100%">
     <feImage xlink:href="#overlay-linear" result="rectangle" />
     <feImage xlink:href="" width="100%" height="100%" result="strawberry" />
     <feBlend mode="multiply" in="rectangle" in2="strawberry" />
<g filter="url(#blend)"></g>

Here’s the result using mode=“multiply” which is the mode I thought looked best for this example.

Blending Two Images

You’re also not limited to blending an image with a rectangle no matter what’s filled with. Here’s an example blending two images. One is the same image of Strawberry Fields I’ve used throughout this series and the other is an image of a vase and shallow bowl I took at the Museum of Natural History in New York.

Instead of creating a rectangle and using it in one of the feImage primitives, here both feImage primitives point to external images. I experimented with different blend modes and settled on darken for these two images.

<svg width="100%" height="495px" style="outline: 1px solid red">
   <filter id="blend" x="0" y="0" width="100%" height="100%">
     <feImage xlink:href="" result="rectangle" />
     <feImage xlink:href="" width="100%" height="100%" result="strawberry" />
     <feBlend mode="darken" in="rectangle" in2="strawberry" />
 <g filter="url(#blend)"></g>

Here’s the result, which adds a vase to the Strawberry Fields memorial. The dark ellipse to the left of the vase is the opening of the bowl. The entire image has a yellowish/brownish cast to it, which comes from the background behind the vase and bowl. The darker strip across the bottom was the shelf both were sitting on.

Closing Thoughts

The feBlend filter primitives is another that’s limited to two inputs, but it does offer more interesting possibilities for how the images are combined than the feMerge and feComposite primitives we saw the last couple of weeks. All three have their place and which you use will depend on what effect you want to achieve.

There are still a number of filter primitives to cover, but it will take a couple more months to get through them and I thought it best to break up the series as we head into the holiday season. I have a short series about ideas and inspiration coming in a couple of weeks, then I’ll do my usual goal setting and review posts to close out 2016 and begin 2017. I’ll get back to SVG filter primitives in January.

« »

Download a free sample from my book, Design Fundamentals.


    • Thanks Geert. I’m guessing you’re using Firefox. I discovered that Firefox doesn’t support one thing I did in the examples. I added a note at the top of the post to let people know. I’ll have to come up with a different way to code the examples, but until then you can see the resulting SVGs in a different browser. Sorry about that.

  1. Great article, this really helps me a lot as a newbie in this industry working in a professional website development company.

Leave a Reply

Your email address will not be published. Required fields are marked *