Skip to content
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-color-adjust] Clarify expectations re forced-color mode, system colors, and transitions #5419

Closed
AmeliaBR opened this issue Aug 11, 2020 · 14 comments

Comments

@AmeliaBR
Copy link
Contributor

In #5342 we agreed that the forced-color-adjust property should not be animatable, as it has too many side effects on the computed values of other properties.

But since forced color mode and forced-color-adjust do have effects on other properties, it should be clarified how those changes should impact transitions on those other properties.

Per spec, transitions apply to changes in the computed value. That means, for example, that if a property is set to currentcolor, it will not transition if the color property is changed (although if the color property is transitioned itself, that will flow through to the second property). I've confirmed that both Chromium and Firefox behave this way.

As browsers switch to treating the system color keywords as inheritable computed values, I would expect the same behavior — meaning, if a property is set to a system color, and the used values of the system colors change because of forced color mode being turned on, there would be no expectation of a transition.

However, if the property initially had a regular color value, and forced color mode triggered the various revert rules to switch to system colors, that would be a change in computed value which would normally trigger transitions. As Rossen noted on the call, “turning on forced color mode” is often an OS-level reset operation, so implementing it as a CSS transition would be difficult. (Also, we don't currently have a syntax for describing the interpolation between two colors when one of them is a system color keyword — it would require the CSS Colors 5 color-mix function.)

Then there is the case that I brought up on the call: what if the author turns forced-color-adjust on or off on a particular sub-tree? E.g., maybe while text is being edited, it uses the forced colors, but when it loses focus some special syntax highlighting kicks in. Or a “pressed” state of a button requires forced-color overrides, but the normal button state uses the forced system button colors. Again, these are changes in the computed value of the color properties, which would normally trigger transitions.

Turning forced colors on/off is a rare event, and controlled by the user, so maybe it's best to treat it as a complete reset, just to make sure it's done cleanly. But in the case of toggling forced-color-adjust, the changes are controlled by the author, who will presumably be testing the change.

I don't think it's an important use case to be able to transition these changes, so it really comes down to which behavior is simpler / most consistent from an implementation perspective — which is worse, not transitioning on changes in computed value, or needing to handle the special cases for things like background color, where the computed value isn't cleanly defined in forced color mode?

The most important thing, IMO, is that there is consistent behavior cross-browser, so that we don't end up with authors relying on behavior from one browser that is difficult to implement elsewhere.

@AmeliaBR AmeliaBR added css-transitions-1 Current Work css-color-adjust-1 Current Work labels Aug 11, 2020
@tabatkins
Copy link
Member

I agree that it's both important to specify this, and that it's not very important which way we decide, from an authoring perspective.

@alisonmaher @andruud What's easier implementation-wise? Figuring out the forced colors, then triggering transitions as necessary? Or having the forced colors not trigger transitions at all (either thru an explicit "forced colors aren't animatable" or by having forced colors happen "after" transitions check for triggers).

forced color mode triggered the various revert rules to switch to system colors,

And note that, as of a few days ago, we're no longer specifying forced-color adjustment as being done via revert, but rather just as an adjustment of the colors.

@alisonmaher
Copy link
Collaborator

alisonmaher commented Aug 21, 2020

This is a good question. I think having forced colors not trigger transitions would be easier to implement or at least may be the simpler approach.

@andruud
Copy link
Member

andruud commented Aug 24, 2020

having forced colors happen "after" transitions check for triggers

Hmm, I think we need to clarify something. There are two (or more) ways of thinking about when/how forced colors "happen":

A) The computed value is produced (and held as the computed value). Then at some point later the computed value is adjusted ("in place") to something else. This means there's effectively two different computed values, and we can choose whether to check for transition triggers before or after the adjustment.

or

B) We predict what the computed value would be had forced colors mode not been enabled ("the original value"), then
either accept that as the computed value (if it's a system color etc), or pick some other value as the computed value. In this case there is only one computed value, and the transition-trigger-check only has one value to choose from.

I think (B) is a better choice (@tabatkins: WDYT?), as having multiple versions of "the computed value" is confusing. So if we want to block transitions from happening, we'd need to do so explicitly.

In Blink, it will actually be more work to not transition the properties, but Rossen's argument makes sense (there might be an OS level reset outside Blink's control), so preventing transitions would probably be simpler overall.

