9 CSS 3D Designs08 / 09

CSS + JSMIT licensed

Neon Lattice

A 5×5 matrix of genuine CSS 3D cubes, each with six correctly positioned faces using translateZ and rotateY, spinning at randomized axes and speeds. Rows pulse in distinct neon bands — cyan, magenta, lime, amber, rose — with glowing top caps that throw colored drop-shadows down through the lattice. A scrolling grid background and slow scanline reinforce the cyberpunk readout feel, and full mouse-tilt parallax rotates the entire matrix in 3D space. Pure transforms, no WebGL. Best for tech dashboards, cyberpunk loading screens, interactive brand heros, sci-fi product launches.

Published

Live Demo
Try it

The code

<section class="cd-nln" aria-label="Neon Lattice 3D cube matrix demo">
  <div class="card">
    <div class="cd-nln-grid" aria-hidden="true"></div>
    <div class="cd-nln-vignette" aria-hidden="true"></div>
    <div class="cd-nln-scanline" aria-hidden="true"></div>

    <div class="matrix" data-cd-nln-matrix aria-hidden="true"></div>
  </div>
</section>
/* ─── 02 Neon Lattice — 5×5 spinning cube matrix ──────────── */

.cd-nln {
  --cd-nln-bg: #010208;
  position: relative;
  width: 100%;
  height: 560px;
  background: var(--cd-nln-bg);
  overflow: hidden;
  perspective: 1200px;
  box-sizing: border-box;
}

.cd-nln *,
.cd-nln *::before,
.cd-nln *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.cd-nln .card {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.cd-nln .cd-nln-grid {
  position: absolute;
  inset: 0;
  background-image: linear-gradient(rgba(0,220,255,0.035) 1px, transparent 1px), linear-gradient(90deg, rgba(0,220,255,0.035) 1px, transparent 1px);
  background-size: 42px 42px;
  animation: cd-nln-grid-shift 30s linear infinite;
  pointer-events: none;
}

@keyframes cd-nln-grid-shift {
  from {
    background-position: 0 0;
  }

  to {
    background-position: 42px 42px;
  }
}

.cd-nln .cd-nln-vignette {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 75% 75% at 50% 50%, transparent 35%, rgba(1,2,8,0.94) 100%);
  pointer-events: none;
}

.cd-nln .cd-nln-scanline {
  position: absolute;
  left: 0;
  right: 0;
  height: 2px;
  background: rgba(0, 220, 255, 0.06);
  animation: cd-nln-scan 6s linear infinite;
  pointer-events: none;
}

@keyframes cd-nln-scan {
  from {
    top: -2px;
  }

  to {
    top: 100%;
  }
}
/* Matrix */

.cd-nln .matrix {
  display: grid;
  grid-template-columns: repeat(5, 72px);
  grid-template-rows: repeat(5, 72px);
  gap: 22px;
  transform-style: preserve-3d;
  transform: rotateX(22deg) rotateY(-18deg);
  transition: transform 0.5s cubic-bezier(0.23, 1, 0.32, 1);
  position: relative;
  z-index: 1;
}

.cd-nln .cube-wrap {
  width: 72px;
  height: 72px;
  perspective: 600px;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: cd-nln-glow-pulse var(--gp, 3s) ease-in-out infinite var(--gpd, 0s);
}

@keyframes cd-nln-glow-pulse {
  0%,
    100% {
    opacity: 0.85;
  }

  50% {
    opacity: 1;
  }
}

.cd-nln .cube {
  width: 52px;
  height: 52px;
  position: relative;
  transform-style: preserve-3d;
  animation: cd-nln-spin var(--sd) linear infinite var(--dl);
}

.cd-nln .f {
  position: absolute;
  width: 52px;
  height: 52px;
  border: 1px solid rgba(255,255,255,0.04);
  backface-visibility: visible;
}

.cd-nln .f-front {
  transform: translateZ(26px);
}

.cd-nln .f-back {
  transform: translateZ(-26px) rotateY(180deg);
}

.cd-nln .f-left {
  transform: translateX(-26px) rotateY(-90deg);
}

