Skip to content

[css-transforms-2] Is it necessary to serialize all 3 components of translate given the 3rd component is 0px #3305

Open

Description

@BorisChiou

Just a follow-up question of this issue. The new update of serialization of translate [1]:

  • If a 2d translation is specified, the property must serialize with only one or two values (per usual, if the second value is 0px, the default, it must be omitted when serializing).
  • If a 3d translation is specified, all three values must be serialized.

This question is only for the case: translate: 100px 100px 0px vs translate: 100px 100px. IIRC, it seems Gecko and Blink treat the translate(x, y) as translate(x, y, 0) while converting it into a matrix for computation. (Maybe it will simplify it if it only has 2d components.) Basically, 3d transformation is different from 2d transformation (by using different number of axes), so my question here is, what is the potential side-effects if we serialize translate: 100px 100px 0px as translate: 100px 100px? If the side-effects is not obvious in this case, could we make it simpler?

[1] https://drafts.csswg.org/css-transforms-2/#individual-transform-serialization

Activity

  1. BorisChiou commented on Nov 8, 2018

    @BorisChiou
    ContributorAuthor
  2. emilio commented on Nov 8, 2018

    @emilio
    Collaborator

    cc @tabatkins

    TL;DR is: why is it incorrect to serialize translate: 10px 0 0; as translate: 10px. I don't get which side effect the spec talks about, at least for translation and scaling I'm pretty sure there's no such side effect.

  3. tabatkins commented on Nov 9, 2018

    @tabatkins
    Member

    translateZ(0) absolutely has side effects; it's a classic hack to trigger forcing the element onto its own rendering layer. Iirc all the 3d transforms do so, even if they're "identity" transforms otherwise.

  4. birtles commented on Nov 9, 2018

    @birtles
    Contributor

    As mentioned in w3c/fxtf-drafts#313, that's WebKit/Blink-specific behavior. It's not clear to me that it's necessary to preserve that behavior with the individual transform properties.

  5. tabatkins commented on Nov 9, 2018

    @tabatkins
    Member

    I was under the apparently-mistaken impression that the effect was present in all browsers!

    That said, it would still be quite bad if, in WK/Blink, the element flipped from 3d to 2d in the middle of an animation, triggering all the weirdness of being demoted and then promoted again. So long as this quirk exists, I lean towards making sure the underlying value is consistent with keeping such animations 3d the whole time.

  6. birtles commented on Nov 10, 2018

    @birtles
    Contributor

    I guess I'm wondering if we can make Blink not interpret translate: 10px 10px 0 as a 3D transform? (While leaving transform: translateZ(0) as doing so.) I believe the individual transform properties are not shipping yet and are not implemented in WebKit so we can avoid propagating the quirk there?

    Animating from translate: 10px 10px -10px to translate: 10px 10px 10px shouldn't trigger layer destruction/re-creation since so long as the element is animated, it effectively has will-change: translate applied and hence should keep its layer throughout.

  7. tabatkins commented on Oct 7, 2019

    @tabatkins
    Member

    I'm not sure why we'd want to interpret 10px 10px 0 as a 2d transform. It's clearly 3d; the author supplied three values.

    While you're right that a CSS animation will indeed preserve the layer, setting things manually (either in an animation, or statically in a group of things with different z values) will still cause it to change its rendering if a 0 z value is treated as 2d.

  8. emilio commented on Oct 8, 2019

    @emilio
    Collaborator

    Why would it? I don't get it. The fact that the z axis is zero doesn't change anything, regardless of whehter the user provided it or not.

  9. tabatkins commented on Oct 8, 2019

    @tabatkins
    Member

    As I stated above, yes it does, at least in current Chrome/WebKit. 3d transforms render differently than equivalent 2d transforms.

  10. emilio commented on Oct 8, 2019

    @emilio
    Collaborator

    That seems like a bug in Chrome / WebKit to me.

  11. emilio commented on Oct 8, 2019

    @emilio
    Collaborator

    And with that I mean: That's not something that deserves a spec to be changed.

  12. tabatkins commented on Oct 8, 2019

    @tabatkins
    Member

    Bug or not (it at least partially is), it's been part of WK/Chrome's transform implementation since it first shipped, and the web depends on that behavior as a "promote to a layer" perf hack. (It also has implications on text anti-aliasing, iirc.) We don't simplify translate3d() into a translate() if it has a 0 z argument, or vice versa.

    The distinction is even maintained in TypedOM, which distinguishes between an unpassed z argument to CSSTranslate and a passed 0 value, and similar for the other 2d-and-3d constructors: https://drafts.css-houdini.org/css-typed-om/#dom-csstranslate-csstranslate

    So far, I've carefully kept the various transform things consistent in this quirk, and I'd like to maintain that. I don't think we should drop it from some syntax forms and not others, because that makes it confusing to predict which behavior you're going to get in WK/Chrome browsers.

    If we want to remove it, I'd like to remove it from all transform syntaxes.

  13. emilio commented on Oct 8, 2019

    @emilio
    Collaborator

    You never simplify any transform function into another, unless you're interpolating, sure, but I don't think it compares apples-to-apples. I still think this is a bug. Browsers are much better at layerizing nowadays, and websites can use will-change: transform if they need to hint the browser. So I think there's no reason to do this.

  14. 13 remaining items

  15. progers commented on Oct 23, 2019

    @progers
    Contributor

    This has little dependency on the issue but it was mentioned several times in this discussion that chromium uses translate3d(0, 0, 0) and translateZ(0) as a compositing trigger. We are attempting to remove this in https://crbug.com/1012775.

  16. yisibl commented on Mar 9, 2020

    @yisibl
    Contributor

    @progers

    Is there any conclusion on this issue? It seems that using --disable-features = DoNotCompositeTrivial3D can no longer be disable.

    This has little dependency on the issue but it was mentioned several times in this discussion that chromium uses translate3d(0, 0, 0) and translateZ(0) as a compositing trigger. We are attempting to remove this in https://crbug.com/1012775.

  17. progers commented on Mar 9, 2020

    @progers
    Contributor

    @yisibl, we attempted to remove the behavior where chromium uses trivial 3d transforms (e.g., transform: translateZ(0)) as a compositing trigger but found the performance tradeoff to not be worth it (it led to a measurable increase in re-painting). Unfortunately, we had to return to using these as a compositing hint. If you are still having issues with chromium in this area, please file a bug at https://crbug.com and I will take a look.

  18. tabatkins commented on Mar 9, 2020

    @tabatkins
    Member

    In that case, Agenda+ to go back to tracking "author explicitly gave a 3d value, we should serialize it as such even if it's equivalent to a 2d value".

  19. css-meeting-bot commented on Mar 11, 2020

    @css-meeting-bot
    Member

    The CSS Working Group just discussed [css-transforms-2] Is it necessary to serialize all 3 components of translate given the 3rd component is 0px, and agreed to the following:

    • RESOLVED: No change
    The full IRC log of that discussion <dael> Topic: [css-transforms-2] Is it necessary to serialize all 3 components of translate given the 3rd component is 0px
    <dael> github: https://github.com//issues/3305
    <dael> Rossen_: TabAtkins you brought this back?
    <chrishtr> (had to leave early, conflicting meeting in second half-hour)
    <dael> TabAtkins: Yes. Originally spec for individual transform properties distinguished between author writing 2d and 3d transform
    <dael> TabAtkins: FF and maybe others objected b/c having z component of 0 is same as 2d translate.
    <dael> TabAtkins: I objected at time b/c Chrome and WK had quirk where we used 3d transform presense as a hint to move to compositing layer. We were going to try and remove it which is why we accepted FF proposal
    <dael> TabAtkins: Turns out we can't remove. We see a lot of extra paints from things not moving to compositing layer. B/c this is unacceptable amount of lost performance we're keeping the hack for now and may need forever.
    <dael> TabAtkins: Want to revert spec to keep track of if something was 2d or 3d so you can round trip.
    <flackr> I think interpolations are also different between 2d and 3d
    <dael> emilio: This quirk is transform specific. Don't get why you need more
    <dael> TabAtkins: All 3d transforms do it right now
    <dael> emilio: I think that translate could be changed. I don't think. people are doing translate (0,0,0)
    <dael> TabAtkins: I doubt they are. But if this is being kept around I'd like to be consistent across platform if we keep 2d and 3d
    <dael> emilio: But transform is different b/c people use transform set
    <dael> TabAtkins: Impacts how we serialize. Matrix or Matrix 3d for example
    <dael> emilio: Seems wrong
    <dael> dbaron: Does 2d or 3d influence animation?
    <dael> TabAtkins: Only with rest of the quirk we talked about
    <dael> flackr: I think this effects complialtion when intrep between matrix
    <flackr> s/complialtion/decomposition
    <dael> AmeliaBR: Animating between 2 2d transformations then your animation is entirely 2d. 2d to 3d it gets upgraded so animation becomes 3d
    <dael> flackr: If there were a case where 3d matrix becomes 2d at 0 it could cause different interp. But only when fallback to matrix interp
    <TabAtkins> I was wrong - it doesn't affect whether we serialize as matrix() or matrix3d()
    <dael> emilio: And doesn't apply to individual transform properties right
    <dael> flackr: Right, I don't think have to fall back to individual transform prop
    <dael> smfr: WK hasn't imple individual and it would be nice as a break to get away from the hack.
    <dael> emilio: TabAtkins I tested and it's not what you were saying
    <dael> TabAtkins: Yep, I jsut tested and found the same
    <dael> TabAtkins: smfr I agree I would love if authors use will-change but it won't effect if we can remove translate-z hack. It means have to be inconcsistent in typedOM b/c right now they track 2d or 3d and they'll want to serialize transformed values.
    <dael> TabAtkins: I'm not happiest with hack being limited to just 3d transform functions. I don't like inconsistent if you turn transform into individual transform. Doesn't feel right to me. Even if we don't like hack existing I don't like inconsistency in platform
    <dael> emilio: Will be inconsistent one way or the other
    <dael> TabAtkins: If something is promoted to compositing is inconssitent. But the more obvious to authors as to if it's in typedOM I'd like to be consistent
    <dael> emilio: Still don't think you should get is3d transform
    <dael> TabAtkins: We want to change if you set with 3 we serialize to 3
    <dael> AmeliaBR: And that's is3d for typed OM, right?
    <dael> TabAtkins: Not sure what you're asking about
    <dael> AmeliaBR: Clarify what emilio thinks is inconsistent. I understand prop is we consistenly keep track of if it's 2d or 3d
    <dael> emilio: Computed serializes 2d for translate-set:0
    <dael> TabAtkins: Yeah we've already got inconsistency in there. That's annoying.
    <dael> TabAtkins: I'm fine accepting it's jsut transform functions that preserve 3d. And not even computed value. This is terrible. Everything is terrible
    <dael> emilio: Agree
    <dael> TabAtkins: I'm fine no change.
    <florian> s/translate-set:0/translateZ(0)/
    <dael> Rossen_: Prop: Close no change
    <dael> Rossen_: And then hopefully someone will make TabAtkins feel better
    <dael> emilio: I can say I'm sad too
    <dael> Rossen_: We all share the pain
    <dael> florian: There's precedent for writing this is sad within spec
    <dael> RESOLVED: No change
  20. dbaron commented on Mar 16, 2021

    @dbaron
    Member

    I discovered (via git blame) that while tests were added for this resolution, it still hasn't been edited into the spec. (If I hadn't happened to run git blame, I would have left the conclusion in Chromium bug 1180311 and Chromium bug 1180387 that the tests were buggy.

  21. dbaron commented on Apr 2, 2021

    @dbaron
    Member

    I've made the changes for the first resolution in the spec in #6147.

    I still need to work out exactly what the second resolution ("RESOLVED: Require transform funcitons to be downgraded to 2d if possible") means in terms of spec changes. It's not completely clear to me if the resolution was about just serialization, or about both serialization and interpolation, although I think it was the latter, and I think it also seems a bit odd if it were only the former, because it would mean that interpolation varies based on something that you can't see in the serialization. I think the implication of the discussion is that there should probably also be a note about the possibility of reverting the change if it's not sufficiently compatible.

  22. dbaron commented on Oct 26, 2021

    @dbaron
    Member

    I also need to figure out when "downgraded to 2d" happens. I'm thinking it makes sense for the specified value of the property to preserve the functions as they are, but the computed value to do any potential downgrading. So this change would apply to the model of what the computed value is (including both the "Computed value:" line and w3c/css-houdini-drafts#1052), and then how that value is used in interpolation.

  23. added a commit that references this issue on Oct 26, 2021
  24. yisibl commented on Mar 9, 2026

    @yisibl
    Contributor

    TabAtkins: I objected at time b/c Chrome and WK had quirk where we used 3d transform presense as a hint to move to compositing layer. We were going to try and remove it which is why we accepted FF proposal

    TabAtkins: Turns out we can't remove. We see a lot of extra paints from things not moving to compositing layer. B/c this is unacceptable amount of lost performance we're keeping the hack for now and may need forever.

    @tabatkins @dbaron

    I hope the specification could include additional clarification that for user agents requiring backward compatibility, 3D transforms should not be converted to 2D.

    This would provide valuable guidance for tools like CSS compressors. Otherwise, it could lead to debates like this comment here:

    but nothing in the actual CSS spec says this is required.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions