← back to Only CSS: Grid Template Animationcompare with ground truth →
model output
GPT-5.4
Only CSS: Grid Template Animation
A 0.77T 0.16
1<!DOCTYPE html>
2<html lang="en">
3<head>
4<meta charset="UTF-8" />
5<meta name="viewport" content="width=device-width,initial-scale=1" />
6<title>Geometric Grid Morph</title>
7<style>
8 :root{
9 --bg1:#070b14;
10 --bg2:#0d1622;
11 --bg3:#132231;
12 --line:#49b9ea;
13 --dot:#6fe7d8;
14 --cell:40px;
15 --gap:9px;
16 --radius:10px;
17 --stroke:2px;
18 --dur:4.8s;
19 --tilt:18deg;
20 }
21
22 html,body{
23 margin:0;
24 width:100%;
25 height:100%;
26 overflow:hidden;
27 background:
28 radial-gradient(ellipse at center, rgba(34,58,78,.55) 0%, rgba(16,26,39,.35) 34%, rgba(8,12,20,.96) 78%, #05070d 100%);
29 font-family:system-ui,sans-serif;
30 }
31
32 .stage{
33 width:100%;
34 height:100%;
35 display:grid;
36 place-items:center;
37 position:relative;
38 }
39
40 .grid{
41 display:grid;
42 grid-template-columns:repeat(10, var(--cell));
43 grid-template-rows:repeat(10, var(--cell));
44 gap:var(--gap);
45 transform-origin:center;
46 animation: boardTilt var(--dur) ease-in-out infinite;
47 filter:
48 drop-shadow(0 0 2px rgba(73,185,234,.18))
49 drop-shadow(0 0 8px rgba(73,185,234,.08));
50 }
51
52 .tile{
53 width:var(--cell);
54 height:var(--cell);
55 border:var(--stroke) solid rgba(73,185,234,.95);
56 border-radius:var(--radius);
57 box-sizing:border-box;
58 position:relative;
59 justify-self:center;
60 align-self:center;
61 animation: morph var(--dur) cubic-bezier(.55,.02,.35,1) infinite;
62 animation-delay:var(--d);
63 background:transparent;
64 }
65
66 .tile::after{
67 content:"";
68 position:absolute;
69 width:10px;
70 height:10px;
71 border-radius:50%;
72 background:var(--dot);
73 left:50%;
74 top:50%;
75 transform:translate(-50%,-50%);
76 box-shadow:0 0 6px rgba(111,231,216,.18);
77 }
78
79 @keyframes boardTilt{
80 0%,18%,32%,50%,68%,82%,100%{ transform:rotate(0deg); }
81 25%,75%{ transform:rotate(calc(var(--tilt) * -1)); }
82 }
83
84 @keyframes morph{
85 0%,18%,32%,50%,68%,82%,100%{
86 width:var(--cell);
87 height:var(--cell);
88 transform:rotate(-12deg);
89 }
90
91 20%,30%,70%,80%{
92 width:calc(var(--cell) * var(--sx));
93 height:calc(var(--cell) * var(--sy));
94 transform:rotate(0deg);
95 }
96 }
97
98 /* subtle vignette */
99 .stage::after{
100 content:"";
101 position:absolute;
102 inset:0;
103 pointer-events:none;
104 background:
105 radial-gradient(circle at center, transparent 0 42%, rgba(0,0,0,.12) 72%, rgba(0,0,0,.34) 100%);
106 mix-blend-mode:multiply;
107 }
108</style>
109</head>
110<body>
111<div class="stage">
112 <div class="grid" id="grid"></div>
113</div>
114
115<script>
116 const grid = document.getElementById('grid');
117 const rows = 10, cols = 10;
118
119 // Pattern approximates the frames:
120 // mostly small squares, with two larger "window" blocks and surrounding bars.
121 function scaleFor(r, c){
122 // default small square
123 let sx = 1, sy = 1;
124
125 // two repeated 5x5 motifs across the width, stacked twice vertically
126 const motifCol = c % 5;
127 const motifRow = r % 5;
128
129 // large center block in each motif
130 if (motifCol === 2 && motifRow === 2) { sx = 3; sy = 3; }
131 // horizontal bars above/below center
132 else if (motifCol === 2 && (motifRow === 0 || motifRow === 1 || motifRow === 3 || motifRow === 4)) { sx = 3; sy = 1; }
133 // vertical bars left/right of center
134 else if ((motifCol === 0 || motifCol === 1 || motifCol === 3 || motifCol === 4) && motifRow === 2) { sx = 1; sy = 2; }
135
136 return {sx, sy};
137 }
138
139 for(let r=0;r<rows;r++){
140 for(let c=0;c<cols;c++){
141 const tile = document.createElement('div');
142 tile.className = 'tile';
143
144 const {sx, sy} = scaleFor(r,c);
145 tile.style.setProperty('--sx', sx);
146 tile.style.setProperty('--sy', sy);
147
148 // tiny stagger keeps the morph feeling organic while still synchronized
149 const delay = ((r * cols + c) % 7) * -0.015;
150 tile.style.setProperty('--d', `${delay}s`);
151
152 grid.appendChild(tile);
153 }
154 }
155</script>
156</body>
157</html>