← back to Only CSS: Flex Breezecompare with ground truth →
model output
GPT-5.4
Only CSS: Flex Breeze
A 0.94T 0.43
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.0" />
6<title>Breeze Animation</title>
7<style>
8 :root{
9 --bg:#ffffff;
10 --cyan:#39d9ff;
11 --pink:#ffe6fb;
12 --green:#39f20f;
13 --count:28;
14 --w:680px;
15 --h:320px;
16 --barW:12px;
17 --gap:11px;
18 --tilt:6deg;
19 --dur:3.2s;
20 }
21
22 *{box-sizing:border-box}
23 html,body{
24 margin:0;
25 width:100%;
26 height:100%;
27 background:var(--bg);
28 font-family: Arial, Helvetica, sans-serif;
29 }
30
31 body{
32 display:grid;
33 place-items:center;
34 }
35
36 .scene{
37 width:760px;
38 height:430px;
39 position:relative;
40 }
41
42 .title{
43 position:absolute;
44 left:50%;
45 top:42px;
46 transform:translateX(-50%);
47 color:var(--cyan);
48 font-size:54px;
49 font-weight:900;
50 font-style:italic;
51 letter-spacing:-2px;
52 line-height:1;
53 text-transform:uppercase;
54 }
55
56 .flag{
57 position:absolute;
58 left:50%;
59 top:120px;
60 width:var(--w);
61 height:var(--h);
62 transform:translateX(-50%);
63 }
64
65 .row{
66 position:absolute;
67 left:0;
68 width:100%;
69 height:92px;
70 display:flex;
71 gap:var(--gap);
72 align-items:flex-end;
73 filter: drop-shadow(0 0 10px rgba(255,255,255,.9));
74 }
75
76 .row.top{ top:0; color:var(--cyan); }
77 .row.mid{ top:86px; color:var(--pink); }
78 .row.bot{ top:172px; color:var(--green); }
79
80 .bar{
81 width:var(--barW);
82 border-radius:999px;
83 background:currentColor;
84 transform-origin:50% 100%;
85 transform:rotate(var(--tilt));
86 animation: breeze var(--dur) ease-in-out infinite;
87 animation-delay: calc(var(--i) * -0.085s);
88 will-change: height, transform;
89 }
90
91 .row.top .bar{
92 height:calc(58px + 42px * (0.5 + 0.5 * sin(var(--p))));
93 }
94 .row.mid .bar{
95 height:calc(34px + 58px * (0.5 + 0.5 * sin(var(--p))));
96 }
97 .row.bot .bar{
98 height:calc(28px + 64px * (0.5 + 0.5 * sin(var(--p))));
99 }
100
101 @keyframes breeze{
102 0%,100%{
103 transform:rotate(6deg) translateY(0);
104 filter:brightness(1);
105 }
106 25%{
107 transform:rotate(5deg) translateY(-1px);
108 filter:brightness(1.01);
109 }
110 50%{
111 transform:rotate(7deg) translateY(0);
112 filter:brightness(1);
113 }
114 75%{
115 transform:rotate(6deg) translateY(1px);
116 filter:brightness(.995);
117 }
118 }
119
120 /* fallback if trig functions unsupported */
121 @supports not (height: calc(10px * sin(1rad))) {
122 .row.top .bar{ height:84px; }
123 .row.mid .bar{ height:62px; }
124 .row.bot .bar{ height:70px; }
125 }
126</style>
127</head>
128<body>
129 <div class="scene">
130 <div class="title">BREEZE</div>
131 <div class="flag">
132 <div class="row top" id="top"></div>
133 <div class="row mid" id="mid"></div>
134 <div class="row bot" id="bot"></div>
135 </div>
136 </div>
137
138<script>
139 const COUNT = 28;
140 const rows = ["top","mid","bot"];
141
142 rows.forEach(id=>{
143 const row = document.getElementById(id);
144 for(let i=0;i<COUNT;i++){
145 const b = document.createElement("span");
146 b.className = "bar";
147 b.style.setProperty("--i", i);
148 const phase = (i/(COUNT-1))*Math.PI*2;
149 b.style.setProperty("--p", `${phase}rad`);
150 row.appendChild(b);
151 }
152 });
153
154 // Animate the wave shape itself so the crest travels left-to-right continuously.
155 const barsByRow = rows.map(id => [...document.getElementById(id).children]);
156 const start = performance.now();
157 const speed = 2 * Math.PI / 3200; // one full cycle in 3.2s
158
159 function frame(t){
160 const timePhase = (t - start) * speed;
161
162 barsByRow[0].forEach((bar,i)=>{
163 const p = (i/(COUNT-1))*Math.PI*2 + timePhase;
164 const h = 58 + 42*(0.5 + 0.5*Math.sin(p));
165 bar.style.height = h.toFixed(2) + "px";
166 });
167
168 barsByRow[1].forEach((bar,i)=>{
169 const p = (i/(COUNT-1))*Math.PI*2 + timePhase - 0.55;
170 const h = 34 + 58*(0.5 + 0.5*Math.sin(p));
171 bar.style.height = h.toFixed(2) + "px";
172 });
173
174 barsByRow[2].forEach((bar,i)=>{
175 const p = (i/(COUNT-1))*Math.PI*2 + timePhase - 1.1;
176 const h = 28 + 64*(0.5 + 0.5*Math.sin(p));
177 bar.style.height = h.toFixed(2) + "px";
178 });
179
180 requestAnimationFrame(frame);
181 }
182 requestAnimationFrame(frame);
183</script>
184</body>
185</html>