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>
相关推荐
VT.馒头9 分钟前
【力扣】2695. 包装数组
前端·javascript·算法·leetcode·职场和发展·typescript
css趣多多21 分钟前
一个UI内置组件el-scrollbar
前端·javascript·vue.js
C澒41 分钟前
前端整洁架构(Clean Architecture)实战解析:从理论到 Todo 项目落地
前端·架构·系统架构·前端框架
C澒1 小时前
Remesh 框架详解:基于 CQRS 的前端领域驱动设计方案
前端·架构·前端框架·状态模式
Charlie_lll1 小时前
学习Three.js–雪花
前端·three.js
onebyte8bits1 小时前
前端国际化(i18n)体系设计与工程化落地
前端·国际化·i18n·工程化
C澒1 小时前
前端分层架构实战:DDD 与 Clean Architecture 在大型业务系统中的落地路径与项目实践
前端·架构·系统架构·前端框架
BestSongC1 小时前
行人摔倒检测系统 - 前端文档(1)
前端·人工智能·目标检测
0思必得02 小时前
[Web自动化] Selenium处理滚动条
前端·爬虫·python·selenium·自动化
Misnice2 小时前
Webpack、Vite、Rsbuild区别
前端·webpack·node.js