3D魔方-Css实现方法

效果:

实现思路:

  1. 在根节点定义尺寸与配色等CSS变量(w、gap、allW、c1...bg)。

  2. 创建容器结构:.container 包裹 .container-box,并将页面居中显示。

  3. 设置透视与3D:给 .container 设置 perspective;给 .container-box 开启 preserve-3d。

  4. 构建六个面:创建 .cube-side(front/back/right/left/top/bottom),每个面内添加一个 .cube-grid。

  5. 使用 box-shadow 生成 3×3 方格阵列,依据 w 与 gap 计算偏移量形成九宫格。

  6. 用 translateZ/rotateX/rotateY 将六个面定位到立方体的正确位置。

  7. 启用背面隐藏:backface-visibility: hidden,避免背面闪烁或穿透导致的视觉问题。

  8. 添加旋转动画:定义 @keyframes rotate,并在 .container-box 上应用 animation。

  9. 可通过调整变量改变魔方大小、间距与颜色主题,实现快速定制。

附代码:

html 复制代码
<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>3D魔方</title>
  <style>
    :root {
      --w: 60px;
      --gap: 10px;
      --allW: calc(3 * var(--w) + 4 * var(--gap));
      --c1: #FF0000;
      --c2: green;
      --c3: #fff;
      --c4: #97d497;
      --c5: #291a80;
      --c6: rgb(255, 0, 212);
      --bg: #0d0e0d;
    }

    * { box-sizing: border-box; }
    html, body { height: 100%; }
    body {
      margin: 0;
      display: grid;
      place-items: center;
      background: var(--bg);
      color: #fff;
      font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Noto Sans", "Apple Color Emoji", "Segoe UI Emoji";
    }

    .container {
      width: var(--allW);
      height: var(--allW);
      perspective: 900px;
    }

    .container-box {
      position: relative;
      width: var(--allW);
      height: var(--allW);
      transform-style: preserve-3d;
      animation: rotate 10s infinite alternate;
    }

    .cube-side {
      width: 100%;
      height: 100%;
      position: absolute;
      background: var(--bg);
      border-radius: 7px;
      padding: var(--gap);
      backface-visibility: hidden;
    }

    .cube-side .cube-grid {
      width: var(--w);
      height: var(--w);
      border-radius: calc(var(--w) / 5);
      color: var(--c);
      background: currentColor;
    }

    .cube-grid {
      box-shadow:
        calc(var(--w) + var(--gap)) 0 0 currentColor,
        calc(var(--w) * 2 + var(--gap) * 2) 0 currentColor,
        0 calc(var(--w) + var(--gap)) currentColor,
        calc(var(--w) + var(--gap)) calc(var(--w) + var(--gap)) currentColor,
        calc(var(--w) * 2 + var(--gap) * 2) calc(var(--w) + var(--gap)) currentColor,
        0 calc(var(--w) * 2 + var(--gap) * 2) currentColor,
        calc(var(--w) + var(--gap)) calc(var(--w) * 2 + var(--gap) * 2) currentColor,
        calc(var(--w) * 2 + var(--gap) * 2) calc(var(--w) * 2 + var(--gap) * 2) currentColor;
    }

    /* Faces positioning */
    .cube-side.side-front { transform: translateZ(calc(var(--allW) / 2)); }
    .cube-side.side-back { transform: rotateX(-180deg) translateZ(calc(var(--allW) / 2)); }
    .cube-side.side-right { transform: rotateY(90deg) translateZ(calc(var(--allW) / 2)); }
    .cube-side.side-left { transform: rotateY(-90deg) translateZ(calc(var(--allW) / 2)); }
    .cube-side.side-top { transform: rotateX(90deg) translateZ(calc(var(--allW) / 2)); }
    .cube-side.side-bottom { transform: rotateX(-90deg) translateZ(calc(var(--allW) / 2)); }

    @keyframes rotate {
      0%   { transform: rotateZ(0deg)  rotateX(0deg)   rotateY(0deg); }
      15%  { transform: rotateZ(45deg) rotateX(45deg)  rotateY(45deg); }
      30%  { transform: rotateZ(45deg) rotateX(90deg)  rotateY(90deg); }
      45%  { transform: rotateZ(45deg) rotateX(135deg) rotateY(135deg); }
      60%  { transform: rotateZ(45deg) rotateX(90deg)  rotateY(180deg); }
      75%  { transform: rotateZ(45deg) rotateX(45deg)  rotateY(225deg); }
      100% { transform: rotateZ(45deg) rotateX(0deg)   rotateY(270deg); }
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="container-box">
      <div class="cube-side side-front">
        <div class="cube-grid" style="--c: var(--c1)"></div>
      </div>
      <div class="cube-side side-back">
        <div class="cube-grid" style="--c: var(--c2)"></div>
      </div>
      <div class="cube-side side-right">
        <div class="cube-grid" style="--c: var(--c3)"></div>
      </div>
      <div class="cube-side side-left">
        <div class="cube-grid" style="--c: var(--c4)"></div>
      </div>
      <div class="cube-side side-top">
        <div class="cube-grid" style="--c: var(--c5)"></div>
      </div>
      <div class="cube-side side-bottom">
        <div class="cube-grid" style="--c: var(--c6)"></div>
      </div>
    </div>
  </div>
</body>
</html>
相关推荐
kyriewen4 小时前
Webpack vs Vite:一个是“老黄牛”,一个是“猎豹”,你选谁?
前端·webpack·vite
打小就很皮...4 小时前
html2canvas + jsPDF 生成 PDF 的踩坑与解决方案总结
前端·pdf
全栈前端老曹4 小时前
【前端地图】多地图平台适配方案——高德、百度、腾讯、Google Maps SDK 差异对比、封装统一地图接口
前端·javascript·百度·dubbo·wgs84·gcj-02·bd09
AGV算法笔记5 小时前
CVPR 2024顶级SLAM论文精读:SplaTAM如何用3D高斯实现稠密RGB-D SLAM?
深度学习·3d·机器人视觉·slam·三维重建
雾岛听风6915 小时前
JavaScript基础语法速查手册
开发语言·前端·javascript
遇见~未来5 小时前
第三篇_现代布局_从弹性到网格
前端·css3
前端那点事5 小时前
Vue前端SEO优化全攻略(实操落地版,新手也能上手)
前端·vue.js
Dxy12393102165 小时前
HTML 如何使用 SVG 画曲线
前端·算法·html
用户2367829801685 小时前
从零实现 GIF 制作工具:LZW 压缩与 Median Cut 色彩量化
前端·javascript
hahaha 1hhh5 小时前
中文乱码 ubuntu autodl
linux·运维·前端