.cd-nln .f-right {
  transform: translateX(26px) rotateY(90deg);
}

.cd-nln .f-top {
  transform: translateY(-26px) rotateX(90deg);
}

.cd-nln .f-bottom {
  transform: translateY(26px) rotateX(-90deg);
}
/* Row 1 — Cyan */

.cd-nln .cube-wrap:nth-child(-n+5) .f-front {
  background: rgba(0,18,38,0.95);
}

.cd-nln .cube-wrap:nth-child(-n+5) .f-back {
  background: rgba(0,12,28,0.95);
}

.cd-nln .cube-wrap:nth-child(-n+5) .f-left {
  background: rgba(0,10,24,0.92);
}

.cd-nln .cube-wrap:nth-child(-n+5) .f-right {
  background: rgba(0,14,30,0.92);
}

.cd-nln .cube-wrap:nth-child(-n+5) .f-bottom {
  background: rgba(0,8,20,0.95);
}

.cd-nln .cube-wrap:nth-child(-n+5) .f-top {
  background: #00e8ff;
  box-shadow: 0 0 18px #00e8ff, 0 0 40px rgba(0,232,255,0.5);
}

.cd-nln .cube-wrap:nth-child(-n+5) {
  filter: drop-shadow(0 0 8px rgba(0,232,255,0.35));
}
/* Row 2 — Magenta */

.cd-nln .cube-wrap:nth-child(n+6):nth-child(-n+10) .f-front {
  background: rgba(28,0,38,0.95);
}

.cd-nln .cube-wrap:nth-child(n+6):nth-child(-n+10) .f-back {
  background: rgba(20,0,28,0.95);
}

.cd-nln .cube-wrap:nth-child(n+6):nth-child(-n+10) .f-left {
  background: rgba(16,0,24,0.92);
}

.cd-nln .cube-wrap:nth-child(n+6):nth-child(-n+10) .f-right {
  background: rgba(22,0,32,0.92);
}

.cd-nln .cube-wrap:nth-child(n+6):nth-child(-n+10) .f-bottom {
  background: rgba(12,0,18,0.95);
}

.cd-nln .cube-wrap:nth-child(n+6):nth-child(-n+10) .f-top {
  background: #ff00ff;
  box-shadow: 0 0 18px #ff00ff, 0 0 40px rgba(255,0,255,0.5);
}

.cd-nln .cube-wrap:nth-child(n+6):nth-child(-n+10) {
  filter: drop-shadow(0 0 8px rgba(255,0,255,0.35));
}
/* Row 3 — Lime */

.cd-nln .cube-wrap:nth-child(n+11):nth-child(-n+15) .f-front {
  background: rgba(0,22,8,0.95);
}

.cd-nln .cube-wrap:nth-child(n+11):nth-child(-n+15) .f-back {
  background: rgba(0,15,5,0.95);
}

.cd-nln .cube-wrap:nth-child(n+11):nth-child(-n+15) .f-left {
  background: rgba(0,12,4,0.92);
}

.cd-nln .cube-wrap:nth-child(n+11):nth-child(-n+15) .f-right {
  background: rgba(0,18,6,0.92);
}

.cd-nln .cube-wrap:nth-child(n+11):nth-child(-n+15) .f-bottom {
  background: rgba(0,10,3,0.95);
}

.cd-nln .cube-wrap:nth-child(n+11):nth-child(-n+15) .f-top {
  background: #00ff66;
  box-shadow: 0 0 18px #00ff66, 0 0 40px rgba(0,255,102,0.5);
}

.cd-nln .cube-wrap:nth-child(n+11):nth-child(-n+15) {
  filter: drop-shadow(0 0 8px rgba(0,255,102,0.35));
}
/* Row 4 — Amber */

.cd-nln .cube-wrap:nth-child(n+16):nth-child(-n+20) .f-front {
  background: rgba(30,14,0,0.95);
}

.cd-nln .cube-wrap:nth-child(n+16):nth-child(-n+20) .f-back {
  background: rgba(22,10,0,0.95);
}

