The goal is to render HTML elements with perspective, as in the examples below.
We tried using CSS skew
transformations, but those didn't look right as they warped the element's aspect ratio or otherwise created distortions.
Here are CSS skew transformations we tried. None of these look as good as the examples below.
Codepen: https://codepen.io/anon/pen/MMzdPx
transform: skew(20deg, -15deg);
transform: skew(45deg, -25deg);
transform: skew(45deg, -30deg);
How can you achieve this kind of perspective rendering of HTML elements?
As you said, use perspective combined with some rotation
img {
width:150px;
margin:20px;
}
img.first {
transform:perspective(500px) rotateY(20deg);
}
img.last {
transform:perspective(500px) rotateY(-20deg);
}
<img src="https://i.imgur.com/DGAOsPz.png" class="first">
<img src="https://i.imgur.com/DGAOsPz.png" class="last">
img {
width:150px;
margin:30px;
transform:perspective(500px) rotateY(15deg) rotateX(50deg) rotateZ(-20deg);
}
<img src="https://i.imgur.com/DGAOsPz.png" >
Related question for more details:
CSS 3d transform doesn't work if perspective is set in the end of property
Something like this. I used CSS custom properties, to make the calculation a little bit more obvious.
Please note: The order of the transform properties is very important. It is evaluated from right to left:
From MDN transform CSS
The transform functions are multiplied in order from left to right, meaning that composite transforms are effectively applied in order from right to left.
That means, transform: rotateX(90deg) translateX(100px)
is not the same as transform: translateX(100px) rotateX(90deg)
. The former first translates and then rotates while the latter does the rotation before the translations.
.box {
width: 130px;
height: 268px;
background-size: cover;
}
.box:nth-child(4n+1) {
background: url(https://picsum.photos/id/100/136/276);
}
.box:nth-child(4n+2) {
background: url(https://picsum.photos/id/200/136/276);
}
.box:nth-child(4n+3) {
background: url(https://picsum.photos/id/300/136/276);
}
.box:nth-child(4n+4) {
background: url(https://picsum.photos/id/400/136/276);
}
.container {
transform: perspective(1200px) rotateX(60deg) rotateZ(-35deg) translate3d(-100px, -200px, -500px);
}
.skew {
position: absolute;
top: 200px;
left: 50%;
--width: 140px;
--height: 278px;
--x: 0;
--y: 0;
--offsetX: calc(var(--x) * var(--width));
--offsetY: calc(var(--y) * var(--height));
transform: translate(var(--offsetX), var(--offsetY));
}
.skew:nth-child(5n + 1) {
--x: -2;
}
.skew:nth-child(5n + 2) {
--x: -1;
}
.skew:nth-child(5n + 3) {
--x: 0;
}
.skew:nth-child(5n + 4) {
--x: 1;
}
.skew:nth-child(5n + 5) {
--x: 2;
}
.skew:nth-child(n + 1):nth-child(-n + 5) {
--y: -2;
}
.skew:nth-child(n + 6):nth-child(-n + 10) {
--y: -1;
}
.skew:nth-child(n + 11):nth-child(-n + 15) {
--y: 0;
}
.skew:nth-child(n + 16):nth-child(-n + 20) {
--y: 1;
}
.skew:nth-child(n + 21):nth-child(-n + 25) {
--y: 2;
}
<div class="container">
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
<div class="skew box"></div>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With