Interactive Experiments
Stained Glass Simulations
Stained glass windows have captivated people for centuries with their vibrant colors, intricate patterns, and the way light transforms them into living art. But what if we could recreate that magic on the web using only CSS and JavaScript?
The beauty of stained glass lies in geometric patterns divided by lead lines, translucent colors that layer and blend, light interaction creating dynamic visual effects, and texture and depth from the glass itself. Translating these properties to the web requires creative use of modern CSS features like gradients, blend modes, filters, and animations.
Technical Approach
Key Techniques
- CSS Grid: Creates geometric divisions with gap property for lead lines
- Gradients: Multiple gradients layer for depth and translucency
- Animations: CSS keyframes simulate light passing through glass
- JavaScript: Adds interactivity—hover effects, click animations, and dynamic color changes
Structure with CSS Grid
.stained-glass {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(60px, 1fr));
gap: 2px; /* Lead lines */
background: #2a2a2a; /* Lead color */
}
.glass-piece {
background:
radial-gradient(circle at 30% 30%, rgba(255,255,255,0.4), transparent),
linear-gradient(135deg, #4a90e2, #67b26f);
backdrop-filter: blur(1px);
animation: shimmer 3s ease-in-out infinite;
}
@keyframes shimmer {
0%, 100% { opacity: 0.8; }
50% { opacity: 1; }
}
Interactive JavaScript
// Click to brighten a glass piece
const piece = document.querySelector('.glass-piece');
piece.addEventListener('click', () => {
piece.style.filter = 'brightness(1.3) saturate(1.5)';
setTimeout(() => {
piece.style.filter = '';
}, 500);
});
// Ripple effect from clicked element
// Target a specific demo container (e.g., 'demo-4' is the Sunset Grid variation)
const demo = document.getElementById('demo-4');
demo.querySelectorAll('.glass-piece').forEach((p, index) => {
p.addEventListener('click', function() {
// Current element index is 'index'
demo.querySelectorAll('.glass-piece').forEach((piece, idx) => {
const delay = Math.abs(idx - index) * 100;
setTimeout(() => {
piece.style.filter = 'brightness(1.4)';
setTimeout(() => {
piece.style.filter = '';
}, 300);
}, delay);
});
});
});
Interactive Demos
Nine variations exploring color, geometry, and light through CSS and JavaScript. Click or hover each panel to interact.
Jewel Mosaic
Click pieces for color burst
Radial Bloom
Hover to illuminate
Ocean Waves
Flowing gradient animation
Sunset Grid
Click to ripple light
Crystalline
Prismatic shimmer effect
Forest Canopy
Hover for dappled light
Monochrome Zen
Minimalist pulse
Fire Kaleidoscope
Click for flame burst
Aurora Borealis
Flowing northern lights
Lessons Learned
- Layering is everything: Multiple gradients, shadows, and blend modes create convincing depth
- Subtle animations win: Slow, gentle movements feel more natural than fast effects
- Performance matters: Using CSS transforms and opacity for animations keeps things smooth
- Constraints breed creativity: Working within CSS/JS limitations led to unexpected discoveries
All 9 variations are built with vanilla CSS and JavaScript—no frameworks, no libraries. Each demo is self-contained and mobile-responsive, adapting gracefully to different screen sizes. The techniques here can be applied beyond stained glass: data visualizations, generative art, UI components, and more.