Snake
A pure CSS snake loader where nine dots arranged in a 3×3 grid fill in sequence then drain, tracing a snake-like path using only box-shadow spread animations.
Generated using Grepped's AI UI component generator — created from scratch, not pulled from a library.
spinnersnakedotsloaderbox-shadowgrid
Live Preview — customize or regenerate this in the workspace
Loading preview…
Design Intent
Nine dots in a 3×3 grid that fill and drain sequentially like a snake using CSS box-shadow spread animations.
CSS
css
body { margin: 0; min-height: 100vh; display: flex; align-items: center; justify-content: center; background: #0f0f0f; }
:root { --primary: #6366f1; }
.snake {
position: relative;
height: 60px;
width: 60px;
}
.snake:after {
animation: snake 2s infinite both ease;
border-radius: 100%;
content: '';
height: 10px;
left: 50%;
margin-left: -32.5px;
margin-top: -5px;
position: absolute;
top: 50%;
width: 10px;
}
@keyframes snake {
0%, 5% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 -10px var(--primary); }
10% { box-shadow: 15px 15px 0 0 var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 -10px var(--primary); }
15% { box-shadow: 15px 15px 0 0 var(--primary), 30px 15px 0 0 var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 -10px var(--primary); }
20% { box-shadow: 15px 15px 0 0 var(--primary), 30px 15px 0 0 var(--primary), 45px 15px 0 0 var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 -10px var(--primary); }
25% { box-shadow: 15px 15px 0 0 var(--primary), 30px 15px 0 0 var(--primary), 45px 15px 0 0 var(--primary), 45px 0 0 0 var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 -10px var(--primary); }
30% { box-shadow: 15px 15px 0 0 var(--primary), 30px 15px 0 0 var(--primary), 45px 15px 0 0 var(--primary), 45px 0 0 0 var(--primary), 45px -15px 0 0 var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 -10px var(--primary); }
35% { box-shadow: 15px 15px 0 0 var(--primary), 30px 15px 0 0 var(--primary), 45px 15px 0 0 var(--primary), 45px 0 0 0 var(--primary), 45px -15px 0 0 var(--primary), 30px -15px 0 0 var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 -10px var(--primary); }
40% { box-shadow: 15px 15px 0 0 var(--primary), 30px 15px 0 0 var(--primary), 45px 15px 0 0 var(--primary), 45px 0 0 0 var(--primary), 45px -15px 0 0 var(--primary), 30px -15px 0 0 var(--primary), 15px -15px 0 0 var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 -10px var(--primary); }
45% { box-shadow: 15px 15px 0 0 var(--primary), 30px 15px 0 0 var(--primary), 45px 15px 0 0 var(--primary), 45px 0 0 0 var(--primary), 45px -15px 0 0 var(--primary), 30px -15px 0 0 var(--primary), 15px -15px 0 0 var(--primary), 15px 0 0 0 var(--primary), 30px 0 0 -10px var(--primary); }
50% { box-shadow: 15px 15px 0 0 var(--primary), 30px 15px 0 0 var(--primary), 45px 15px 0 0 var(--primary), 45px 0 0 0 var(--primary), 45px -15px 0 0 var(--primary), 30px -15px 0 0 var(--primary), 15px -15px 0 0 var(--primary), 15px 0 0 0 var(--primary), 30px 0 0 0 var(--primary); }
55% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 0 var(--primary), 45px 15px 0 0 var(--primary), 45px 0 0 0 var(--primary), 45px -15px 0 0 var(--primary), 30px -15px 0 0 var(--primary), 15px -15px 0 0 var(--primary), 15px 0 0 0 var(--primary), 30px 0 0 0 var(--primary); }
60% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 0 var(--primary), 45px 0 0 0 var(--primary), 45px -15px 0 0 var(--primary), 30px -15px 0 0 var(--primary), 15px -15px 0 0 var(--primary), 15px 0 0 0 var(--primary), 30px 0 0 0 var(--primary); }
65% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 0 var(--primary), 45px -15px 0 0 var(--primary), 30px -15px 0 0 var(--primary), 15px -15px 0 0 var(--primary), 15px 0 0 0 var(--primary), 30px 0 0 0 var(--primary); }
70% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 0 var(--primary), 30px -15px 0 0 var(--primary), 15px -15px 0 0 var(--primary), 15px 0 0 0 var(--primary), 30px 0 0 0 var(--primary); }
75% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 0 var(--primary), 15px -15px 0 0 var(--primary), 15px 0 0 0 var(--primary), 30px 0 0 0 var(--primary); }
80% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 0 var(--primary), 15px 0 0 0 var(--primary), 30px 0 0 0 var(--primary); }
85% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 0 var(--primary), 30px 0 0 0 var(--primary); }
90% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 0 var(--primary); }
95%, 100% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 -10px var(--primary); }
}HTML
html
<div class="snake"></div>Full Source
html
<!DOCTYPE html>
<html>
<head>
<style>
body { margin: 0; min-height: 100vh; display: flex; align-items: center; justify-content: center; background: #0f0f0f; }
:root { --primary: #6366f1; }
.snake {
position: relative;
height: 60px;
width: 60px;
}
.snake:after {
animation: snake 2s infinite both ease;
border-radius: 100%;
content: '';
height: 10px;
left: 50%;
margin-left: -32.5px;
margin-top: -5px;
position: absolute;
top: 50%;
width: 10px;
}
@keyframes snake {
0%, 5% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 -10px var(--primary); }
10% { box-shadow: 15px 15px 0 0 var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 -10px var(--primary); }
15% { box-shadow: 15px 15px 0 0 var(--primary), 30px 15px 0 0 var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 -10px var(--primary); }
20% { box-shadow: 15px 15px 0 0 var(--primary), 30px 15px 0 0 var(--primary), 45px 15px 0 0 var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 -10px var(--primary); }
25% { box-shadow: 15px 15px 0 0 var(--primary), 30px 15px 0 0 var(--primary), 45px 15px 0 0 var(--primary), 45px 0 0 0 var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 -10px var(--primary); }
30% { box-shadow: 15px 15px 0 0 var(--primary), 30px 15px 0 0 var(--primary), 45px 15px 0 0 var(--primary), 45px 0 0 0 var(--primary), 45px -15px 0 0 var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 -10px var(--primary); }
35% { box-shadow: 15px 15px 0 0 var(--primary), 30px 15px 0 0 var(--primary), 45px 15px 0 0 var(--primary), 45px 0 0 0 var(--primary), 45px -15px 0 0 var(--primary), 30px -15px 0 0 var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 -10px var(--primary); }
40% { box-shadow: 15px 15px 0 0 var(--primary), 30px 15px 0 0 var(--primary), 45px 15px 0 0 var(--primary), 45px 0 0 0 var(--primary), 45px -15px 0 0 var(--primary), 30px -15px 0 0 var(--primary), 15px -15px 0 0 var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 -10px var(--primary); }
45% { box-shadow: 15px 15px 0 0 var(--primary), 30px 15px 0 0 var(--primary), 45px 15px 0 0 var(--primary), 45px 0 0 0 var(--primary), 45px -15px 0 0 var(--primary), 30px -15px 0 0 var(--primary), 15px -15px 0 0 var(--primary), 15px 0 0 0 var(--primary), 30px 0 0 -10px var(--primary); }
50% { box-shadow: 15px 15px 0 0 var(--primary), 30px 15px 0 0 var(--primary), 45px 15px 0 0 var(--primary), 45px 0 0 0 var(--primary), 45px -15px 0 0 var(--primary), 30px -15px 0 0 var(--primary), 15px -15px 0 0 var(--primary), 15px 0 0 0 var(--primary), 30px 0 0 0 var(--primary); }
55% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 0 var(--primary), 45px 15px 0 0 var(--primary), 45px 0 0 0 var(--primary), 45px -15px 0 0 var(--primary), 30px -15px 0 0 var(--primary), 15px -15px 0 0 var(--primary), 15px 0 0 0 var(--primary), 30px 0 0 0 var(--primary); }
60% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 0 var(--primary), 45px 0 0 0 var(--primary), 45px -15px 0 0 var(--primary), 30px -15px 0 0 var(--primary), 15px -15px 0 0 var(--primary), 15px 0 0 0 var(--primary), 30px 0 0 0 var(--primary); }
65% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 0 var(--primary), 45px -15px 0 0 var(--primary), 30px -15px 0 0 var(--primary), 15px -15px 0 0 var(--primary), 15px 0 0 0 var(--primary), 30px 0 0 0 var(--primary); }
70% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 0 var(--primary), 30px -15px 0 0 var(--primary), 15px -15px 0 0 var(--primary), 15px 0 0 0 var(--primary), 30px 0 0 0 var(--primary); }
75% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 0 var(--primary), 15px -15px 0 0 var(--primary), 15px 0 0 0 var(--primary), 30px 0 0 0 var(--primary); }
80% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 0 var(--primary), 15px 0 0 0 var(--primary), 30px 0 0 0 var(--primary); }
85% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 0 var(--primary), 30px 0 0 0 var(--primary); }
90% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 0 var(--primary); }
95%, 100% { box-shadow: 15px 15px 0 -10px var(--primary), 30px 15px 0 -10px var(--primary), 45px 15px 0 -10px var(--primary), 45px 0 0 -10px var(--primary), 45px -15px 0 -10px var(--primary), 30px -15px 0 -10px var(--primary), 15px -15px 0 -10px var(--primary), 15px 0 0 -10px var(--primary), 30px 0 0 -10px var(--primary); }
}
</style>
</head>
<body>
<div class="snake"></div>
</body>
</html>