Slider 3D
Un carrousel de imágenes 3D usando solo CSS… ¯\(ツ)/¯
<div class="slider-wrapper"> <div class="slider" style="--quantity: 10"> <div style="--position: 1"><div></div></div> <div style="--position: 2"><div></div></div> <div style="--position: 3"><div></div></div> <div style="--position: 4"><div></div></div> <div style="--position: 5"><div></div></div> <div style="--position: 6"><div></div></div> <div style="--position: 7"><div></div></div> <div style="--position: 8"><div></div></div> <div style="--position: 9"><div></div></div> <div style="--position: 10"><div></div></div> </div></div>
.slider-wrapper { width: 100%; height: 16rem; overflow: hidden; position: relative; align-content: center; .slider { --z: 12rem; width: 7rem; height: 9rem; margin: 0 auto; transform-style: preserve-3d; transform: perspective(1000px); animation: carousel 20s linear infinite; > * { position: absolute; inset: 0; transform: rotateY( calc((var(--position) - 1) * (360 / var(--quantity)) * 1deg) ) translateZ(var(--z)); > * { width: 100%; height: 100%; border-radius: 0.675rem; object-fit: cover; background-image: linear-gradient(in oklch to left, #fbbf24, #f97316, #dc2626); /* Fondo de ejemplo */ } } }}
@keyframes carousel { from { transform: perspective(1000px) rotateY(0deg); } to { transform: perspective(1000px) rotateY(360deg); }}
Desglose técnico
1. Contenido del slider
Lo que coloques dentro de <div style="--position: 1"> <div></div> </div>
es el elemento que se moverá.
Por defecto, he puesto un <div></div>
vacío, pero es probable que prefieras usar un <img/>
para mostrar imágenes.
quantity
es el número de elementos que se moverán, así que asegúrate de que este valor coincida con la cantidad de elementos dentro del selector.position
es el número de cada elemento dentro del slider, que determinará su lugar en el círculo (o más bien, en la animación).
2. Modifica los valores
El valor de --z
controla la profundidad en el eje Z, o la distancia entre los elementos en el carrusel. Este valor se aplica a la propiedad translateZ
, lo cual hace que los elementos se separen en un espacio tridimensional. Si aumentas el valor de --z
, los elementos estarán más separados, mientras que, al disminuirlo, se acercarán entre sí.
igualmente puedes modificar los valores de
height
ywidth
pero, supongo que eso ya lo sabes.
3. transform
y rotateY
La parte más rara es rotateY
, que tiene la fórmula rotateY(calc((var(--position) - 1) * (360 / var(--quantity)) * 1deg))
. Básicamente, esta línea hace que cada elemento gire para colocarse en su posición correcta.
La fórmula es la siguiente:
(posición - 1) * (360° / cantidad)
Entonces, si lo aplicamos a un objeto, se vería así:
> * { transform: rotateY(calc( (var(--position) - 1) * (360 / var(--quantity)) ));}
4. ¿Por qué calc()
y var()
?
calc()
se usa para hacer cálculos matemáticos directamente en CSS.var()
permite acceder a las variables personalizadas que hemos definido (en este caso,--position
y--quantity
).
Si solo usamos eso, no funcionará porque no estamos especificando la unidad de medida correcta. Necesitamos trabajar con grados, así que añadimos * 1deg
para convertir el resultado en grados, sin cambiar su valor. Así:
> * { transform: rotateY(calc( (var(--position) - 1) * (360 / var(--quantity)) * 1deg ));}
Fin.