Bring geometry to life in your browser by creating mesmerizing 3D shapes and intersections with CSS! In this blog, we’ll explore how to design a 3D sphere, cubes, and their dynamic intersections—all using pure CSS. By mastering CSS 3D transforms, perspective
, and lighting effects, we’ll construct visually stunning shapes that interact and overlap, showcasing the beauty of geometry. Whether you’re looking to enhance your web animations or dive into advanced CSS design, this tutorial will spark your creativity. Let’s intersect design and innovation—one shape at a time!
I would recommend you don’t just copy and paste the code, just look at the code and type by understanding it.
Demo
See the Pen CSS – 3D – Sphere – Cubes – Intersection (No JS) by Konstantin Denerz (@konstantindenerz) on CodePen.
HTML Code
Starter Template
<!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- CSS --> <link rel="stylesheet" href="style.css"> <title>Coding Torque</title> </head> <body> <!-- Further code here --> </body> </html>
Paste the below code in your <body>
tag.
<div class="wrapper"> <div class="container"> <div class="wall"> <div class="surface"></div> <div class="surface"></div> <div class="left"></div> <div class="top"></div> </div> <div class="wall"> <div class="surface"></div> <div class="surface"></div> <div class="left"></div> <div class="top"></div> </div> <div class="wall"> <div class="surface"></div> <div class="surface"></div> <div class="left"></div> <div class="top"></div> </div> <div class="wall"> <div class="surface"></div> <div class="surface"></div> <div class="left"></div> <div class="top"></div> </div> <div class="wall"> <div class="surface"></div> <div class="surface"></div> <div class="left"></div> <div class="top"></div> </div> <div class="wall"> <div class="surface"></div> <div class="surface"></div> <div class="left"></div> <div class="top"></div> </div> <div class="ball-container"> <div class="ball"></div> </div> </div> </div>
CSS Code
Create a file style.css and paste the code below.
// @property rule (CSS Future Tip 🔮): https://drafts.css-houdini.org/css-properties-values-api/ // 🔥 cos(): https://web.dev/css-trig-functions/ @property --angle { syntax: "<angle>"; inherits: true; initial-value: 0deg; } @property --circle-diameter { syntax: "<length>"; inherits: true; initial-value: 0; } $walls: 6; $half: $walls / 2; $surfaces: $walls * 2; :root { --color-background: conic-gradient( black, #192d39, #0e1e2e, #281133, #14293d, #16031a, black ); --color-on-background: white; --c1: #6eccee; --c2: #ffdc99; --c3: #e3a4d0; --c4: #d455ff; --animation-duration: 2.8s; --border-width: 0.6vmin; --glow: drop-shadow(0 0 6vmin rgba(255, 255, 255, 0.19)); --hole-pos-y: 20%; --hole-radius: 22vmin; --offset-per-surface: calc(360deg / 24); } .container { position: relative; width: 50vmin; aspect-ratio: 1/1.2; --angle: 30deg; animation: angle var(--animation-duration) linear infinite; transform-style: preserve-3d; transform: rotateX(-45deg) rotateY(45deg); } .wall { position: absolute; inset: 0; --wall-gap: 10vmin; filter: var(--glow); $surfaceIndex: 0; @for $i from 1 through $walls { $index: $i - 3; $surfaceIndex: $surfaceIndex + 1; &:nth-of-type(#{$i}) { transform: translateZ(calc(var(--wall-gap) * #{$index - 1})); --index: #{$i}; .surface, .top { --index: #{$surfaceIndex}; &:nth-child(2) { $surfaceIndex: $surfaceIndex + 1; --index: #{$surfaceIndex}; } } } } } .surface { position: absolute; inset: 0; --angle-offset: calc(var(--index) * var(--offset-per-surface)); --circle-diameter: calc( var(--hole-radius) * cos(calc(var(--angle) + var(--angle-offset))) ); -webkit-mask: radial-gradient( circle at 50% var(--hole-pos-y), transparent var(--circle-diameter), black var(--circle-diameter) ); mask: radial-gradient( circle at 50% var(--hole-pos-y), transparent var(--circle-diameter), black var(--circle-diameter) ); -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-size: 100% 100%; mask-size: 100% 100%; -webkit-mask-position: 0 0; mask-position: 0 0; background: radial-gradient( circle at 50% var(--hole-pos-y), var(--c4) calc(var(--circle-diameter) + var(--border-width)), var(--c4) calc(var(--circle-diameter) + var(--border-width)), transparent var(--circle-diameter) ), linear-gradient(black, black), linear-gradient( 45deg, var(--c1), var(--c3), var(--c2), var(--c1), var(--c4), var(--c3), var(--c2) ); background-repeat: no-repeat; background-size: 100% 100%, calc(100% - var(--border-width) * 2) calc(100% - var(--border-width) * 2), 100%, 100%; background-position: 0 0, var(--border-width) var(--border-width), 0 0; &:nth-child(2) { --circle-diameter: calc( var(--hole-radius) * cos(calc(var(--angle) + var(--angle-offset))) ); transform: translate(4vmin, 5.7vmin); } } .left { position: absolute; transform: skewY(55deg) translateY(2.9vmin); inset: 0; width: 4.5vmin; background: linear-gradient(black, black) no-repeat, linear-gradient(to top, var(--c1), var(--c3), var(--c2), var(--c1)) no-repeat; background-size: calc(100% - var(--border-width) * 2) calc(100% - var(--border-width) * 2), 100%, 100%; background-position: var(--border-width) var(--border-width), 0 0; } .top { position: absolute; transform: skewX(36deg) translateX(2vmin); inset: 0; height: 6vmin; background: linear-gradient(black, black) no-repeat, linear-gradient(to right, var(--c1), var(--c3), var(--c2), var(--c1)) no-repeat; background-size: calc(100% - var(--border-width) * 2) calc(100% - var(--border-width) * 2), 100%, 100%; background-position: var(--border-width) var(--border-width), 0 0; --angle-offset: calc(var(--index) * var(--offset-per-surface)); --circle-diameter: calc( var(--hole-radius) * cos(calc(var(--angle) + var(--angle-offset))) ); -webkit-mask: radial-gradient( calc(var(--circle-diameter) * 0.86) at 50% calc(60% / cos(calc(var(--angle) + var(--angle-offset)))), transparent var(--circle-diameter), black var(--circle-diameter) ); mask: radial-gradient( calc(var(--circle-diameter) * 0.86) at 50% calc(60% / cos(calc(var(--angle) + var(--angle-offset)))), transparent var(--circle-diameter), black var(--circle-diameter) ); -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-size: 100% 100%; mask-size: 100% 100%; -webkit-mask-position: 0 0; mask-position: 0 0; } @keyframes angle { from { --angle: 360deg; } to { --angle: 0deg; } } .ball-container { display: grid; place-items: center; position: absolute; inset: 0; transform: translateZ(-60vmin); animation: ball-container var(--animation-duration) linear infinite; } .ball { width: 42vmin; aspect-ratio: 1; border-radius: 50%; filter: var(--glow); background: radial-gradient( 21.5vmin 21.5vmin at center, black 20vmin, transparent 20vmin ), conic-gradient( var(--c1), var(--c3), var(--c2), var(--c4), var(--c3), var(--c1), var(--c2), var(--c1) ); box-shadow: 0 0 10vmin rgba(255, 255, 255, 0.08); transform: rotateX(45deg) rotateY(45deg) translateY(-20vmin); } @keyframes ball-container { from { transform: translateZ(-40vmin); opacity: 0; } 10% { transform: translateZ(-25vmin); opacity: 1; } 85% { opacity: 1; } to { opacity: 0; transform: translateZ(70vmin); } } body { width: 100vw; height: 100vh; display: grid; place-items: center; background: var(--color-background); color: var(--color-on-background); overflow: hidden; mix-blend-mode: plus-lighter; }
Final Output
Written by: Piyush Patil
Code Credits: https://codepen.io/konstantindenerz/pen/xxyZJpO
If you found any mistakes or have any doubts please feel free to Contact Us
Hope you find this post helpful💖