-
Notifications
You must be signed in to change notification settings - Fork 50
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-transform-2] Logical Transforms #311
Comments
/cc @flackr @stephenmcgruer @smfr who have contributed most of the ideas here in various discussions. |
Thanks for filing this! Just adding some notes and thoughts: I extended your demo with an example of using the technique of adding a logical-flip matrix: It's important to note that you have to undo this logical flip or else the content would be flipped as well. I wonder if instead of adding logical to each transform function we should add a logical "transform-function" which produces the correct flip for the writing mode. I suspect logical rotation does in fact make sense. If you consider cases such as an arrow that turns to point at some text, the rotation direction will depend on writing direction. For transform-origin, we'd need to add logical keywords to replace top/left/bottom/right, e.g. (block-)start/center/end and (inline-)start/center/end. For interpolation, I assume we want translate(x, y) to be interpolable with the logical equivalent which is perhaps an argument that the logical transforms should implicitly alias to the physical (or vice versa)? |
Just what I was about to suggest. Something like:
So for eample, for LTR,
For vertical modes, ther would be some rotate() in there. |
Note that it would have to be the first transform in order to modify all of the subsequent transform functions and needs to be undone afterwards in order to not actually transform the element content itself. Another option could be a composible function, i.e. transform: logical(translate(100px, 200px))
It's all in my codepen :-): *[dir=h_lr] {
writing-mode: horizontal-tb;
direction: ltr;
--logical-flip: matrix(1, 0, 0, 1, 0, 0); /* identity */
--inverse-logical-flip: var(--logical-flip);
}
*[dir=h_rl] {
writing-mode: horizontal-tb;
direction: rtl;
--logical-flip: matrix(-1, 0, 0, 1, 0, 0); /* equivalent to scale(-1, 1) */
--inverse-logical-flip: var(--logical-flip);
}
*[dir=v_lr] {
writing-mode: vertical-lr;
direction: ltr;
--logical-flip: matrix(0, 1, 1, 0, 0, 0); /* flips x and y components */
--inverse-logical-flip: var(--logical-flip);
}
*[dir=v_rl] {
writing-mode: vertical-lr;
direction: rtl;
--logical-flip: matrix(0, -1, 1, 0, 0, 0); /* flips components and inverts x component - inverse is not symmetric */
--inverse-logical-flip: matrix(0, 1, -1, 0, 0, 0); /* flips components and inverts y component. */
} I think percentage resolution might also be a special case for vertical writing modes but I haven't tested this. |
Any updates ? |
There's also a CSSWG issue: w3c/csswg-drafts#1544 |
Problem
Currently transform only defines physical properties e.g., translate and scale work on x and y ignoring block or inline axis (as controlled by writing-mode and direction).
CSS defines a set of logical (longhand?) properties that allow web developers to create layouts that are correct regardless of the writing mode. The fact that transform does not have logical longhands makes it awkward to use in conjunction with other logical properties to create writing mode independent layout and animations.
See for example this article to see how developers currently use transforms in such context. Another example is RTLCSS which seems to be a popular style preprocessor tool used to get around this shortcoming.
I propose we add logical longhand syntax for related transform properties.
Here is a simple demo that shows the current behavior and what I consider the ideal logical behavior of transform when writing mode is changes.
BTW RTLCSS has a playground where you can test how it maps physical LTR styles to RTL versions.
For example it turns:
into:
Transforms are popular for animations due to their performance benefits. So this issue is particularly problematic for animations.
Another related issue is that as we have been working on introducing scroll-linked animations (which can operate based on logical or physical directions), it seems most natural that a logical ScrollTimeline should be used to drive logical properties. So having logical transforms is desired. This is why we originally started looking into this.
Proposal
Introduce logical syntax for transform where various 2d components can be
specified in terms of logical values such as inline base and block flow direction.
These logical values can then be mapped to appropriate physical values similar to other logical properties.
Syntax ideas 1
Perhaps we can have logical version of 2d transform functions e.g.,
translate-logical(inline, block)
===translate(x, y)
scale-logical(inline, block)
===scale(x, y)
Also individual transform for inline, block matching translate{X,Y} and scale{X,Y}
Similarly introduce a logical version of transform origin
transform-origin-logical: inline block
===transform-origin: x y
This seems close to what other logical properties have.
For the shorthand, we can allow both physical and logical versions to be mixed in transform function list.
This also provides a nice way to have backward compatibility e.g.:
Syntax idea 2
Perhaps we can have a mode:
transform-mode: logical; /* defaults to physical */
Although based on my understanding CSSWG seems to prefer to avoid designs that introduce modes.
Other considerations
What should happen to rotate?
For rotation we can have define the rotation direction that relies on the inline and block arrows relationship. I suspect this may actually be meaningful since this is what the RTLCSS appears to be doing. Alternatively we can leave the rotation to remain consistent regardless of writing mode.
What about 3d transform functions?
Z axis does not have a logical equivalent so it should be left alone. Given this, it is not clear if we need to have logical version of 3d transform functions.
How should this specified?
We suspect that this does not require a whole lot of change to the specification. In particular, we may be able to do this by introducing a matrix that represent the logical to physical mapping and simply do a matrix multiplication as the last step to change logical into physical. Obviously a closer look is needed to actually confirm this is possible.
Performance implications
Writing modes are not expected to change very often so we don't expect this to be a lot different than recalculations that needs to happen to resolve percentage and calc values. Browser fast path could still continue to operate on physical basis.
The text was updated successfully, but these errors were encountered: