Pure CSS Shapes & solids #loop #shape

Pyramid in pure CSS

A glass pyramid with a glowing core: triangles cut with clip-path, leaned inward by exactly the angle that makes the tips meet.

  • 73 lines of CSS
  • 7 lines of HTML
  • No JavaScript
  • No dependencies
  • MIT licensed

How it works

  1. Each side is a rectangle cut into a triangle with clip-path: polygon(50% 0, 0 100%, 100% 100%).
  2. Like a cube face: rotateY(n × 90deg) translateZ(base / 2) puts it on one side of the floor.
  3. Then rotateX with transform-origin: bottom leans it inward. The angle that makes all four tips meet is asin((base / 2) / slant): 30° when base and slant height are equal.
  4. The faces are see-through (colours with transparency), so the far faces and the glowing core inside show through. The core spins back against the pyramid (rotateY(-360deg) on the same timing), so it always faces you and stays round.

Key techniques

  • clip-path: polygon()
  • transform-origin: bottom
  • lean angle = asin((base / 2) / slant)

Copy-paste code

HTML 7 lines

<div class="scene">
  <div class="pyramid">
    <i></i><i></i><i></i><i></i>
    <b></b>
    <u></u>
  </div>
</div>

CSS 73 lines

.scene {
  perspective: 800px;
}

.pyramid {
  --base: 140px;
  position: relative;
  width: var(--base);
  height: var(--base);        /* slant height = base → lean is exactly 30deg */
  transform-style: preserve-3d;
  animation: pyramid-spin 12s linear infinite;
}

/* glass faces: see-through, so the far faces and the core show through */
.pyramid i {
  --c: #2ee6d6;
  position: absolute;
  inset: 0;
  clip-path: polygon(50% 0, 0 100%, 100% 100%);
  transform-origin: bottom center;
  background:
    linear-gradient(90deg, transparent 44%, rgb(255 255 255 / 0.18) 50%, transparent 56%),
    linear-gradient(color-mix(in srgb, var(--c) 78%, transparent), rgb(139 108 255 / 0.22));
}

.pyramid i:nth-child(even) {
  --c: #ff4d9d;
}

.pyramid i:nth-child(1) { transform: rotateY(0deg)   translateZ(calc(var(--base) / 2)) rotateX(30deg); }
.pyramid i:nth-child(2) { transform: rotateY(90deg)  translateZ(calc(var(--base) / 2)) rotateX(30deg); }
.pyramid i:nth-child(3) { transform: rotateY(180deg) translateZ(calc(var(--base) / 2)) rotateX(30deg); }
.pyramid i:nth-child(4) { transform: rotateY(270deg) translateZ(calc(var(--base) / 2)) rotateX(30deg); }

/* floor: dark glass with a glowing rim */
.pyramid b {
  position: absolute;
  inset: auto 0 0;
  height: var(--base);
  border: 1px solid rgb(46 230 214 / 0.7);
  background: rgb(139 108 255 / 0.3);
  box-shadow: 0 0 34px rgb(139 108 255 / 0.6);
  transform: translateY(50%) rotateX(90deg);
}

/* the core: a third of the way up (the pyramid stands base × cos 30deg ≈ 121px tall). It turns
   back against the spin, so it always faces you and stays round. */
.pyramid u {
  position: absolute;
  top: 101px;
  left: 50%;
  width: 36px;
  height: 36px;
  margin: -18px 0 0 -18px;
  border-radius: 50%;
  background: radial-gradient(circle, #fff 0 18%, #ffb547 42%, transparent 72%);
  animation: face-you 12s linear infinite, pulse 2.4s ease-in-out infinite alternate;
}

@keyframes pyramid-spin {
  from { transform: translateY(-20px) rotateX(-16deg) rotateY(0deg); }
  to   { transform: translateY(-20px) rotateX(-16deg) rotateY(360deg); }
}

@keyframes face-you {
  from { transform: rotateY(0deg); }
  to   { transform: rotateY(-360deg); }
}

@keyframes pulse {
  from { opacity: 0.75; scale: 0.85; }
  to   { opacity: 1; scale: 1.15; }
}

Sass source 102 lines

@use 'sass:math';

$base: 112px;
$slant: 112px; // height of each triangular face
// Lean each face inward until its tip reaches the centre line (30° when base = slant).
$lean: math.asin(math.div($base * 0.5, $slant));
$height: $slant * math.cos($lean); // how tall the pyramid really stands

// A glass pyramid with a glowing core: see-through faces in the site's colours, so the far faces
// and the light inside show through, and the whole thing floats and turns.
.d-pyramid {
  position: relative;
  width: $base;
  height: $slant;
  transform-style: preserve-3d;
  animation: d-pyramid-spin 12s linear infinite;

  // the four faces: triangles leaned in from the edges of the floor
  i {
    position: absolute;
    inset: 0;
    clip-path: polygon(50% 0, 0 100%, 100% 100%);
    transform-origin: bottom center;
    background:
      // a bright edge light running down the face's middle
      linear-gradient(90deg, transparent 44%, rgb(255 255 255 / 0.18) 50%, transparent 56%),
      linear-gradient(color-mix(in srgb, var(--c) 78%, transparent), color-mix(in srgb, var(--accent) 22%, transparent));

    --c: var(--accent-2);

    &:nth-child(even) {
      --c: var(--hot);
    }

    @for $i from 1 through 4 {
      &:nth-child(#{$i}) {
        transform: rotateY(($i - 1) * 90deg) translateZ($base * 0.5) rotateX($lean);
      }
    }
  }

  // the floor: dark glass with a glowing rim
  b {
    position: absolute;
    bottom: 0;
    left: 0;
    width: $base;
    height: $base;
    border: 1px solid color-mix(in srgb, var(--accent-2) 70%, transparent);
    background: color-mix(in srgb, var(--accent) 30%, transparent);
    box-shadow: 0 0 34px color-mix(in srgb, var(--accent) 60%, transparent);
    transform: translateY(50%) rotateX(90deg);
  }

  // the core: a glowing orb a third of the way up. It turns back against the spin, so it always
  // faces you and stays round.
  u {
    position: absolute;
    top: $slant - $height * 0.32;
    left: 50%;
    width: 30px;
    height: 30px;
    margin: -15px 0 0 -15px;
    border-radius: 50%;
    background: radial-gradient(circle, #fff 0 18%, var(--warm) 42%, color-mix(in srgb, var(--warm) 0%, transparent) 72%);
    animation:
      d-pyramid-face 12s linear infinite,
      d-pyramid-pulse 2.4s ease-in-out infinite alternate;
  }
}

@keyframes d-pyramid-spin {
  from {
    transform: translateY(-20px) rotateX(-16deg) rotateY(0deg);
  }

  to {
    transform: translateY(-20px) rotateX(-16deg) rotateY(360deg);
  }
}

@keyframes d-pyramid-face {
  from {
    transform: rotateY(0deg);
  }

  to {
    transform: rotateY(-360deg);
  }
}

@keyframes d-pyramid-pulse {
  from {
    opacity: 0.75;
    scale: 0.85;
  }

  to {
    opacity: 1;
    scale: 1.15;
  }
}
Standalone snippet · plain CSS, no build step, no dependencies.