Adobe

decor

Web Platform Team Blog

Making the web awesome

New blending features in CSS

A couple of months ago, we posted a blog post on bringing blending to the web. Since then, Nikos Andronikos from Canon and I have been busy integrating feedback in the draft spec and we presented it to the CSS working group in May.

At Google I/O Vincent Hardy also gave an overview of the capabilities. If you’re interested, you can watch it here. (The part on blending and compositing starts around 55min.) The WebKit build he is using is also publicly available so you can experiment with these features.

We’re still looking for feedback so let us know if you have any ideas to improve the spec or if you see features that we missed!

The blog post got some great feedback and resulted in a couple of new features that we incorporated into the spec. This post will go over these new features:

Blending Within the CSS Box

The first blog post only talked about blending between HTML elements. However, the CSS box model and the CSS3 background spec define a stack of content and sometimes you want to blend within this stack.

For instance, you might want to blend the color of a text element with its background image:

The CSS syntax would look like:

p {
 color: green;
 foreground-blend-mode: overlay;
 background: linear-gradient(to right, #00a9e0 0%,#323290 20%,
             #ea1688 40%, #eb2e2e 60%,#fde92e 80%,#009e54 100%);
}

‘foreground-blend-mode’ specifies the blending of the text or nested elements. To specify blending for background images, we introduced ‘background-blend-mode‘ which takes a list of blending modes. Each item in that list corresponds to a background image.

Blending of the Drop Shadow

Currently, CSS box shadows and text shadows are drawn on top of the background which is not always desired. Alpha can be used to work around this but it will make the drop shadow look washed out and produce artifacts. Most authoring applications give you the ability to blend the shadow because it produces a more pleasing effect.

For instance, this is a green drop shadow with 75% opacity:

If we remove the opacity and apply a ‘multiply’ blend mode, we get the following result:

Notice how the color of the shadow changes depending on the background. In the opacity case, the border of the green shadow gets a bit darker. This side effect is gone as well.

The CSS syntax would look like:

p {
    text-shadow: green 20px 54px;
    text-shadow-blend-mode: multiply;
}

Adding Blending to Canvas

Up until the last blog post, we were only thinking of adding blending features to CSS. Someone replied that we should make it part of canvas as well which sounded like a great idea.

As you might know, canvas already supports the compositing operators but not blending. If people want to get blending behavior today, they have to either do it manually which is slow and uses a lot of memory, or use prerendered bitmaps which is not as flexible.

We proposed two different solutions:

  • Extend ‘globalCompositeOperation’ with blending keywords
  • Introduce a new keyword ‘globalBlendOperation’ that sets the current blend mode

The proposal to extend the ‘globalCompositeOperation’ will most likely be accepted since it is powerful enough and easy to implement.

We looked at the architecture of WebKit and Mozilla to see how difficult it would be to implement this. It turns out that they already have all the code in place so we were able to create a prototype in a couple of hours. (Unfortunately, those builds are not available publicly yet.)

For instance, to get the effect of a ‘screen’ blend mode between two intersecting circles: 

you would write the following code:

var ctx = $("#canvas")[0].getContext("2d");
ctx.fillStyle = "#FF0000";
ctx.beginPath();
ctx.arc(75, 75, 50, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();
ctx.globalCompositeOperation = 'screen';
ctx.fillStyle = "#00FF00";
ctx.beginPath();
ctx.arc(125, 75, 50, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();

What is Next for the Blending Specification?

Once Nikos and I incorporate all the feedback, we are going to request to progress the spec to “working draft” which will cause more scrutiny on all the features we’re introducing. Fortunately, blending and compositing do not cause content reflow which makes it a lot less controversial.

While we push the spec forward, we will also work on integrating this feature into several browsers so you can start using it.

Let us know what you think!

17 Comments

  1. July 18, 2012 at 1:11 am, Matt Wilcox said:

    This is very cool. I’ve thought about this before and I’ve thought that we need blending control *as an extension to the colour mode* – because we want blending control everywhere we declare colour or paint (like images).

    I’d like a syntax like this:

    p {
    color: red overlay; // text node
    text-shadow: 1px 1px 3px rgba(0,0,0,0.5) multiply;
    background: url(image.png) multiply, url(image2.png) screen;
    }

    The other issue with CSS like this is a complete inability to delve into the stack to change one specific property. Instead we have to keep re-defining the entire stack. That’s very impractical.

    • July 18, 2012 at 8:32 am, Rik Cabanier said:

      I agree that that looks a lot nicer. My fear is that there will be push-back since it changes existing properties that are in different W3C specs.
      The discussion will start in earnest when we go to “working draft”. If there is enough support, I’d be happy to change the spec.

      • August 08, 2012 at 1:40 am, Matt Wilcox said:

        I would love to see that spec changed to match something like this.

        Unfortunately, I’m aware of how the politics of the W3C (and complexity of simple-seeming ideas) has a way of trumping practicality for authors a lot of the time.

    • February 03, 2013 at 10:46 pm, Ranjan Pathak said:

      I too completely agree with what you said, It should actually be like this.. Nothing like writing a long code Instead clean small codes.

  2. July 18, 2012 at 1:15 am, Matt Wilcox said:

    I can’t stress this enough: blending modes are most logical as an extension of the colour or background model. Doing that means we don’t have to declare countless things like text-shadow-blend-mode or border-blend-mode or shadow-blend-mode.

    Just extend colour and wherever colour works so do blend modes. Much more understandable and intuitive.

    • July 18, 2012 at 9:15 am, jon mills said:

      right on. the less declarations we developers have to write, the better.

      • July 18, 2012 at 8:04 pm, june said:

        Especially when it comes to redefining attributes to change a value on :hover

  3. July 18, 2012 at 9:09 am, BrianMB said:

    I fully agree with Matt.

    If that is too difficult to push, I suggest that blending-mode should work like CSS Transitions. You define the CSS to blend along with the blend mode. Like so:

    blending-mode: color multiply;

    This would blend the text against layers behind it. The default value for this would be “all.”

    Whatever the solution ends up being, properties like text-shadow-blending-mode are crazy town.

    • July 18, 2012 at 9:22 am, Rik Cabanier said:

      section 7.3.6 in https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html is similar to your proposal.
      It’s true that a 25 letter css keyword like ‘text-shadow-blending-mode’ is inconvenient but the CSS working groups prefers keywords that are descriptive. (Just look at all the ‘animation-xxx’ keywords…)

      • July 24, 2012 at 10:22 am, BrianMB said:

        I have to clarify that it isn’t about convenience (my suggestion doesn’t actually require much less writing, if any). We have tooling to make writing verbose code (e.g. vendor prefixes) simpler.

        In CSS, we have really cool conventions that work well already. Transitions are terrifically designed. RGBa (analogous to Matt’s suggestion) is also great. Extending these paradigms to new features is a good idea.

  4. July 18, 2012 at 7:53 pm, june said:

    Is there a way to adjust the opacity of multiple background images?

    • July 18, 2012 at 8:00 pm, Rik Cabanier said:

      There doesn’t seem to be a way to do this currently. I found a message on www-style from Tab Atkins:

      the most recent discussion of this started at http://lists.w3.org/Archives/Public/www-style/2011Sep/0033.html.
      In particular, read my response at http://lists.w3.org/Archives/Public/www-style/2011Sep/0035.html, as it respresents our current thinking on the matter.

      So people are definitely thinking about adding it.
      For now opacity can come from the content like a png with an alpha channel or a CSS gradient

      • July 18, 2012 at 8:08 pm, june said:

        But what if I want to have a background texture change to another image with a fade transition.

        I could use multiple html elements positioned over each other and adjust the opacity of 1 on :hover.

        OR I could just have 2 background images on 1 element and change the opacity of 1 of them on :hover.
        I think most would prefer the 2nd option.

        • July 19, 2012 at 9:20 am, Rik Cabanier said:

          You should bring up that use case on www-style.
          If enough people ask for this feature, it will become part of the spec.

    • July 24, 2012 at 10:38 am, BrianMB said:

      June:

      cross-fade probably can satisfy this use-case in a reasonably programmatic fashion:

      http://peter.sh/files/examples/cross-fading.html

      Not as cool as simply setting opacity on each background layer, but it’s close.

  5. July 23, 2012 at 5:13 am, Tweet-Parade (no.29 July 2012) | gonzoblog.nl said:

    […] New blending features in CSS – The first blog post only talked about blending between HTML elements. However, the CSS box model and the CSS3 background spec define a stack of content and sometimes you want to blend within this stack. […]

  6. August 27, 2012 at 7:17 am, Firefox/Gecko Delivery Planning: 2012-07-18 | meetingnotes9274 said:

    […] made an interesting blog post about some of the CSS blending features they are working on. WebKit builds with the features are now available as […]