@tabatkins
Copy link
Member

Yeah, (a) is basically inserting another value stage between "computed" and "used" just for this. It works, but it's maybe a bit overkill. ^_^

I'm fine with (b); I'm guessing the wording would be that transitions can't start if the start or end values come from forcing (even if the value would have been the same with or without forcing, like if the author is already using system colors).

@andruud
Copy link
Member

andruud commented Aug 24, 2020

Yeah, that sounds good. We should consider any value that passes through the force process as "forced", even if it's a "pass through unmodified" for some values.

@alisonmaher
Copy link
Collaborator

I was chatting with Rossen around this one and wanted to add on a bit more based on the discussion. Let's say that we have the following case:

<div id="parent" style="background: black;">
  <div id="child " style="background: black; transition: 3s;"></div>
</div>

And let's also say that when we change the background-color on the parent, we also update the child's background-color to match, triggering a transition.

Given approach (B), we can have the following cases in Forced Colors Mode:

  1. If forced-color-adjust is auto, and we change the parent's background-color to white, we wouldn't trigger a transition on the child because the background remains the same color.
  2. If forced-color-adjust is set to none on the parent, and we change the parent's background-color to white, we would update the child's background-color to white as a result, triggering a transition.
  3. If case 1 happens again, and then we change the value of forced-color-adjust to none on the parent, should we trigger a transition on the child in this case or not?

I do see the value of the current proposal given case 2. However, considering case 3, perhaps the simplest and most consistent behavior here would be to not trigger transitions at all in Forced Colors Mode.

@tabatkins
Copy link
Member

Hm, I'm not 100% sure I understand the case you're laying out here. In each case, when is the child changing its background-color? I also don't understand the relevance of the parent in any of the cases, since it doesn't have a transition anyway, and there's no significant inheritance going on here.

@alisonmaher
Copy link
Collaborator

Yeah sorry, I could've made this clearer. It was a hypothetical in which in script, whenever the parent's background changed, we would update the child's background to match. In each of the three cases above, we were updating the parent's background color and determining if we should trigger a transition on the child (given the child would be updated to match).

But I guess this could just be simplified to:

<div style="background: black; transition: 3s;"></div>

  1. If forced-color-adjust is auto, and we change the background-color to white, we wouldn't trigger a transition because the background remains the same color.
  2. If forced-color-adjust is set to none, and we change the background-color to white, we would trigger a transition.
  3. If case 1 happens again, and then we change the value of forced-color-adjust to none, should we trigger a transition or not?

After simplifying, I suppose the third case isn't that ambiguous after all given the current proposal. It sounds like in this case, if we change the value of forced-color-adjust from auto to none after the color was set to white, we wouldn't trigger a transition since at that point, the color would be updating from a forced value to a non-forced value.

Given this, the current proposal makes more sense to me now, so I'd be on board with that approach.

@tabatkins
Copy link
Member

Yup, you got it exactly.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-color-adjust] Clarify expectations re forced-color mode, system colors, and transitions, and agreed to the following:

  • RESOLVED: colors assigned due to forced-colors mode are not interpolatable