.cd-nln .cube-wrap:nth-child(n+16):nth-child(-n+20) .f-left {
  background: rgba(18,8,0,0.92);
}

.cd-nln .cube-wrap:nth-child(n+16):nth-child(-n+20) .f-right {
  background: rgba(24,12,0,0.92);
}

.cd-nln .cube-wrap:nth-child(n+16):nth-child(-n+20) .f-bottom {
  background: rgba(14,6,0,0.95);
}

.cd-nln .cube-wrap:nth-child(n+16):nth-child(-n+20) .f-top {
  background: #ffcc00;
  box-shadow: 0 0 18px #ffcc00, 0 0 40px rgba(255,204,0,0.5);
}

.cd-nln .cube-wrap:nth-child(n+16):nth-child(-n+20) {
  filter: drop-shadow(0 0 8px rgba(255,204,0,0.35));
}
/* Row 5 — Rose */

.cd-nln .cube-wrap:nth-child(n+21) .f-front {
  background: rgba(32,0,12,0.95);
}

.cd-nln .cube-wrap:nth-child(n+21) .f-back {
  background: rgba(22,0,8,0.95);
}

.cd-nln .cube-wrap:nth-child(n+21) .f-left {
  background: rgba(18,0,6,0.92);
}

.cd-nln .cube-wrap:nth-child(n+21) .f-right {
  background: rgba(26,0,10,0.92);
}

.cd-nln .cube-wrap:nth-child(n+21) .f-bottom {
  background: rgba(12,0,4,0.95);
}

.cd-nln .cube-wrap:nth-child(n+21) .f-top {
  background: #ff3080;
  box-shadow: 0 0 18px #ff3080, 0 0 40px rgba(255,48,128,0.5);
}

.cd-nln .cube-wrap:nth-child(n+21) {
  filter: drop-shadow(0 0 8px rgba(255,48,128,0.35));
}

@keyframes cd-nln-spin {
  from {
    transform: rotateX(var(--rx-start,0deg)) rotateY(var(--ry-start,0deg)) rotateZ(0deg);
  }

  to {
    transform: rotateX(var(--rx-end,360deg)) rotateY(var(--ry-end,360deg)) rotateZ(var(--rz-end,0deg));
  }
}

