Below is the base "un-skewed" element we want to skew in both the Z and X direction to create a diagonal skew.
* {
box-sizing: border-box;
transform-style: preserve-3d;
margin: 0; padding: 0;
}
html, body {
height: 100%;
}
body {
perspective: 30rem;
}
body, div, span {
display: flex;
justify-content: center;
align-items: center;
}
section > div > div {
transform: scaleX( 0.5 ) scaleZ( 0.5 );
}
div div:nth-of-type( 2 ) {
transform: rotateY( 180deg ) rotateZ( 90deg );
}
span {
position: absolute;
box-shadow: 0rem 0rem 0rem 0.5rem #444 inset;
width: 10rem;
height: 10rem;
background-color: rgba( 200,200,200,0.25 );
}
span:nth-of-type( 1 ) { transform: translateZ( 5rem ); }
span:nth-of-type( 2 ) { transform: rotateY( 90deg ) translateZ( 5rem ); }
span:nth-of-type( 3 ) { transform: rotateY( -90deg ) translateZ( 5rem ); }
<style>
.rotate_y, .rotate_x {
animation-name: rotateY;
animation-duration: 6s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
@keyframes rotateY {
0% { transform: rotateY( 0deg ); }
100% { transform: rotateY( 360deg ); }
}
.rotate_x {
animation-name: rotateX;
}
@keyframes rotateX {
0% { transform: rotateX( 0deg ); }
100% { transform: rotateX( 360deg ); }
}
</style>
<section class='rotate_y'>
<div class='rotate_x'>
<div>
<div> <span></span><span></span><span></span> </div>
<div> <span></span><span></span><span></span> </div>
</div>
</div>
</section>
Adding transform: skewX( 45deg )
to body section > div > div
in the HTML window works as expected:
* {
box-sizing: border-box;
transform-style: preserve-3d;
margin: 0; padding: 0;
}
html, body {
height: 100%;
}
body {
perspective: 30rem;
}
body, div, span {
display: flex;
justify-content: center;
align-items: center;
}
section > div > div {
transform: scaleX( 0.5 ) scaleZ( 0.5 );
}
div div:nth-of-type( 2 ) {
transform: rotateY( 180deg ) rotateZ( 90deg );
}
span {
position: absolute;
box-shadow: 0rem 0rem 0rem 0.5rem #444 inset;
width: 10rem;
height: 10rem;
background-color: rgba( 200,200,200,0.25 );
}
span:nth-of-type( 1 ) { transform: translateZ( 5rem ); }
span:nth-of-type( 2 ) { transform: rotateY( 90deg ) translateZ( 5rem ); }
span:nth-of-type( 3 ) { transform: rotateY( -90deg ) translateZ( 5rem ); }
<style>
.rotate_y, .rotate_x {
animation-name: rotateY;
animation-duration: 6s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
@keyframes rotateY {
0% { transform: rotateY( 0deg ); }
100% { transform: rotateY( 360deg ); }
}
.rotate_x {
animation-name: rotateX;
}
@keyframes rotateX {
0% { transform: rotateX( 0deg ); }
100% { transform: rotateX( 360deg ); }
}
/* skew in the X direction added */
body section > div > div {
transform: scaleX( 0.5 ) scaleZ( 0.5 ) skewX( 45deg );
}
</style>
<section class='rotate_y'>
<div class='rotate_x'>
<div>
<div> <span></span><span></span><span></span> </div>
<div> <span></span><span></span><span></span> </div>
</div>
</div>
</section>
transform: skewX( 45deg )
and transform: skewY( 45deg )
work perfectly. However adding transform: skewZ( 45deg )
does not.
Is skewing in the Z direction a part of the CSS spec? And if not what is a good workaround?
Below is an example snippet of what happens when I set skewZ()
. ( it nullifies all transform properties as if it's an invalid CSS rule. )
* {
box-sizing: border-box;
transform-style: preserve-3d;
margin: 0; padding: 0;
}
html, body {
height: 100%;
}
body {
perspective: 30rem;
}
body, div, span {
display: flex;
justify-content: center;
align-items: center;
}
section > div > div {
transform: scaleX( 0.5 ) scaleZ( 0.5 );
}
div div:nth-of-type( 2 ) {
transform: rotateY( 180deg ) rotateZ( 90deg );
}
span {
position: absolute;
box-shadow: 0rem 0rem 0rem 0.5rem #444 inset;
width: 10rem;
height: 10rem;
background-color: rgba( 200,200,200,0.25 );
}
span:nth-of-type( 1 ) { transform: translateZ( 5rem ); }
span:nth-of-type( 2 ) { transform: rotateY( 90deg ) translateZ( 5rem ); }
span:nth-of-type( 3 ) { transform: rotateY( -90deg ) translateZ( 5rem ); }
<style>
.rotate_y, .rotate_x {
animation-name: rotateY;
animation-duration: 6s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
@keyframes rotateY {
0% { transform: rotateY( 0deg ); }
100% { transform: rotateY( 360deg ); }
}
.rotate_x {
animation-name: rotateX;
}
@keyframes rotateX {
0% { transform: rotateX( 0deg ); }
100% { transform: rotateX( 360deg ); }
}
/* skewing in the Z direction doesn't register */
body section > div > div {
transform: scaleX( 0.5 ) scaleZ( 0.5 ) skewX( 45deg ) skewZ( 45deg );
}
</style>
<section class='rotate_y'>
<div class='rotate_x'>
<div>
<div> <span></span><span></span><span></span> </div>
<div> <span></span><span></span><span></span> </div>
</div>
</div>
</section>
The desired result here is for the html element in question to be skewed both in the Z and X direction simultaneously.
Actually, there is not the possibility to set simply a skewZ, because it is harder than that.
The skew that you already know, are 2D transforms. What they really are, is skewX (for the Y axis), and skewY (for the X axis).
When going 3D, you would have
Not so easy !
There are 2 ways to get some skewZ.
First, using a rotation, as you already commented. Just rememeber to unset it:
transform: rotateX(90deg) skewX(10deg) rotateX(-90deg)
The other one is to use a transform matrix . This is a matrix with the clasicals skews
1 skewY 0 0
skewX 1 0 0
0 0 1 0
0 0 0 1
And this is a matrix with the Z skews
1 0 skewZ/x 0
0 1 skewZ/y 0
0 0 1 0
0 0 0 1