I am currently in the process of creating a unique "3D carousel" from scratch.
This carousel is designed to hold 3 slides that are stacked on top of each other using CSS Grid, all with the same grid-area: 1/1
property.
The first slide remains positioned at the center of the carousel.
To achieve a basic 3D effect, I utilize a translate function to shift slides 2 (to the left) and 3 (to the right).
My goal is to have the container of the carousel perfectly fit the content (the 3 slides), hence I establish padding on the left and right sides of the carousel to compensate for any overflow caused by slides 2 and 3.
Currently, the amount of padding matches the offset of slides 2 and 3. (For example, if I translateX(-100px)
slide 2, then a padding-left: 100px
works effectively.
However, things become more challenging when I apply a scale(0.5)
transformation to slides 2 and 3: the padding value becomes inaccurate. Although I can manually adjust the padding to find a suitable value, I cannot seem to discover a formula that consistently accommodates changes in the main slide width, offset, or scaling factor.
I have provided a Codepen demonstration to highlight this issue, especially occurring at resolutions below 1024px (where you need to resize the window to observe the problem).
window.onload = function (event) {
document.querySelector("span").innerHTML = window.innerWidth + 'px'
};
window.onresize = function (event) {
document.querySelector("span").innerHTML = window.innerWidth + 'px';
};
* {
box-sizing: border-box;
}
div {
--offset: 100px;
--scaling: 0.75;
--width: 200px;
--padding: calc(
var(--width) / 2 * var(--scaling)
);
border: 1px dashed black;
background: lightgrey;
display: inline-flex;
width: var(--width);
padding: 0 var(--padding);
box-sizing: content-box;
}
div ul {
list-style: none;
padding: 0;
margin: 0;
display: grid;
}
@media screen and (max-width: 1025px) {
div ul {
--offset: 75px;
--scaling: 0.75;
--width: 150px;
}
}
div ul li {
grid-area: 1/1;
border: 1px solid black;
width: 200px;
height: 200px;
}
div ul li:nth-child(1) {
background-color: red;
z-index: 1;
}
div ul li:nth-child(2) {
background-color: blue;
transform: translateX(var(--offset)) scale(var(--scaling));
}
div ul li:nth-child(3) {
background-color: green;
transform: translateX(calc(var(--offset) * -1)) scale(var(--scaling));
}
<div>
<ul>
<li>Card 1</li>
<li>Card 2</li>
<li>Card 3</li>
</ul>
</div>
<p>At less than 1024px resolution wide, padding is not correctly calculated (width of the Card 1 changes, offset of Cards 2 and 3 too.)</p>
<p>The padding (lightgrey zone) should <strong>NOT</strong> be visible at the left / right side under 1024 pixels </p>
<p> Current viewport width: <span></span> </p>
Here is a list of manual padding values that align perfectly with corresponding width, offset, and scaling variables. Unfortunately, I have been unable to identify a universal formula connecting these values. Please note that the values may be rounded (e.g., 68px = 67.5px).
// width(px) offset(px) scaling padding(px)
// 150 50 0.50 = 12
// 300 100 0.50 = 25
// 200 100 0.50 = 50
// 150 100 0.50 = 62
// 350 150 0.50 = 62
// 250 100 0.75 = 68
// 300 175 0.50 = 100
// 300 200 0.50 = 125
// 300 200 0.75 = 162
If further details are required, please do not hesitate to reach out. Enjoy experimenting!