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.

  • 79 lines of CSS
  • 7 lines of HTML
  • No JavaScript
  • No dependencies
  • Snippet under MIT
GitHub

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.
  5. Every length is a multiple of one base unit, --u, so the pyramid is the same share of a gallery card, the editor and a recording canvas. The base is 140 of those units.

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 79 lines

.scene {
  /* one base unit: every length below is a multiple of it, so the pyramid is the same share of a
     card, the editor, a full screen and a recording canvas */
  --u: 0.36vmin;
  perspective: calc(800 * var(--u));
}

.pyramid {
  --base: calc(140 * var(--u));
  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. The rim is an inset line plus a soft shade, not a
   border: the floor is seen nearly side-on, and a 1px border squeezed that flat breaks into dashes */
.pyramid b {
  position: absolute;
  inset: auto 0 0;
  height: var(--base);
  background: rgb(139 108 255 / 0.3);
  box-shadow:
    inset 0 0 0 calc(1.5 * var(--u)) rgb(46 230 214 / 0.7),
    inset 0 0 calc(6 * var(--u)) rgb(46 230 214 / 0.7),
    0 0 calc(34 * var(--u)) 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 ≈ 121 units tall). It
   turns back against the spin, so it always faces you and stays round. */
.pyramid u {
  position: absolute;
  top: calc(101 * var(--u));
  left: 50%;
  width: calc(36 * var(--u));
  height: calc(36 * var(--u));
  margin: calc(-18 * var(--u)) 0 0 calc(-18 * var(--u));
  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(calc(-20 * var(--u))) rotateX(-16deg) rotateY(0deg); }
  to   { transform: translateY(calc(-20 * var(--u))) 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; }
}
Standalone snippet · plain CSS, no build step, no dependencies.