I'm building a website that has a 3D book:
My main goal is to support a png
and a webp
image for all browsers. If I only load one image all is working fine:
.book-container {
display: flex;
align-items: center;
justify-content: center;
perspective: 600px;
}
@keyframes initAnimation {
0% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(-30deg);
}
}
.book {
width: 200px;
height: 320px;
position: relative;
transform-style: preserve-3d;
transform: rotateY(-30deg);
transition: 1s ease;
animation: 1s ease 0s 1 initAnimation;
}
.book:hover {
transform: rotateY(0deg);
}
.book > :first-child {
position: absolute;
top: 0;
left: 0;
background-color: red;
width: 200px;
height: 320px;
transform: translateZ(25px);
background-color: #01060f;
border-radius: 0 2px 2px 0;
box-shadow: 5px 5px 20px #E5E4E2;
}
.book::before {
position: absolute;
content: ' ';
background-color: blue;
left: 0;
top: 3px;
width: 48px;
height: 314px;
transform: translateX(172px) rotateY(90deg);
background: linear-gradient(90deg,
#fff 0%,
#f9f9f9 5%,
#fff 10%,
#f9f9f9 15%,
#fff 20%,
#f9f9f9 25%,
#fff 30%,
#f9f9f9 35%,
#fff 40%,
#f9f9f9 45%,
#fff 50%,
#f9f9f9 55%,
#fff 60%,
#f9f9f9 65%,
#fff 70%,
#f9f9f9 75%,
#fff 80%,
#f9f9f9 85%,
#fff 90%,
#f9f9f9 95%,
#fff 100%
);
}
.book::after {
position: absolute;
top: 0;
left: 0;
content: ' ';
width: 200px;
height: 320px;
transform: translateZ(-25px);
background-color: #01060f;
border-radius: 0 2px 2px 0;
box-shadow: -10px 0 50px 10px #666;
}
<a
href="#"
target="_blank"
rel="noreferrer noopener">
<div >
<img
alt="My Cover"
src="https://i.stack.imgur.com/1MPyO.png"
/>
</div>
</a>
But when I add the picture element to support both, the image loses the resize:
.book-container {
display: flex;
align-items: center;
justify-content: center;
perspective: 600px;
}
@keyframes initAnimation {
0% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(-30deg);
}
}
.book {
width: 200px;
height: 320px;
position: relative;
transform-style: preserve-3d;
transform: rotateY(-30deg);
transition: 1s ease;
animation: 1s ease 0s 1 initAnimation;
}
.book:hover {
transform: rotateY(0deg);
}
.book > :first-child {
position: absolute;
top: 0;
left: 0;
background-color: red;
width: 200px;
height: 320px;
transform: translateZ(25px);
background-color: #01060f;
border-radius: 0 2px 2px 0;
box-shadow: 5px 5px 20px #E5E4E2;
}
.book::before {
position: absolute;
content: ' ';
background-color: blue;
left: 0;
top: 3px;
width: 48px;
height: 314px;
transform: translateX(172px) rotateY(90deg);
background: linear-gradient(90deg,
#fff 0%,
#f9f9f9 5%,
#fff 10%,
#f9f9f9 15%,
#fff 20%,
#f9f9f9 25%,
#fff 30%,
#f9f9f9 35%,
#fff 40%,
#f9f9f9 45%,
#fff 50%,
#f9f9f9 55%,
#fff 60%,
#f9f9f9 65%,
#fff 70%,
#f9f9f9 75%,
#fff 80%,
#f9f9f9 85%,
#fff 90%,
#f9f9f9 95%,
#fff 100%
);
}
.book::after {
position: absolute;
top: 0;
left: 0;
content: ' ';
width: 200px;
height: 320px;
transform: translateZ(-25px);
background-color: #01060f;
border-radius: 0 2px 2px 0;
box-shadow: -10px 0 50px 10px #666;
}
<a
href="#"
target="_blank"
rel="noreferrer noopener">
<div >
<picture>
<source srcset="https://i.ibb.co/grB6NbQ/THE-BOOK-cover-image.webp" type="image/webp">
<source srcset="https://i.stack.imgur.com/1MPyO.png" type="image/png">
<img
alt="My Cover"
src="https://i.stack.imgur.com/1MPyO.png"/>
</picture>
</div>
</a>
Any idea what should I change? I guess the main issue is in this part of the code:
.book > :first-child {
position: absolute;
top: 0;
left: 0;
background-color: red;
width: 200px;
height: 320px;
transform: translateZ(25px);
background-color: #01060f;
border-radius: 0 2px 2px 0;
box-shadow: 5px 5px 20px #E5E4E2;
}
Here is the full snippet if you want to check it:
https://jsfiddle.net/p01vac52/1/
But I'm not so sure, I didn't expect that the picture element will fully break it. Or do you think it's a better idea to change the source using JS?
CodePudding user response:
As commented,
The srcset
attribute selects which image to load based on its size values and device specs, the picture
/ img
elements will still need width
/height
values to scale the loaded image to the required size.
I added img { width: 100% }
to make the image fit inside .book { width: 200px; height: 320px; }
.
.book-container {
display: flex;
align-items: center;
justify-content: center;
perspective: 600px;
}
@keyframes initAnimation {
0% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(-30deg);
}
}
.book {
width: 200px;
height: 320px;
position: relative;
transform-style: preserve-3d;
transform: rotateY(-30deg);
transition: 1s ease;
animation: 1s ease 0s 1 initAnimation;
}
img {
width: 100%;
}
.book:hover {
transform: rotateY(0deg);
}
.book> :first-child {
position: absolute;
top: 0;
left: 0;
background-color: red;
width: 200px;
height: 320px;
transform: translateZ(25px);
background-color: #01060f;
border-radius: 0 2px 2px 0;
box-shadow: 5px 5px 20px #E5E4E2;
}
.book::before {
position: absolute;
content: ' ';
background-color: blue;
left: 0;
top: 3px;
width: 48px;
height: 314px;
transform: translateX(172px) rotateY(90deg);
background: linear-gradient(90deg, #fff 0%, #f9f9f9 5%, #fff 10%, #f9f9f9 15%, #fff 20%, #f9f9f9 25%, #fff 30%, #f9f9f9 35%, #fff 40%, #f9f9f9 45%, #fff 50%, #f9f9f9 55%, #fff 60%, #f9f9f9 65%, #fff 70%, #f9f9f9 75%, #fff 80%, #f9f9f9 85%, #fff 90%, #f9f9f9 95%, #fff 100%);
}
.book::after {
position: absolute;
top: 0;
left: 0;
content: ' ';
width: 200px;
height: 320px;
transform: translateZ(-25px);
background-color: #01060f;
border-radius: 0 2px 2px 0;
box-shadow: -10px 0 50px 10px #666;
}
<a href="#" target="_blank" rel="noreferrer noopener">
<div >
<picture>
<source srcset="https://i.ibb.co/grB6NbQ/THE-BOOK-cover-image.webp" type="image/webp">
<source srcset="https://i.stack.imgur.com/1MPyO.png" type="image/png">
<img alt="My Cover" src="https://i.stack.imgur.com/1MPyO.png" />
</picture>
</div>
</a>