The full IRC log of that discussion <dael> Topic: [css-color-adjust] Clarify expectations re forced-color mode, system colors, and transitions
<dael> github: https://github.com//issues/5419
<dael> Rossen_: I know AmeliaBR sent regrets. Seems consensus on issue. alisonmaher can you summerize?
<dael> alisonmaher: General issues are specifically when you change forced-color-adjust to aut or none do we trigger transition. If to or from are forced we would not trigger transitions is the proposal
<fremy> sounds like the right call to me
<emilio> q+
<dael> TabAtkins: Simplifies impl and happy to have in spec
<dael> Rossen_: Also support. Makes behavior predictable
<AmeliaBR> no need to wait for me: my opinion was “please pick what works best for implementations & spec it!”
<dael> emilio: Other than display is the precedent for such a thing?
<dael> TabAtkins: There's a couple of non-interpolatable properties. Some have values that cannot be interpolated though others can.
<dael> emilio: This is different. This isn't about interpolable but about if triggers transitions on other arbitrary properties
<dael> TabAtkins: Yes. If the stuff is forced or not controls if other properties can interp certain values. That is novel. Seems easier on out impl to handle it.
<dael> emilio: Why?
<dael> TabAtkins: Don't know. Rune would have more details
<dael> emilio: To me seems it would make; this would need to be a special case
<dael> Rossen_: Impl aside from user or author PoV which behavior would you prefer
<fremy> q+
<dael> emilio: If author has spec BG transitions I don't see why it shouldn't?
<dael> Rossen_: How if in middle of transition you go to or from forced colors. You're going off a cliff for expected. But continuing to transition means some thigns change. These are dissonant to me.
<dael> emilio: To make sure I understand saying that changing forced-color adjust stops in progress particular property values?
<dael> TabAtkins: Not quite. Any colors comping from forced color mode don't interpolate. In general it's forced vs not and that's outside the property.
<dael> emilio: Agree with Rossen_ similar that stopping transition when element stops making boxes makes sense it does make sense when you change to stop animations and transitions. I need to look deeper into implications.
<dael> Rossen_: We do have a resolution on animations
<dael> fremy: An example of why don't want to transition colors. When in forced-colors the backplate is on top of text. Will disappear when set to none. Previous text color contrasts backplate so you don't want text color to transition because it's a completely different background. Text could disappear for a few seconds. I think stopping transitions makes the most sense
<dael> emilio: Could make argument with a bunch of different property combos, right? Not just forced-colors.
<dael> Rossen_: Is this something you want to object emilio, discuss more?
<dael> emilio: colors from forced-colors and colors don't interpolate?
<dael> TabAtkins: Prop: Colors assigned due to forced-colors mode are not interpolable
<dael> emilio: I won't object. I need to look more
<dael> emilio: When you revert a property and it goes to color from UA sheet I assume that counts as assigned b/c forced color mode?
<dael> emilio: You have forced colors. That can cause you to revert some properties to UA level. If you use a color; it's not just default colors you assign but also the ones you get when revert to a value from UA stylesheet. They shouldn't interp. But same as if author spec revert
<dael> TabAtkins: Should have been from set of forced system colors so yes
<dael> emilio: I don't know. Feels awkward resolution. I would be curious about constraints that simplify this in Chrome
<dael> emilio: I won't object
<dael> Rossen_: If you have a better proposal and want to re-open please do
<dael> Rossen_: Let's make progress now
<dael> Rossen_: Objections to colors assigned due to forced-colors mode are not interpolable
<TabAtkins> https://github.com//issues/5419#issue-677260327 lays out some initial thoughts, from Amelia, and subsequent comments from Alison and Rune
<dael> RESOLVED: colors assigned due to forced-colors mode are not interpolatable
<Rossen_> q?
<Rossen_> ack emilio
<Rossen_> ack fremy

@emilio
Copy link
Collaborator

emilio commented Sep 30, 2020

Curious @andruud, what are the implementation issues that make this proposal simpler in Chromium? I think that this would be somewhat awkward to implement in Gecko (but I'd have to try).

@andruud
Copy link
Member

andruud commented Sep 30, 2020

@emilio It's not clear whether this makes anything simpler really. Transitioning on computed values changes is the default behavior, so we'll need to take extra steps to prevent that from happening. But I think not transitioning is a "safe" choice, since you avoid any potential problems re. "OS level reset" mentioned by Rossen. (I've not investigated whether "OS level reset" is a real problem).

@tabatkins
Copy link
Member

tabatkins commented Sep 30, 2020

@fantasai just re-raised the question of making forcing colors at used value time instead of computed value time in #4915.

If I change the spec to specifically affect the used value of the color, this whole question becomes moot anyway - transitions might happen underneath the hood (and since that's detectable via Web Animations API, we should still be clear whether or not it happens), but the end-result for the user is a system color and zero transitions.

(If transitions do still happen, that's probably a better result for the background-color, which takes its color from the system color but its alpha from the author's background-color. This would allow backgrounds to still fade in/out.)

@tabatkins
Copy link
Member

Fixed in 806c43e; it's now clear that the forced-color adjustment happens at used-value time, and so it (a) has no effect on transitions, and (b) will usually make the transition irrelevant anyway (even if you're transitioning between two system colors, the intermediate color won't be a system color, so the transition won't have a visible effect while it's running).

This also means that background-color will visibly transition its alpha even in forced-colors mode.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants