
A Visual Experiment Using Modern CSS and SCSS
I’m pleased to share a recent CodePen project where I created a 3D rotating text banner using nothing but HTML and CSS (SCSS). This animation highlights just how powerful modern CSS has become — capable of handling complex, GPU-accelerated visual effects without any JavaScript or external libraries.
Check out the demo on CodePen →
The Concept
The idea was simple: build a circular banner that displays the phrase “Crafting Code With Creativity” rotating in 3D space. Rather than use JavaScript to generate panels or manage the animation loop, I wanted to see how much could be achieved through CSS alone — and the results were both lightweight and surprisingly fluid.
HTML Structure
At the core, the HTML is composed of three main parts:
.scene: the container with a 3D perspective
.banner: the rotating wrapper for 24 panels
.panel: individual rotated divs arranged around a circle
.screen: a transparent layer to soften the look with gradient shading
<div class="scene">
<div class="banner">
<div class="panel"></div>
<!-- ...repeated up to 24 panels -->
</div>
<div class="screen"></div>
</div>
The Animation Breakdown
Each .panel is absolutely positioned and rotated around the Y-axis. Using a combination of rotateY() and translateZ(), they are placed in 3D space forming a circular ring.
The .banner then rotates continuously using the @keyframes rotate animation.
.banner {
display: flex;
transform-style: preserve-3d;
animation: rotate 24s infinite linear;
}
@keyframes rotate {
to {
transform: rotateY(-360deg);
}
}
The key to this effect is the combination of preserve-3d and the browser’s native perspective on the parent :
body {
background-color: #000;
color: #fff;
min-height: 100vh;
display: grid;
place-items: center;
perspective: 500px;
perspective-origin: 50% calc(50% - 150px);
font-family: fantasy;
}
The Panels and SCSS Logic
Each .panel is styled with a consistent size and placed precisely using SCSS loops and CSS custom properties:
.panel {
position: absolute;
transform: translate(-50%, -50%) rotateY(var(--angle)) translateZ(190px);
width: 50px;
height: 120px;
overflow: hidden;
}
The text is placed inside a ::before pseudo-element, so the same string can scroll across all 24 panels with a horizontal offset:
.panel::before {
position: absolute;
left: var(--left);
content: "Crafting Code With Creativity";
font-size: 96px;
width: max-content;
color: hsl(var(--hue), 70%, 40%);
}
Using SCSS’s @for loop, each panel is given:
A unique rotation angle
A left offset to align the text
A color hue (even though white is used here, HSL allows for experimentation)
@for $i from 0 to 24 {
.panel:nth-child(#{$i + 1}) {
--left: #{-50px * $i};
--hue: #{360 / 24 * $i};
--angle: #{360deg / 24 * $i};
}
}
Adding Visual Depth with .screen
To polish the look, a .screen layer adds a subtle gradient overlay, enhancing the 3D illusion:
.screen {
position: absolute;
width: 400px;
height: 400px;
background-image: linear-gradient(90deg, #000a, #0004, #000a);
transform: translate(-50%, -50%);
}
This doesn’t interfere with the animation but gives it a glassy, dimensional feel.
Why It Works So Well
Pure CSS: No JavaScript required, resulting in faster performance and simpler integration.
GPU-Accelerated: All transforms and animations are hardware-accelerated, ensuring smooth motion.
SCSS-Driven: SCSS loops and variables keep the codebase clean, maintainable, and scalable.
Creative Control: Using HSL color values and CSS custom properties allows for quick experimentation and theming.
Use Cases
This type of 3D animation could be used for:
Hero sections on portfolio websites
Creative intros for tech products or events
Animated headlines or banners
Digital art experiments and generative design
You can even enhance it further by pausing the animation on hover, adding interactivity, or layering multiple rings for a stacked effect.
Final Thoughts
This project is a great demonstration of what modern CSS can do when pushed creatively. It also shows how far we can go with just stylesheets — crafting immersive, performant visuals that previously would have required JavaScript or WebGL.
Feel free to explore, fork, and adapt this idea for your own use.
View the full live version here:
Live CodePen Demo