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>

More Spinners Animations