-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[css-compositing-2] Add plus-lighter to mix-blend-mode and background-blend-mode #444
Conversation
I'm going to try and write some tests for this, but I haven't written CSS tests before. Wish me luck! |
@tabatkins are the tests in the right format for this? The other tests look like ref tests, but maybe there's a more modern way? |
#446 - wondering if |
The more I think about it, moving @cabanier maybe you have thoughts here? Right now Should the spec change be limited to what Chrome's currently prepared to implement, or converge with |
Yes, don't make it into a blend mode. It doesn't solve the issue with clamping.
The plan (from 8 years ago?) was to make another css property for compositing but that never happened.
Is Chrome looking into implementing cross-fade in css? |
The purpose of this PR is to allow developers to make an element composite using
Yeah, some combinations of blend & composite don't seem to make much sense.
Not I've updated the PR to use 'lighter' rather than 'plus-lighter'. |
If the intent is for cross-fading, making lighter a compositing mode won't work because it won't behave as expected when there's foreground or background alpha. |
Are you sure? I think |
Maybe it does the right thing. The alpha of the backdrop determines how much of the blend operation is applied. It's possible that this ends up doing what is expected. |
I think it does. It's what Chrome uses for |
Maybe... That code is setting a "blend mode" which is really a compositing mode. |
@cabanier I'm a bit confused about how blend-mode vs compositing-mode are supposed to be different. There are existing blend modes which define how the source and backdrop color values should be combined (the blending step) and then how this combined result is modulated by the backdrop alpha (the compositing step). For example, the lighten blend-mode states something similar to what we want to do with lighter, the backdrop is replaced with the result of blending the 2 color values instead of any further compositing operation. Is that not a valid way to specify a mix-blend-mode? |
A blend mode changes the color of the foreground color based on the blending formula and the alpha of the backdrop. |
That's the part I'm unsure about. The text for lighten says, "The backdrop is replaced with the source where the source is lighter". Are we doing source over compositing as defined below : co = αs x Cs + αb x Cb x (1 – αs), where Cs = max(Cs, Cb) via the blending operation |
The spec has a step by step explanation how blending is done: https://drafts.fxtf.org/compositing-1/#blending |
Thank you. This makes it much clearer now. You're right that what we want here is "lighter" composite operator with "normal" blend mode. And there is currently no way to change the composite operator in CSS. Would it be reasonable to include composite operators in mix-blend-mode and follow a pattern similar to globalCompositeOperation. The latter lets you specify a blend mode (in which case we default to source-over compositing) or composite operator (in which case we default to normal blending) : https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/graphics/graphics_types.cc;l=56;drc=d7044ac79851029fa1698731d9ce5c251a5939be We can have mix-blend-mode provide the same capability as globalCompositeOperation in CSS. It's unclear why a developer shouldn't be able to specify any combination of the 2 but the syntax could be extended to permit that for both mix-blend-mode and globalCompositeOperation going forward. |
I'm unsure. At the time, it seemed to me that these compositing modes were too primitive to expose directly which is why we punted them to later. |
Hmmm, I didn't follow the alternate being proposed. Could you clarify how developers should do this instead of being able to configure the compositing of 2 elements? A demo showing the exact use-case is here. It's using canvas to mimic the capability needed in CSS. We have 2 elements with partially identical pixels that draw on top of each other and we need to ensure that blending the identical pixels is a no-op. |
This PR is ready to land. It's unclear if @cabanier what are the next steps? |
It should be simple enough to create this as an experiment in a version of chromium that you built yourself. If the elements can be blended by regular drawing (and not by the compositor), you just need to add it to skia. You could even just replace a blend mode with I'm still unsure if the compositing mode will always work in the way you expect. Also, blending creates a stacking context out of the content that is blending but not the content that you are blending with. This could cause some confusion for authors. |
OK then. Not sure why you need my input if it's set in stone. |
Not set in stone, but you're the editor so we need your code review to land the PR. If there is a specific testcase you have in mind that we should check in the prototype, or a WPT example to add, we're happy to do that. If your concern is a general one about fit for our desired use cases, that's legit but IMO the best way to find that out is by testing with partners later on, not blocking the a PR for an initial spec if we don't know why it is problematic... |
I agree. |
Yep, if I take a nightly from https://download-chromium.appspot.com/ and use the |
Furthermore, the layout effects of causing a stacking context are not a problem for the desired use cases. Rik, why do you think more author feedback is needed for that case? |
The stated use case for this feature was: |
The example here is such a case: https://jakearchibald.com/2021/dom-cross-fade/#update-it-already-works-in-safari. It has two sibling SVG elements with mix-blend-mode: plus-lighter and a containing element with The CSS to do this is not a lot - just the one containing div and 3 lines of CSS. |
I was thinking of an HTML example. Couldn't you could already do this in SVG with |
What we need is a method that works for all kinds of HTML content, including in particular for replaced elements containing snapshot images from a current or previous document. I don't think SVG is general enough to cover all such cases. |
@cabanier I only used SVG in that example because the scaling worked well for the article. I can make a demo using DOM elements if I really need to, but SVG elements are also DOM elements so that demo does the job IMO |
@jakearchibald Yes, please make an example with HTML elements to see how most people are going to use this feature. |
With CSS Grid you can line up "stacked" elements very easily. In this example, all direct child elements of .wrapper { display: grid; }
.wrapper > * { grid-area: 1 / 1 / 2 / 2; } |
Yep! That's the pattern I recommended in https://youtu.be/PYSOnC2CrD8 too |
@cabanier https://static-misc-3.glitch.me/composite-test/mix-blend-mode-dom.html - here's a demo using only DOM elements. Of course, the cross-fade is likely to be an animation triggered by a click, but the slider used on this page makes it easier to see the difference between the default compositing method (source-over) and Summary of material relating to this:
|
Nice! I didn't know you could do it with grid :-) |
@cabanier is this good to land then? Anything else I need to do? |
This looks good! |
I'm not sure what you mean by 'timing', can you explain a bit? |
After we shipped this feature with blend modes that weren't susceptible to timing, someone on the skia team refactored the formulas which enabled an attack. See https://arstechnica.com/information-technology/2018/05/chrome-and-firefox-leaks-let-sites-steal-visitors-facebook-names-profile-pics/ |
Gotcha. We'll double check that. That shouldn't block the spec landing though, right? It's an implementation detail. |
Yes, the spec already specifies this but it's easily overlooked. |
Can the spec and tests land now, then? |
Yes :-) |
Thanks for reviewing and landing this! |
Fixes https://github.com/w3c/csswg-drafts/issues/6821.
Tests web-platform-tests/wpt#31757.
This allows any two elements to be cross-faded together. More details: https://jakearchibald.com/2021/dom-cross-fade/.
I'm not really sure about the difference between "blend" and "composite", particularly since
globalCompositeOperation
in canvas includes both.We might eventually get to the stage where
mix-blend-mode
andglobalCompositeOperation
have the same set of operations, which is kinda weird since they have different names.