搞3D图片轮播,纯CSS就能转得飞起。从基础布局到旋转动画,再到立方体乱翻,一套HTML代码通吃。这里拆解水平旋转、垂直切换、立方体翻滚三种玩法,手把手看代码怎么动起来。
基础堆叠
先把图片叠成一摞。HTML结构就一个容器加一堆img标签,数量随便。
<div class="gallery">
<img src="img1.jpg" alt="">
<img src="img2.jpg" alt="">
<img src="img3.jpg" alt="">
<img src="img4.jpg" alt="">
<img src="img5.jpg" alt="">
<img src="img6.jpg" alt="">
</div>CSS网格把每张图塞进同一个格子,后盖前。
.gallery {
display: grid;
}
.gallery > img {
grid-area: 1 / 1;
width: 160px;
aspect-ratio: 1;
object-fit: cover;
}这一步就像把六张照片摞在桌面,完全看不见下层。接下来要掰开它们,摆成3D形状。
水平3D旋转
核心思路:每张图绕着中心转圈,再往前推,最后集体转起来。先上Sass循环,自动算位置。
$n: 6; // 图片数量
@for $i from 1 to ($n + 1) {
.gallery > img:nth-child(#{$i}) {
transform:
rotate(#{360 * ($i - 1) / $n}deg)
translateY(50% / tan(180deg / $n))
rotateX(90deg);
}
}解释一下这三步:
rotate:把图片摊成圆形,每张转不同角度。比如6张图,每张差60度。translateY:把图片往外推。距离公式50% / tan(180deg/N)保证边缘刚好碰一起。这就像六个人手拉手围成圈,每人退一步才能拉成圆。rotateX(90deg):把平躺的圆立起来。原本图片朝上,转90度后变成朝侧面,围成柱状。
推完所有图片后,整个容器要旋转起来才能看到每张图。动画抄之前圆形轮播的帧数逻辑。
.gallery {
transform-style: preserve-3d;
--_t: perspective(280px) rotateX(-90deg);
animation: r 12s cubic-bezier(.5, -0.2, .5, 1.2) infinite;
}
@keyframes r {
0%, 3% { transform: var(--_t) rotate(0deg); }
14.7%, 19.7% { transform: var(--_t) rotate(-60deg); }
31.3%, 36.3% { transform: var(--_t) rotate(-120deg); }
48%, 53% { transform: var(--_t) rotate(-180deg); }
64.7%, 69.7% { transform: var(--_t) rotate(-240deg); }
81.3%, 86.3% { transform: var(--_t) rotate(-300deg); }
98%, 100% { transform: var(--_t) rotate(-360deg); }
}这里的百分比是按6张图算的:每张停留约11%,中间用2%缓冲过渡。rotateX(-90deg) 是为了让视角从上方俯瞰,perspective 给深度感。跑起来就像旋转木马,每张图轮流停在面前。
写代码时容易翻车的地方:忘记 transform-style: preserve-3d 会导致子元素的3D变换被压扁。还有 translateY 的数值如果写死,换不同数量图片时边缘会错位,用Sass自动算就能避免。
垂直3D旋转
想换个方向转?把 rotate 改成 rotateX 就行。水平版本绕Z轴转,垂直版本绕X轴转。
@for $i from 1 to ($n + 1) {
.gallery > img:nth-child(#{$i}) {
transform:
rotateX(#{360 * ($i - 1) / $n}deg)
translateY(50% / tan(180deg / $n))
rotateX(90deg);
}
}关键帧里的 rotate 也换成 rotateX。
@keyframes r {
0%, 3% { transform: var(--_t) rotateX(0deg); }
14.7%, 19.7% { transform: var(--_t) rotateX(-60deg); }
/* 后面同理... */
98%, 100% { transform: var(--_t) rotateX(-360deg); }
}效果变成图片像风车一样上下翻滚。有个小坑:rotateX 旋转超过90度后图片会面向背面,需要确保每张图的初始角度能兜住整个圆。
立方体滑块
想要真正的六面体?固定6张图,每张贴一个面。这里不用Sass,直接手写每张图的位置。
.gallery {
--s: 250px;
transform-style: preserve-3d;
--_p: perspective(calc(2.5 * var(--s)));
animation: r 9s infinite cubic-bezier(.5, -0.5, .5, 1.5);
}
.gallery img {
grid-area: 1 / 1;
width: var(--s);
aspect-ratio: 1;
object-fit: cover;
transform: var(--_t,) translateZ(calc(var(--s) / 2));
}
.gallery img:nth-child(2) { --_t: rotateX(-90deg); }
.gallery img:nth-child(3) { --_t: rotateY(90deg) rotate(-90deg); }
.gallery img:nth-child(4) { --_t: rotateX(180deg) rotate(90deg); }
.gallery img:nth-child(5) { --_t: rotateX(90deg) rotate(90deg); }
.gallery img:nth-child(6) { --_t: rotateY(-90deg); }第一张图只有平移,其他每张先旋转到对应面,再平移到中心。比如第二张 rotateX(-90deg) 就贴到顶面。那个逗号 var(--_t,) 不是笔误——当 --_t 没定义时,逗号让属性回退到空值,避免整行失效。
关键帧依次翻转各个面:
@keyframes r {
0%, 3% { transform: var(--_p); }
14%, 19% { transform: var(--_p) rotateX(90deg); }
31%, 36% { transform: var(--_p) rotateX(90deg) rotateZ(90deg); }
47%, 52% { transform: var(--_p) rotateX(90deg) rotateZ(90deg) rotateY(-90deg); }
64%, 69% { transform: var(--_p) rotateX(90deg) rotateZ(90deg) rotateY(-90deg) rotateX(90deg); }
81%, 86% { transform: var(--_p) rotateX(90deg) rotateZ(90deg) rotateY(-90deg) rotateX(90deg) rotateZ(90deg); }
97%, 100%{ transform: var(--_p) rotateX(90deg) rotateZ(90deg) rotateY(-90deg) rotateX(90deg) rotateZ(90deg) rotateY(-90deg); }
}每一步叠加一个新旋转,六个状态刚好转完一圈。调试时可以打开浏览器开发者工具,挨个改旋转值,盯着屏幕看到贴正为止。虽然笨,但比硬算角度快得多。
随机乱转立方体
不想按顺序转?那就假装随机。关键帧里每个阶段直接跳到想要展示的那一面,中间过渡用 rotate3d 瞎转。
@keyframes r {
0%, 3% { transform: var(--_p) rotate3d( 0, 0, 0, 0deg); }
14%,19% { transform: var(--_p) rotate3d(-1, 1, 0, 180deg); }
31%,36% { transform: var(--_p) rotate3d( 0,-1, 0, 90deg); }
47%,52% { transform: var(--_p) rotate3d( 1, 0, 0, 90deg); }
64%,69% { transform: var(--_p) rotate3d( 1, 0, 0, -90deg); }
81%,86% { transform: var(--_p) rotate3d( 0, 1, 0, 90deg); }
97%,100% { transform: var(--_p) rotate3d( 0, 0, 0, 0deg); }
}rotate3d(x, y, z, deg) 可以绕着任意轴转。这几个值不需要有数学规律,全凭手感在开发者工具里扭。只要保证开头和结尾都是第一张图,中间每段露出不同面就行。比如第二段转到背面,第三段突然翻到右侧面,看起来就像骰子在桌上乱滚。
操作时一个小技巧:把动画时长调慢到20秒,一边改一边预览,找到满意的组合就记下来。最终效果比规规矩矩的旋转更有趣味。
