Blending coming to an SVG renderer near you! (Including Inkscape)

SVG has supported a limited set of blend modes through the use of SVG filters. Now SVG (and HTML) are getting a full set of blend modes that can be directly applied to all graphical objects. Chrome already has some support for the new blending method.

Here is a snippet of SVG from the specification CSS Blending and Compositing Level 1:

<svg>
  <rect width="120" height="120" fill="black"/>
  <circle cx="40" cy="40" r="40" fill="red"/>
  <circle cx="80" cy="40" r="40" fill="lime"/>
  <circle cx="60" cy="80" r="40" fill="blue"/>
</svg>

Normally, SVG uses the painter’s model where each element is painted on top of the previous. So the above SVG gets rendered as (actual inline SVG):

Inlined SVG. Circles drawn using painter’s model.

With CSS blending, one can specify how the blending between the elements is done by setting the ‘mix-blend-mode’ property. The following style rule:

circle { mix-blend-mode: screen; }

yields the following figure:

Inlined SVG. Circles blended with ‘mix-blend-mode’ = ‘screen’.

which in a browser (recent Chrome) that supports CSS blending should look like this:

Red, lime, and blue overlapping circles, blended with 'screen' mode.

PNG.

Why the black background? If the background was white, the circles would not be visible. This is because the circles blend not only with each other but also with the background. (With the ‘screen’ blending mode, any color blended with a white background results in white.) To stop blending with the background, one can use the ‘isolation’ property. By wrapping the three circles in a group and setting the ‘isolation’ property to ‘isolate’, the three circles are first blended onto a transparent, black background and then the resulting image is painted normally. The code looks like this:

<svg>
  <g>
    <circle cx="40" cy="40" r="40" fill="red"/>
    <circle cx="80" cy="40" r="40" fill="lime"/>
    <circle cx="60" cy="80" r="40" fill="blue"/>
  </g>
</svg>

and the CSS:

circle { mix-blend-mode: screen; }
g { isolation: isolate; }

The resulting image should look like this:

Red, green, and blue overlapping circles, blended with 'screen' mode.

PNG.

I wasn’t able to get the ‘isolation’ property to work with Chrome (which should support it), thus I used a PNG in the above figure.

At the SVG Working Group meeting last week, the group approved moving the CSS Compositing and Blending Level 1 to a Candidate Recommendation. Since this a joint specification, the CSS Working group must also give their approval. A Candidate Recommendation is the last step before becoming a Recommendation (i.e. an official W3C specification). During this last step two things must happen. First a comprehensive test suite must be written and second at least two different implementations must pass the tests for each feature in the specification. This latter requirement ensures that the specification is clear enough that it can be implemented (and also demonstrates there is a real interest in the specification).

Chrome already implements the specification so just one more implementation is needed. It is expected that Firefox will soon support the specification. There is also a test plan that includes SVG tests. So we are well on the way to getting this through the last step.

In addition, I’ve also just added support for CSS Blending to Inscape trunk. For the moment, a compile time flag must be set to enable the support. There is no GUI (other than the XML editor) and there is still a bit of work to be done (the Inkscape canvas background needs to be isolated from the drawing and I’ve seen a bug when part of the drawing is cached.

The CSS Compositing and Blending Level 1 specification also include a full set of Porter-Duff compositing operators. For the moment, they only apply to Canvas. It was intended that they apply to HTML and SVG but the rendering models used by browsers cannot yet accomodate them. They will be included in the next version of the specification, CSS Compositing and Blending Level 2. The SVG working group approved the start on the next level at the last meeting.

Blending and compositing has been included in SVG filters from the beginning. However, only a limited set of blending modes and compositing operators are available in SVG filters. Unfortunately, CSS Filters Level 1 has not extended filters to include the new blending modes and compositing operators despite being trivial to implement once the original set has been implemented (it took me all of an hour to add them to Inkscape trunk). Again the motivation is to speed up approval of the level 1 specification; level 2 will include them. Work on level 2 is expected to begin early next year.

If you are interested in playing with then new blending modes and compositing modes in Inkscape, check out Inkscape trunk and set the flags WITH_CSSBLEND and/or WITH_CSSCOMPOSITE (see the file configure.ac). As mentioned above, there is no GUI for the new non-filter based blending modes. The new blending modes and compositing operators for filters are available through the Filters dialog.

You can also have a look at my Blending Test Page.

This entry was posted in CSS, Inkscape, SVG and tagged , . Bookmark the permalink.

6 Responses to Blending coming to an SVG renderer near you! (Including Inkscape)

  1. Alex says:

    Firefox already supports mix-blend-mode/background-blend-mode/isolation, but it’s disabled by default currently due to some bugs (Including one I just found on this page)

  2. Tavmjong Bah says:

    Alex, that’s good news (the support, not the bugs!). How can I enable support?

  3. Alex says:

    In about:config you can flick the preference “layout.css.mix-blend-mode.enabled” to true and that will enable the support. I think support made it into 28, but I’m not sure (I know background-blend-mode is enabled by default in the 29 nightly)

    • Rik says:

      Our big to-do is to implement blending for accelerated compositing.
      Right now, we turn off all the optimizations that Firefox does to speed up drawing so blending is sometimes slow.
      We’re also still tackling some pesky bugs on Chrome Canary but those might not show up for SVG content.
      I think support for SVG blending in wekbit nightly is coming up soon too.

  4. Alex says:

    And another issue I just noticed (Probably why this is still disabled), Firefox doesn’t support isolation, but instead seems to imply it from embedding the elements within a element.

    i.e. child elements of are blended directly onto the surface behind them, child elements of a are rendered onto their own surface and then composited.

  5. Rik says:

    yes, Firefox doesn’t support isolation yet. Hopefully we’ll have time to add that in the next couple of months. Meanwhile, you could emulate it using opacity= .99

    What bug did you find?