@media (max-width: 720px) {
  .cd-nln .matrix {
    grid-template-columns: repeat(5, 52px);
    grid-template-rows: repeat(5, 52px);
    gap: 16px;
  }

  .cd-nln .cube-wrap {
    width: 52px;
    height: 52px;
  }

  .cd-nln .cube,
    .cd-nln .f {
    width: 40px;
    height: 40px;
  }

  .cd-nln .f-front {
    transform: translateZ(20px);
  }

  .cd-nln .f-back {
    transform: translateZ(-20px) rotateY(180deg);
  }

  .cd-nln .f-left {
    transform: translateX(-20px) rotateY(-90deg);
  }

  .cd-nln .f-right {
    transform: translateX(20px) rotateY(90deg);
  }

  .cd-nln .f-top {
    transform: translateY(-20px) rotateX(90deg);
  }

  .cd-nln .f-bottom {
    transform: translateY(20px) rotateX(-90deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .cd-nln .cd-nln-grid,
    .cd-nln .cd-nln-scanline,
    .cd-nln .cube-wrap,
    .cd-nln .cube {
    animation: none !important;
  }
}
(() => {
  const root = document.querySelector('.cd-nln');
  if (!root) return;
  const matrix = root.querySelector('[data-cd-nln-matrix]');
  if (!matrix) return;

  // Build cubes
  const axes = [
    [360, 360, 0], [360, 0, 0], [0, 360, 0],
    [0, 0, 360], [360, 360, 360], [-360, 360, 0], [360, -360, 0],
  ];
  for (let i = 0; i < 25; i++) {
    const ax = axes[Math.floor(Math.random() * axes.length)];
    const sd = (Math.random() * 8 + 3).toFixed(1) + 's';
    const dl = (-Math.random() * 12).toFixed(2) + 's';
    const gp = (Math.random() * 3 + 2).toFixed(1) + 's';
    const gpd = (-Math.random() * 5).toFixed(2) + 's';
    const rxStart = Math.random() * 360;
    const ryStart = Math.random() * 360;

    const wrap = document.createElement('div');
    wrap.className = 'cube-wrap';
    wrap.style.cssText = `--gp:${gp}; --gpd:${gpd};`;

    const cube = document.createElement('div');
    cube.className = 'cube';
    cube.style.cssText = `
      --sd:${sd}; --dl:${dl};
      --rx-start:${rxStart}deg; --ry-start:${ryStart}deg;
      --rx-end:${rxStart + ax[0]}deg; --ry-end:${ryStart + ax[1]}deg; --rz-end:${ax[2]}deg;
    `;

    cube.innerHTML = '<div class="f f-front"></div><div class="f f-back"></div><div class="f f-left"></div><div class="f f-right"></div><div class="f f-top"></div><div class="f f-bottom"></div>';

    wrap.appendChild(cube);
    matrix.appendChild(wrap);
  }

  // Mouse parallax scoped to wrapper
  const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  if (prefersReduced) return;

  let tx = 22, ty = -18, cx = 22, cy = -18, rafId = null;

  root.addEventListener('mousemove', e => {
    const rect = root.getBoundingClientRect();
    tx = 22 + ((e.clientY - rect.top) / rect.height - 0.5) * 25;
    ty = -18 + ((e.clientX - rect.left) / rect.width - 0.5) * 30;
    if (!rafId) rafId = requestAnimationFrame(animate);
  });
  root.addEventListener('mouseleave', () => { tx = 22; ty = -18; });

  function animate() {
    cx += (tx - cx) * 0.055;
    cy += (ty - cy) * 0.055;
    matrix.style.transform = `rotateX(${cx}deg) rotateY(${cy}deg)`;
    if (Math.abs(tx - cx) > 0.05 || Math.abs(ty - cy) > 0.05) {
      rafId = requestAnimationFrame(animate);
    } else {
      rafId = null;
    }
  }
})();
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS 3D Design from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Neon Lattice
Source: https://codefronts.com/design-styles/css-3d/neon-lattice/

A 5×5 matrix of genuine CSS 3D cubes, each with six correctly positioned faces using translateZ and rotateY, spinning at randomized axes and speeds. Rows pulse in distinct neon bands — cyan, magenta, lime, amber, rose — with glowing top caps that throw colored drop-shadows down through the lattice. A scrolling grid background and slow scanline reinforce the cyberpunk readout feel, and full mouse-tilt parallax rotates the entire matrix in 3D space. Pure transforms, no WebGL. Best for tech dashboards, cyberpunk loading screens, interactive brand heros, sci-fi product launches.
## HTML
```html
<section class="cd-nln" aria-label="Neon Lattice 3D cube matrix demo">
  <div class="card">
    <div class="cd-nln-grid" aria-hidden="true"></div>
    <div class="cd-nln-vignette" aria-hidden="true"></div>
    <div class="cd-nln-scanline" aria-hidden="true"></div>

    <div class="matrix" data-cd-nln-matrix aria-hidden="true"></div>
  </div>
</section>
```
## CSS
```css
/* ─── 02 Neon Lattice — 5×5 spinning cube matrix ──────────── */

.cd-nln {
  --cd-nln-bg: #010208;
  position: relative;
  width: 100%;
  height: 560px;
  background: var(--cd-nln-bg);
  overflow: hidden;
  perspective: 1200px;
  box-sizing: border-box;
}

.cd-nln *,
.cd-nln *::before,
.cd-nln *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.cd-nln .card {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.cd-nln .cd-nln-grid {
  position: absolute;
  inset: 0;
  background-image: linear-gradient(rgba(0,220,255,0.035) 1px, transparent 1px), linear-gradient(90deg, rgba(0,220,255,0.035) 1px, transparent 1px);
  background-size: 42px 42px;
  animation: cd-nln-grid-shift 30s linear infinite;
  pointer-events: none;
}

@keyframes cd-nln-grid-shift {
  from {
    background-position: 0 0;
  }

  to {
    background-position: 42px 42px;
  }
}

.cd-nln .cd-nln-vignette {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 75% 75% at 50% 50%, transparent 35%, rgba(1,2,8,0.94) 100%);
  pointer-events: none;
}

.cd-nln .cd-nln-scanline {
  position: absolute;
  left: 0;
  right: 0;
  height: 2px;
  background: rgba(0, 220, 255, 0.06);
  animation: cd-nln-scan 6s linear infinite;
  pointer-events: none;
}

@keyframes cd-nln-scan {
  from {
    top: -2px;
  }

  to {
    top: 100%;
  }
}
/* Matrix */

.cd-nln .matrix {
  display: grid;
  grid-template-columns: repeat(5, 72px);
  grid-template-rows: repeat(5, 72px);
  gap: 22px;
  transform-style: preserve-3d;
  transform: rotateX(22deg) rotateY(-18deg);
  transition: transform 0.5s cubic-bezier(0.23, 1, 0.32, 1);
  position: relative;
  z-index: 1;
}

.cd-nln .cube-wrap {
  width: 72px;
  height: 72px;
  perspective: 600px;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: cd-nln-glow-pulse var(--gp, 3s) ease-in-out infinite var(--gpd, 0s);
}

@keyframes cd-nln-glow-pulse {
  0%,
    100% {
    opacity: 0.85;
  }

  50% {
    opacity: 1;
  }
}

.cd-nln .cube {
  width: 52px;
  height: 52px;
  position: relative;
  transform-style: preserve-3d;
  animation: cd-nln-spin var(--sd) linear infinite var(--dl);
}

.cd-nln .f {
  position: absolute;
  width: 52px;
  height: 52px;
  border: 1px solid rgba(255,255,255,0.04);
  backface-visibility: visible;
}

.cd-nln .f-front {
  transform: translateZ(26px);
}

.cd-nln .f-back {
  transform: translateZ(-26px) rotateY(180deg);
}

.cd-nln .f-left {
  transform: translateX(-26px) rotateY(-90deg);
}

.cd-nln .f-right {
  transform: translateX(26px) rotateY(90deg);
}

.cd-nln .f-top {
  transform: translateY(-26px) rotateX(90deg);
}

.cd-nln .f-bottom {
  transform: translateY(26px) rotateX(-90deg);
}
/* Row 1 — Cyan */

.cd-nln .cube-wrap:nth-child(-n+5) .f-front {
  background: rgba(0,18,38,0.95);
}

.cd-nln .cube-wrap:nth-child(-n+5) .f-back {
  background: rgba(0,12,28,0.95);
}

.cd-nln .cube-wrap:nth-child(-n+5) .f-left {
  background: rgba(0,10,24,0.92);
}

.cd-nln .cube-wrap:nth-child(-n+5) .f-right {
  background: rgba(0,14,30,0.92);
}

.cd-nln .cube-wrap:nth-child(-n+5) .f-bottom {
  background: rgba(0,8,20,0.95);
}

.cd-nln .cube-wrap:nth-child(-n+5) .f-top {
  background: #00e8ff;
  box-shadow: 0 0 18px #00e8ff, 0 0 40px rgba(0,232,255,0.5);
}

.cd-nln .cube-wrap:nth-child(-n+5) {
  filter: drop-shadow(0 0 8px rgba(0,232,255,0.35));
}
/* Row 2 — Magenta */

.cd-nln .cube-wrap:nth-child(n+6):nth-child(-n+10) .f-front {
  background: rgba(28,0,38,0.95);
}

.cd-nln .cube-wrap:nth-child(n+6):nth-child(-n+10) .f-back {
  background: rgba(20,0,28,0.95);
}

.cd-nln .cube-wrap:nth-child(n+6):nth-child(-n+10) .f-left {
  background: rgba(16,0,24,0.92);
}

.cd-nln .cube-wrap:nth-child(n+6):nth-child(-n+10) .f-right {
  background: rgba(22,0,32,0.92);
}

.cd-nln .cube-wrap:nth-child(n+6):nth-child(-n+10) .f-bottom {
  background: rgba(12,0,18,0.95);
}

.cd-nln .cube-wrap:nth-child(n+6):nth-child(-n+10) .f-top {
  background: #ff00ff;
  box-shadow: 0 0 18px #ff00ff, 0 0 40px rgba(255,0,255,0.5);
}

.cd-nln .cube-wrap:nth-child(n+6):nth-child(-n+10) {
  filter: drop-shadow(0 0 8px rgba(255,0,255,0.35));
}
/* Row 3 — Lime */

.cd-nln .cube-wrap:nth-child(n+11):nth-child(-n+15) .f-front {
  background: rgba(0,22,8,0.95);
}

.cd-nln .cube-wrap:nth-child(n+11):nth-child(-n+15) .f-back {
  background: rgba(0,15,5,0.95);
}

.cd-nln .cube-wrap:nth-child(n+11):nth-child(-n+15) .f-left {
  background: rgba(0,12,4,0.92);
}

.cd-nln .cube-wrap:nth-child(n+11):nth-child(-n+15) .f-right {
  background: rgba(0,18,6,0.92);
}

.cd-nln .cube-wrap:nth-child(n+11):nth-child(-n+15) .f-bottom {
  background: rgba(0,10,3,0.95);
}

.cd-nln .cube-wrap:nth-child(n+11):nth-child(-n+15) .f-top {
  background: #00ff66;
  box-shadow: 0 0 18px #00ff66, 0 0 40px rgba(0,255,102,0.5);
}

.cd-nln .cube-wrap:nth-child(n+11):nth-child(-n+15) {
  filter: drop-shadow(0 0 8px rgba(0,255,102,0.35));
}
/* Row 4 — Amber */

.cd-nln .cube-wrap:nth-child(n+16):nth-child(-n+20) .f-front {
  background: rgba(30,14,0,0.95);
}

.cd-nln .cube-wrap:nth-child(n+16):nth-child(-n+20) .f-back {
  background: rgba(22,10,0,0.95);
}

.cd-nln .cube-wrap:nth-child(n+16):nth-child(-n+20) .f-left {
  background: rgba(18,8,0,0.92);
}

.cd-nln .cube-wrap:nth-child(n+16):nth-child(-n+20) .f-right {
  background: rgba(24,12,0,0.92);
}

.cd-nln .cube-wrap:nth-child(n+16):nth-child(-n+20) .f-bottom {
  background: rgba(14,6,0,0.95);
}

.cd-nln .cube-wrap:nth-child(n+16):nth-child(-n+20) .f-top {
  background: #ffcc00;
  box-shadow: 0 0 18px #ffcc00, 0 0 40px rgba(255,204,0,0.5);
}

.cd-nln .cube-wrap:nth-child(n+16):nth-child(-n+20) {
  filter: drop-shadow(0 0 8px rgba(255,204,0,0.35));
}
/* Row 5 — Rose */

.cd-nln .cube-wrap:nth-child(n+21) .f-front {
  background: rgba(32,0,12,0.95);
}

.cd-nln .cube-wrap:nth-child(n+21) .f-back {
  background: rgba(22,0,8,0.95);
}

.cd-nln .cube-wrap:nth-child(n+21) .f-left {
  background: rgba(18,0,6,0.92);
}

.cd-nln .cube-wrap:nth-child(n+21) .f-right {
  background: rgba(26,0,10,0.92);
}

.cd-nln .cube-wrap:nth-child(n+21) .f-bottom {
  background: rgba(12,0,4,0.95);
}

.cd-nln .cube-wrap:nth-child(n+21) .f-top {
  background: #ff3080;
  box-shadow: 0 0 18px #ff3080, 0 0 40px rgba(255,48,128,0.5);
}

.cd-nln .cube-wrap:nth-child(n+21) {
  filter: drop-shadow(0 0 8px rgba(255,48,128,0.35));
}

@keyframes cd-nln-spin {
  from {
    transform: rotateX(var(--rx-start,0deg)) rotateY(var(--ry-start,0deg)) rotateZ(0deg);
  }

  to {
    transform: rotateX(var(--rx-end,360deg)) rotateY(var(--ry-end,360deg)) rotateZ(var(--rz-end,0deg));
  }
}

@media (max-width: 720px) {
  .cd-nln .matrix {
    grid-template-columns: repeat(5, 52px);
    grid-template-rows: repeat(5, 52px);
    gap: 16px;
  }

  .cd-nln .cube-wrap {
    width: 52px;
    height: 52px;
  }

  .cd-nln .cube,
    .cd-nln .f {
    width: 40px;
    height: 40px;
  }

  .cd-nln .f-front {
    transform: translateZ(20px);
  }

  .cd-nln .f-back {
    transform: translateZ(-20px) rotateY(180deg);
  }

  .cd-nln .f-left {
    transform: translateX(-20px) rotateY(-90deg);
  }

  .cd-nln .f-right {
    transform: translateX(20px) rotateY(90deg);
  }

  .cd-nln .f-top {
    transform: translateY(-20px) rotateX(90deg);
  }

  .cd-nln .f-bottom {
    transform: translateY(20px) rotateX(-90deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .cd-nln .cd-nln-grid,
    .cd-nln .cd-nln-scanline,
    .cd-nln .cube-wrap,
    .cd-nln .cube {
    animation: none !important;
  }
}
```

## JavaScript
```js
(() => {
  const root = document.querySelector('.cd-nln');
  if (!root) return;
  const matrix = root.querySelector('[data-cd-nln-matrix]');
  if (!matrix) return;

  // Build cubes
  const axes = [
    [360, 360, 0], [360, 0, 0], [0, 360, 0],
    [0, 0, 360], [360, 360, 360], [-360, 360, 0], [360, -360, 0],
  ];
  for (let i = 0; i < 25; i++) {
    const ax = axes[Math.floor(Math.random() * axes.length)];
    const sd = (Math.random() * 8 + 3).toFixed(1) + 's';
    const dl = (-Math.random() * 12).toFixed(2) + 's';
    const gp = (Math.random() * 3 + 2).toFixed(1) + 's';
    const gpd = (-Math.random() * 5).toFixed(2) + 's';
    const rxStart = Math.random() * 360;
    const ryStart = Math.random() * 360;

    const wrap = document.createElement('div');
    wrap.className = 'cube-wrap';
    wrap.style.cssText = `--gp:${gp}; --gpd:${gpd};`;

    const cube = document.createElement('div');
    cube.className = 'cube';
    cube.style.cssText = `
      --sd:${sd}; --dl:${dl};
      --rx-start:${rxStart}deg; --ry-start:${ryStart}deg;
      --rx-end:${rxStart + ax[0]}deg; --ry-end:${ryStart + ax[1]}deg; --rz-end:${ax[2]}deg;
    `;

    cube.innerHTML = '<div class="f f-front"></div><div class="f f-back"></div><div class="f f-left"></div><div class="f f-right"></div><div class="f f-top"></div><div class="f f-bottom"></div>';

    wrap.appendChild(cube);
    matrix.appendChild(wrap);
  }

  // Mouse parallax scoped to wrapper
  const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  if (prefersReduced) return;

  let tx = 22, ty = -18, cx = 22, cy = -18, rafId = null;

  root.addEventListener('mousemove', e => {
    const rect = root.getBoundingClientRect();
    tx = 22 + ((e.clientY - rect.top) / rect.height - 0.5) * 25;
    ty = -18 + ((e.clientX - rect.left) / rect.width - 0.5) * 30;
    if (!rafId) rafId = requestAnimationFrame(animate);
  });
  root.addEventListener('mouseleave', () => { tx = 22; ty = -18; });

  function animate() {
    cx += (tx - cx) * 0.055;
    cy += (ty - cy) * 0.055;
    matrix.style.transform = `rotateX(${cx}deg) rotateY(${cy}deg)`;
    if (Math.abs(tx - cx) > 0.05 || Math.abs(ty - cy) > 0.05) {
      rafId = requestAnimationFrame(animate);
    } else {
      rafId = null;
    }
  }
})();
```

Techniques used in this demo

Search CodeFronts

Loading…