Skip to content

Commit 0f69d4f

Browse files
authored
[v4] Make 3D rotations composable (#13319)
* Reorganize to co-locate rotate/skew/transform * Make 3D rotations composable * Uppercase axis in rotate functions * Update changelog --------- Co-authored-by: Adam Wathan <[email protected]>
1 parent 86dd697 commit 0f69d4f

File tree

5 files changed

+397
-218
lines changed

5 files changed

+397
-218
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Make `rotate-x/y/z-*` utilities composable ([#13319](https://github.com/tailwindlabs/tailwindcss/pull/13319))
13+
1014
### Fixed
1115

1216
- Remove percentage values for `translate-z` utilities ([#13321](https://github.com/tailwindlabs/tailwindcss/pull/13321))

packages/tailwindcss/src/__snapshots__/intellisense.test.ts.snap

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,15 @@ exports[`getClassList 1`] = `
109109
"-rotate-y-45",
110110
"-rotate-y-6",
111111
"-rotate-y-90",
112+
"-rotate-z-0",
113+
"-rotate-z-1",
114+
"-rotate-z-12",
115+
"-rotate-z-180",
116+
"-rotate-z-2",
117+
"-rotate-z-3",
118+
"-rotate-z-45",
119+
"-rotate-z-6",
120+
"-rotate-z-90",
112121
"-scale-0",
113122
"-scale-100",
114123
"-scale-105",
@@ -1332,6 +1341,15 @@ exports[`getClassList 1`] = `
13321341
"rotate-y-45",
13331342
"rotate-y-6",
13341343
"rotate-y-90",
1344+
"rotate-z-0",
1345+
"rotate-z-1",
1346+
"rotate-z-12",
1347+
"rotate-z-180",
1348+
"rotate-z-2",
1349+
"rotate-z-3",
1350+
"rotate-z-45",
1351+
"rotate-z-6",
1352+
"rotate-z-90",
13351353
"rounded-b-full",
13361354
"rounded-b-none",
13371355
"rounded-bl-full",

packages/tailwindcss/src/property-order.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,19 @@ export default [
6767

6868
'transform-origin',
6969

70-
// '--tw-translate-x',
71-
// '--tw-translate-y',
7270
'translate',
73-
'rotate',
74-
// '--tw-rotate',
75-
'--tw-skew-x',
76-
'--tw-skew-y',
71+
'--tw-translate-x',
72+
'--tw-translate-y',
73+
'scale',
7774
'--tw-scale-x',
7875
'--tw-scale-y',
7976
'--tw-scale-z',
80-
'scale',
77+
'rotate',
78+
'--tw-rotate-x',
79+
'--tw-rotate-y',
80+
'--tw-rotate-z',
81+
'--tw-skew-x',
82+
'--tw-skew-y',
8183
'transform',
8284

8385
'animation',

packages/tailwindcss/src/utilities.test.ts

Lines changed: 180 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2583,34 +2583,34 @@ test('translate-y', () => {
25832583

25842584
test('translate-z', () => {
25852585
expect(run(['translate-y-px', '-translate-z-[--value]'])).toMatchInlineSnapshot(`
2586-
".-translate-z-\\[--value\\] {
2587-
--tw-translate-z: calc(var(--value) * -1);
2588-
translate: var(--tw-translate-x) var(--tw-translate-y) var(--tw-translate-z);
2589-
}
2586+
".translate-y-px {
2587+
--tw-translate-y: 1px;
2588+
translate: var(--tw-translate-x) var(--tw-translate-y);
2589+
}
25902590
2591-
.translate-y-px {
2592-
--tw-translate-y: 1px;
2593-
translate: var(--tw-translate-x) var(--tw-translate-y);
2594-
}
2591+
.-translate-z-\\[--value\\] {
2592+
--tw-translate-z: calc(var(--value) * -1);
2593+
translate: var(--tw-translate-x) var(--tw-translate-y) var(--tw-translate-z);
2594+
}
25952595
2596-
@property --tw-translate-x {
2597-
syntax: "<length-percentage>";
2598-
inherits: false;
2599-
initial-value: 0;
2600-
}
2596+
@property --tw-translate-x {
2597+
syntax: "<length-percentage>";
2598+
inherits: false;
2599+
initial-value: 0;
2600+
}
26012601
2602-
@property --tw-translate-y {
2603-
syntax: "<length-percentage>";
2604-
inherits: false;
2605-
initial-value: 0;
2606-
}
2602+
@property --tw-translate-y {
2603+
syntax: "<length-percentage>";
2604+
inherits: false;
2605+
initial-value: 0;
2606+
}
26072607
2608-
@property --tw-translate-z {
2609-
syntax: "<length-percentage>";
2610-
inherits: false;
2611-
initial-value: 0;
2612-
}"
2613-
`)
2608+
@property --tw-translate-z {
2609+
syntax: "<length-percentage>";
2610+
inherits: false;
2611+
initial-value: 0;
2612+
}"
2613+
`)
26142614
expect(run(['translate-z', 'translate-z-full', '-translate-z-full', 'translate-z-1/2'])).toEqual(
26152615
'',
26162616
)
@@ -2668,15 +2668,48 @@ test('rotate', () => {
26682668
test('rotate-x', () => {
26692669
expect(run(['rotate-x-45', '-rotate-x-45', 'rotate-x-[123deg]'])).toMatchInlineSnapshot(`
26702670
".-rotate-x-45 {
2671-
rotate: x -45deg;
2671+
--tw-rotate-x: calc(rotateX(45deg) * -1);
2672+
transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
26722673
}
26732674
26742675
.rotate-x-45 {
2675-
rotate: x 45deg;
2676+
--tw-rotate-x: rotateX(45deg);
2677+
transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
26762678
}
26772679
26782680
.rotate-x-\\[123deg\\] {
2679-
rotate: x 123deg;
2681+
--tw-rotate-x: 123deg;
2682+
transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
2683+
}
2684+
2685+
@property --tw-rotate-x {
2686+
syntax: "<transform-function>";
2687+
inherits: false;
2688+
initial-value: rotateX(0);
2689+
}
2690+
2691+
@property --tw-rotate-y {
2692+
syntax: "<transform-function>";
2693+
inherits: false;
2694+
initial-value: rotateY(0);
2695+
}
2696+
2697+
@property --tw-rotate-z {
2698+
syntax: "<transform-function>";
2699+
inherits: false;
2700+
initial-value: rotateZ(0);
2701+
}
2702+
2703+
@property --tw-skew-x {
2704+
syntax: "<transform-function>";
2705+
inherits: false;
2706+
initial-value: skewX(0);
2707+
}
2708+
2709+
@property --tw-skew-y {
2710+
syntax: "<transform-function>";
2711+
inherits: false;
2712+
initial-value: skewY(0);
26802713
}"
26812714
`)
26822715
expect(run(['rotate-x', '-rotate-x', 'rotate-x-potato'])).toEqual('')
@@ -2685,15 +2718,48 @@ test('rotate-x', () => {
26852718
test('rotate-y', () => {
26862719
expect(run(['rotate-y-45', '-rotate-y-45', 'rotate-y-[123deg]'])).toMatchInlineSnapshot(`
26872720
".-rotate-y-45 {
2688-
rotate: y -45deg;
2721+
--tw-rotate-y: calc(rotateY(45deg) * -1);
2722+
transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
26892723
}
26902724
26912725
.rotate-y-45 {
2692-
rotate: y 45deg;
2726+
--tw-rotate-y: rotateY(45deg);
2727+
transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
26932728
}
26942729
26952730
.rotate-y-\\[123deg\\] {
2696-
rotate: y 123deg;
2731+
--tw-rotate-y: 123deg;
2732+
transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
2733+
}
2734+
2735+
@property --tw-rotate-x {
2736+
syntax: "<transform-function>";
2737+
inherits: false;
2738+
initial-value: rotateX(0);
2739+
}
2740+
2741+
@property --tw-rotate-y {
2742+
syntax: "<transform-function>";
2743+
inherits: false;
2744+
initial-value: rotateY(0);
2745+
}
2746+
2747+
@property --tw-rotate-z {
2748+
syntax: "<transform-function>";
2749+
inherits: false;
2750+
initial-value: rotateZ(0);
2751+
}
2752+
2753+
@property --tw-skew-x {
2754+
syntax: "<transform-function>";
2755+
inherits: false;
2756+
initial-value: skewX(0);
2757+
}
2758+
2759+
@property --tw-skew-y {
2760+
syntax: "<transform-function>";
2761+
inherits: false;
2762+
initial-value: skewY(0);
26972763
}"
26982764
`)
26992765
expect(run(['rotate-y', '-rotate-y', 'rotate-y-potato'])).toEqual('')
@@ -2704,19 +2770,37 @@ test('skew', () => {
27042770
".-skew-6 {
27052771
--tw-skew-x: skewX(calc(6deg * -1));
27062772
--tw-skew-y: skewY(calc(6deg * -1));
2707-
transform: var(--tw-skew-x) var(--tw-skew-y);
2773+
transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
27082774
}
27092775
27102776
.skew-6 {
27112777
--tw-skew-x: skewX(6deg);
27122778
--tw-skew-y: skewY(6deg);
2713-
transform: var(--tw-skew-x) var(--tw-skew-y);
2779+
transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
27142780
}
27152781
27162782
.skew-\\[123deg\\] {
27172783
--tw-skew-x: skewX(123deg);
27182784
--tw-skew-y: skewY(123deg);
2719-
transform: var(--tw-skew-x) var(--tw-skew-y);
2785+
transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
2786+
}
2787+
2788+
@property --tw-rotate-x {
2789+
syntax: "<transform-function>";
2790+
inherits: false;
2791+
initial-value: rotateX(0);
2792+
}
2793+
2794+
@property --tw-rotate-y {
2795+
syntax: "<transform-function>";
2796+
inherits: false;
2797+
initial-value: rotateY(0);
2798+
}
2799+
2800+
@property --tw-rotate-z {
2801+
syntax: "<transform-function>";
2802+
inherits: false;
2803+
initial-value: rotateZ(0);
27202804
}
27212805
27222806
@property --tw-skew-x {
@@ -2738,17 +2822,35 @@ test('skew-x', () => {
27382822
expect(run(['skew-x-6', '-skew-x-6', 'skew-x-[123deg]'])).toMatchInlineSnapshot(`
27392823
".-skew-x-6 {
27402824
--tw-skew-x: skewX(calc(6deg * -1));
2741-
transform: var(--tw-skew-x) var(--tw-skew-y);
2825+
transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
27422826
}
27432827
27442828
.skew-x-6 {
27452829
--tw-skew-x: skewX(6deg);
2746-
transform: var(--tw-skew-x) var(--tw-skew-y);
2830+
transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
27472831
}
27482832
27492833
.skew-x-\\[123deg\\] {
27502834
--tw-skew-x: skewX(123deg);
2751-
transform: var(--tw-skew-x) var(--tw-skew-y);
2835+
transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
2836+
}
2837+
2838+
@property --tw-rotate-x {
2839+
syntax: "<transform-function>";
2840+
inherits: false;
2841+
initial-value: rotateX(0);
2842+
}
2843+
2844+
@property --tw-rotate-y {
2845+
syntax: "<transform-function>";
2846+
inherits: false;
2847+
initial-value: rotateY(0);
2848+
}
2849+
2850+
@property --tw-rotate-z {
2851+
syntax: "<transform-function>";
2852+
inherits: false;
2853+
initial-value: rotateZ(0);
27522854
}
27532855
27542856
@property --tw-skew-x {
@@ -2770,17 +2872,35 @@ test('skew-y', () => {
27702872
expect(run(['skew-y-6', '-skew-y-6', 'skew-y-[123deg]'])).toMatchInlineSnapshot(`
27712873
".-skew-y-6 {
27722874
--tw-skew-y: skewY(calc(6deg * -1));
2773-
transform: var(--tw-skew-x) var(--tw-skew-y);
2875+
transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
27742876
}
27752877
27762878
.skew-y-6 {
27772879
--tw-skew-y: skewY(6deg);
2778-
transform: var(--tw-skew-x) var(--tw-skew-y);
2880+
transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
27792881
}
27802882
27812883
.skew-y-\\[123deg\\] {
27822884
--tw-skew-y: skewY(123deg);
2783-
transform: var(--tw-skew-x) var(--tw-skew-y);
2885+
transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
2886+
}
2887+
2888+
@property --tw-rotate-x {
2889+
syntax: "<transform-function>";
2890+
inherits: false;
2891+
initial-value: rotateX(0);
2892+
}
2893+
2894+
@property --tw-rotate-y {
2895+
syntax: "<transform-function>";
2896+
inherits: false;
2897+
initial-value: rotateY(0);
2898+
}
2899+
2900+
@property --tw-rotate-z {
2901+
syntax: "<transform-function>";
2902+
inherits: false;
2903+
initial-value: rotateZ(0);
27842904
}
27852905
27862906
@property --tw-skew-x {
@@ -3026,25 +3146,43 @@ test('transform', () => {
30263146
]),
30273147
).toMatchInlineSnapshot(`
30283148
".transform {
3029-
transform: var(--tw-skew-x) var(--tw-skew-y);
3149+
transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
30303150
}
30313151
30323152
.transform-\\[scaleZ\\(2\\)_rotateY\\(45deg\\)\\] {
30333153
transform: scaleZ(2)rotateY(45deg);
30343154
}
30353155
30363156
.transform-cpu {
3037-
transform: var(--tw-skew-x) var(--tw-skew-y);
3157+
transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
30383158
}
30393159
30403160
.transform-gpu {
3041-
transform: translateZ(0) var(--tw-skew-x) var(--tw-skew-y);
3161+
transform: translateZ(0) var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
30423162
}
30433163
30443164
.transform-none {
30453165
transform: none;
30463166
}
30473167
3168+
@property --tw-rotate-x {
3169+
syntax: "<transform-function>";
3170+
inherits: false;
3171+
initial-value: rotateX(0);
3172+
}
3173+
3174+
@property --tw-rotate-y {
3175+
syntax: "<transform-function>";
3176+
inherits: false;
3177+
initial-value: rotateY(0);
3178+
}
3179+
3180+
@property --tw-rotate-z {
3181+
syntax: "<transform-function>";
3182+
inherits: false;
3183+
initial-value: rotateZ(0);
3184+
}
3185+
30483186
@property --tw-skew-x {
30493187
syntax: "<transform-function>";
30503188
inherits: false;

0 commit comments

Comments
 (0)