Progressive Blur Skill
Workflow
- Confirm placement (top or bottom), height, and z-index relative to UI.
- Provide the matching snippet and a short usage checklist.
- Offer only targeted tweaks (height, blur steps, direction, opacity stops).
Usage checklist
- Insert the HTML inside
<body>.
- Keep the
.gradient-blur element near the top of the DOM.
- Ensure the background behind it exists (backdrop-filter blurs what is behind).
- Adjust
z-index to sit above content but below modals.
Top blur (from top)
<div class="gradient-blur">
<div></div><div></div><div></div><div></div><div></div><div></div>
</div>
<style>
.gradient-blur {
position: fixed;
z-index: 5;
inset: 0 0 auto 0;
height: 12%;
pointer-events: none;
}
.gradient-blur > div,
.gradient-blur::before,
.gradient-blur::after {
position: absolute;
inset: 0;
}
.gradient-blur::before {
content: "";
z-index: 1;
backdrop-filter: blur(0.5px);
-webkit-mask: linear-gradient(to top,
rgba(0, 0, 0, 0) 0%,
rgba(0, 0, 0, 1) 12.5%,
rgba(0, 0, 0, 1) 25%,
rgba(0, 0, 0, 0) 37.5%);
mask: linear-gradient(to top,
rgba(0, 0, 0, 0) 0%,
rgba(0, 0, 0, 1) 12.5%,
rgba(0, 0, 0, 1) 25%,
rgba(0, 0, 0, 0) 37.5%);
}
.gradient-blur > div:nth-of-type(1) {
z-index: 2;
backdrop-filter: blur(1px);
-webkit-mask: linear-gradient(to top,
rgba(0, 0, 0, 0) 12.5%,
rgba(0, 0, 0, 1) 25%,
rgba(0, 0, 0, 1) 37.5%,
rgba(0, 0, 0, 0) 50%);
mask: linear-gradient(to top,
rgba(0, 0, 0, 0) 12.5%,
rgba(0, 0, 0, 1) 25%,
rgba(0, 0, 0, 1) 37.5%,
rgba(0, 0, 0, 0) 50%);
}
.gradient-blur > div:nth-of-type(2) {
z-index: 3;
backdrop-filter: blur(2px);
-webkit-mask: linear-gradient(to top,
rgba(0, 0, 0, 0) 25%,
rgba(0, 0, 0, 1) 37.5%,
rgba(0, 0, 0, 1) 50%,
rgba(0, 0, 0, 0) 62.5%);
mask: linear-gradient(to top,
rgba(0, 0, 0, 0) 25%,
rgba(0, 0, 0, 1) 37.5%,
rgba(0, 0, 0, 1) 50%,
rgba(0, 0, 0, 0) 62.5%);
}
.gradient-blur > div:nth-of-type(3) {
z-index: 4;
backdrop-filter: blur(4px);
-webkit-mask: linear-gradient(to top,
rgba(0, 0, 0, 0) 37.5%,
rgba(0, 0, 0, 1) 50%,
rgba(0, 0, 0, 1) 62.5%,
rgba(0, 0, 0, 0) 75%);
mask: linear-gradient(to top,
rgba(0, 0, 0, 0) 37.5%,
rgba(0, 0, 0, 1) 50%,
rgba(0, 0, 0, 1) 62.5%,
rgba(0, 0, 0, 0) 75%);
}
.gradient-blur > div:nth-of-type(4) {
z-index: 5;
backdrop-filter: blur(8px);
-webkit-mask: linear-gradient(to top,
rgba(0, 0, 0, 0) 50%,
rgba(0, 0, 0, 1) 62.5%,
rgba(0, 0, 0, 1) 75%,
rgba(0, 0, 0, 0) 87.5%);
mask: linear-gradient(to top,
rgba(0, 0, 0, 0) 50%,
rgba(0, 0, 0, 1) 62.5%,
rgba(0, 0, 0, 1) 75%,
rgba(0, 0, 0, 0) 87.5%);
}
.gradient-blur > div:nth-of-type(5) {
z-index: 6;
backdrop-filter: blur(16px);
-webkit-mask: linear-gradient(to top,
rgba(0, 0, 0, 0) 62.5%,
rgba(0, 0, 0, 1) 75%,
rgba(0, 0, 0, 1) 87.5%,
rgba(0, 0, 0, 0) 100%);
mask: linear-gradient(to top,
rgba(0, 0, 0, 0) 62.5%,
rgba(0, 0, 0, 1) 75%,
rgba(0, 0, 0, 1) 87.5%,
rgba(0, 0, 0, 0) 100%);
}
.gradient-blur > div:nth-of-type(6) {
z-index: 7;
backdrop-filter: blur(32px);
-webkit-mask: linear-gradient(to top,
rgba(0, 0, 0, 0) 75%,
rgba(0, 0, 0, 1) 87.5%,
rgba(0, 0, 0, 1) 100%);
mask: linear-gradient(to top,
rgba(0, 0, 0, 0) 75%,
rgba(0, 0, 0, 1) 87.5%,
rgba(0, 0, 0, 1) 100%);
}
.gradient-blur::after {
content: "";
z-index: 8;
backdrop-filter: blur(64px);
-webkit-mask: linear-gradient(to top,
rgba(0, 0, 0, 0) 87.5%,
rgba(0, 0, 0, 1) 100%);
mask: linear-gradient(to top,
rgba(0, 0, 0, 0) 87.5%,
rgba(0, 0, 0, 1) 100%);
}
</style>
Bottom blur (from bottom)
<div class="gradient-blur">
<div></div><div></div><div></div><div></div><div></div><div></div>
</div>
<style>
.gradient-blur {
position: fixed;
z-index: 5;
inset: auto 0 0 0;
height: 65%;
pointer-events: none;
}
.gradient-blur > div,
.gradient-blur::before,
.gradient-blur::after {
position: absolute;
inset: 0;
}
.gradient-blur::before {
content: "";
z-index: 1;
backdrop-filter: blur(0.5px);
-webkit-mask: linear-gradient(to bottom,
rgba(0, 0, 0, 0) 0%,
rgba(0, 0, 0, 1) 12.5%,
rgba(0, 0, 0, 1) 25%,
rgba(0, 0, 0, 0) 37.5%);
mask: linear-gradient(to bottom,
rgba(0, 0, 0, 0) 0%,
rgba(0, 0, 0, 1) 12.5%,
rgba(0, 0, 0, 1) 25%,
rgba(0, 0, 0, 0) 37.5%);
}
.gradient-blur > div:nth-of-type(1) {
z-index: 2;
backdrop-filter: blur(1px);
-webkit-mask: linear-gradient(to bottom,
rgba(0, 0, 0, 0) 12.5%,
rgba(0, 0, 0, 1) 25%,
rgba(0, 0, 0, 1) 37.5%,
rgba(0, 0, 0, 0) 50%);
mask: linear-gradient(to bottom,
rgba(0, 0, 0, 0) 12.5%,
rgba(0, 0, 0, 1) 25%,
rgba(0, 0, 0, 1) 37.5%,
rgba(0, 0, 0, 0) 50%);
}
.gradient-blur > div:nth-of-type(2) {
z-index: 3;
backdrop-filter: blur(2px);
-webkit-mask: linear-gradient(to bottom,
rgba(0, 0, 0, 0) 25%,
rgba(0, 0, 0, 1) 37.5%,
rgba(0, 0, 0, 1) 50%,
rgba(0, 0, 0, 0) 62.5%);
mask: linear-gradient(to bottom,
rgba(0, 0, 0, 0) 25%,
rgba(0, 0, 0, 1) 37.5%,
rgba(0, 0, 0, 1) 50%,
rgba(0, 0, 0, 0) 62.5%);
}
.gradient-blur > div:nth-of-type(3) {
z-index: 4;
backdrop-filter: blur(4px);
-webkit-mask: linear-gradient(to bottom,
rgba(0, 0, 0, 0) 37.5%,
rgba(0, 0, 0, 1) 50%,
rgba(0, 0, 0, 1) 62.5%,
rgba(0, 0, 0, 0) 75%);
mask: linear-gradient(to bottom,
rgba(0, 0, 0, 0) 37.5%,
rgba(0, 0, 0, 1) 50%,
rgba(0, 0, 0, 1) 62.5%,
rgba(0, 0, 0, 0) 75%);
}
.gradient-blur > div:nth-of-type(4) {
z-index: 5;
backdrop-filter: blur(8px);
-webkit-mask: linear-gradient(to bottom,
rgba(0, 0, 0, 0) 50%,
rgba(0, 0, 0, 1) 62.5%,
rgba(0, 0, 0, 1) 75%,
rgba(0, 0, 0, 0) 87.5%);
mask: linear-gradient(to bottom,
rgba(0, 0, 0, 0) 50%,
rgba(0, 0, 0, 1) 62.5%,
rgba(0, 0, 0, 1) 75%,
rgba(0, 0, 0, 0) 87.5%);
}
.gradient-blur > div:nth-of-type(5) {
z-index: 6;
backdrop-filter: blur(16px);
-webkit-mask: linear-gradient(to bottom,
rgba(0, 0, 0, 0) 62.5%,
rgba(0, 0, 0, 1) 75%,
rgba(0, 0, 0, 1) 87.5%,
rgba(0, 0, 0, 0) 100%);
mask: linear-gradient(to bottom,
rgba(0, 0, 0, 0) 62.5%,
rgba(0, 0, 0, 1) 75%,
rgba(0, 0, 0, 1) 87.5%,
rgba(0, 0, 0, 0) 100%);
}
.gradient-blur > div:nth-of-type(6) {
z-index: 7;
backdrop-filter: blur(32px);
-webkit-mask: linear-gradient(to bottom,
rgba(0, 0, 0, 0) 75%,
rgba(0, 0, 0, 1) 87.5%,
rgba(0, 0, 0, 1) 100%);
mask: linear-gradient(to bottom,
rgba(0, 0, 0, 0) 75%,
rgba(0, 0, 0, 1) 87.5%,
rgba(0, 0, 0, 1) 100%);
}
.gradient-blur::after {
content: "";
z-index: 8;
backdrop-filter: blur(64px);
-webkit-mask: linear-gradient(to bottom,
rgba(0, 0, 0, 0) 87.5%,
rgba(0, 0, 0, 1) 100%);
mask: linear-gradient(to bottom,
rgba(0, 0, 0, 0) 87.5%,
rgba(0, 0, 0, 1) 100%);
}
</style>
Customization knobs
- Direction: flip
to top ↔ to bottom.
- Height: adjust
.gradient-blur height percentage.
- Strength: change blur values (0.5px → 64px).
- Steps: add/remove layers to control smoothness.
Common pitfalls
backdrop-filter needs content behind it; it will not blur a flat background.
- High blur values are GPU-heavy; reduce steps on low-end devices.
- Ensure
pointer-events: none stays to avoid blocking clicks.
Questions to ask when specs are missing
- Should the blur start from the top or bottom?
- How tall should the blur area be?
- Is performance a concern on lower-end devices?
1---2name: progressive-blur3description: Create a layered CSS progressive blur (top or bottom) using multiple backdrop-filter masks for depth and softness. Use when asked for “progressive blur”, “gradient blur overlay”, or stepped blur masks that fade from an edge of the viewport.4---5
6# Progressive Blur Skill
7
8## Workflow
91. Confirm placement (top or bottom), height, and z-index relative to UI.
102. Provide the matching snippet and a short usage checklist.
113. Offer only targeted tweaks (height, blur steps, direction, opacity stops).
12
13## Usage checklist
14- Insert the HTML inside `<body>`.
15- Keep the `.gradient-blur` element near the top of the DOM.
16- Ensure the background behind it exists (backdrop-filter blurs what is behind).
17- Adjust `z-index` to sit above content but below modals.
18
19## Top blur (from top)
20```html
21<div class="gradient-blur">
22 <div></div><div></div><div></div><div></div><div></div><div></div>
23</div>
24<style>
25 .gradient-blur {
26 position: fixed;
27 z-index: 5;
28 inset: 0 0 auto 0;
29 height: 12%;
30 pointer-events: none;
31 }
32
33 .gradient-blur > div,
34 .gradient-blur::before,
35 .gradient-blur::after {
36 position: absolute;
37 inset: 0;
38 }
39
40 .gradient-blur::before {
41 content: "";
42 z-index: 1;
43 backdrop-filter: blur(0.5px);
44 -webkit-mask: linear-gradient(to top,
45 rgba(0, 0, 0, 0) 0%,
46 rgba(0, 0, 0, 1) 12.5%,
47 rgba(0, 0, 0, 1) 25%,
48 rgba(0, 0, 0, 0) 37.5%);
49 mask: linear-gradient(to top,
50 rgba(0, 0, 0, 0) 0%,
51 rgba(0, 0, 0, 1) 12.5%,
52 rgba(0, 0, 0, 1) 25%,
53 rgba(0, 0, 0, 0) 37.5%);
54 }
55
56 .gradient-blur > div:nth-of-type(1) {
57 z-index: 2;
58 backdrop-filter: blur(1px);
59 -webkit-mask: linear-gradient(to top,
60 rgba(0, 0, 0, 0) 12.5%,
61 rgba(0, 0, 0, 1) 25%,
62 rgba(0, 0, 0, 1) 37.5%,
63 rgba(0, 0, 0, 0) 50%);
64 mask: linear-gradient(to top,
65 rgba(0, 0, 0, 0) 12.5%,
66 rgba(0, 0, 0, 1) 25%,
67 rgba(0, 0, 0, 1) 37.5%,
68 rgba(0, 0, 0, 0) 50%);
69 }
70
71 .gradient-blur > div:nth-of-type(2) {
72 z-index: 3;
73 backdrop-filter: blur(2px);
74 -webkit-mask: linear-gradient(to top,
75 rgba(0, 0, 0, 0) 25%,
76 rgba(0, 0, 0, 1) 37.5%,
77 rgba(0, 0, 0, 1) 50%,
78 rgba(0, 0, 0, 0) 62.5%);
79 mask: linear-gradient(to top,
80 rgba(0, 0, 0, 0) 25%,
81 rgba(0, 0, 0, 1) 37.5%,
82 rgba(0, 0, 0, 1) 50%,
83 rgba(0, 0, 0, 0) 62.5%);
84 }
85
86 .gradient-blur > div:nth-of-type(3) {
87 z-index: 4;
88 backdrop-filter: blur(4px);
89 -webkit-mask: linear-gradient(to top,
90 rgba(0, 0, 0, 0) 37.5%,
91 rgba(0, 0, 0, 1) 50%,
92 rgba(0, 0, 0, 1) 62.5%,
93 rgba(0, 0, 0, 0) 75%);
94 mask: linear-gradient(to top,
95 rgba(0, 0, 0, 0) 37.5%,
96 rgba(0, 0, 0, 1) 50%,
97 rgba(0, 0, 0, 1) 62.5%,
98 rgba(0, 0, 0, 0) 75%);
99 }
100
101 .gradient-blur > div:nth-of-type(4) {
102 z-index: 5;
103 backdrop-filter: blur(8px);
104 -webkit-mask: linear-gradient(to top,
105 rgba(0, 0, 0, 0) 50%,
106 rgba(0, 0, 0, 1) 62.5%,
107 rgba(0, 0, 0, 1) 75%,
108 rgba(0, 0, 0, 0) 87.5%);
109 mask: linear-gradient(to top,
110 rgba(0, 0, 0, 0) 50%,
111 rgba(0, 0, 0, 1) 62.5%,
112 rgba(0, 0, 0, 1) 75%,
113 rgba(0, 0, 0, 0) 87.5%);
114 }
115
116 .gradient-blur > div:nth-of-type(5) {
117 z-index: 6;
118 backdrop-filter: blur(16px);
119 -webkit-mask: linear-gradient(to top,
120 rgba(0, 0, 0, 0) 62.5%,
121 rgba(0, 0, 0, 1) 75%,
122 rgba(0, 0, 0, 1) 87.5%,
123 rgba(0, 0, 0, 0) 100%);
124 mask: linear-gradient(to top,
125 rgba(0, 0, 0, 0) 62.5%,
126 rgba(0, 0, 0, 1) 75%,
127 rgba(0, 0, 0, 1) 87.5%,
128 rgba(0, 0, 0, 0) 100%);
129 }
130
131 .gradient-blur > div:nth-of-type(6) {
132 z-index: 7;
133 backdrop-filter: blur(32px);
134 -webkit-mask: linear-gradient(to top,
135 rgba(0, 0, 0, 0) 75%,
136 rgba(0, 0, 0, 1) 87.5%,
137 rgba(0, 0, 0, 1) 100%);
138 mask: linear-gradient(to top,
139 rgba(0, 0, 0, 0) 75%,
140 rgba(0, 0, 0, 1) 87.5%,
141 rgba(0, 0, 0, 1) 100%);
142 }
143
144 .gradient-blur::after {
145 content: "";
146 z-index: 8;
147 backdrop-filter: blur(64px);
148 -webkit-mask: linear-gradient(to top,
149 rgba(0, 0, 0, 0) 87.5%,
150 rgba(0, 0, 0, 1) 100%);
151 mask: linear-gradient(to top,
152 rgba(0, 0, 0, 0) 87.5%,
153 rgba(0, 0, 0, 1) 100%);
154 }
155</style>
156```
157
158## Bottom blur (from bottom)
159```html
160<div class="gradient-blur">
161 <div></div><div></div><div></div><div></div><div></div><div></div>
162</div>
163<style>
164 .gradient-blur {
165 position: fixed;
166 z-index: 5;
167 inset: auto 0 0 0;
168 height: 65%;
169 pointer-events: none;
170 }
171
172 .gradient-blur > div,
173 .gradient-blur::before,
174 .gradient-blur::after {
175 position: absolute;
176 inset: 0;
177 }
178
179 .gradient-blur::before {
180 content: "";
181 z-index: 1;
182 backdrop-filter: blur(0.5px);
183 -webkit-mask: linear-gradient(to bottom,
184 rgba(0, 0, 0, 0) 0%,
185 rgba(0, 0, 0, 1) 12.5%,
186 rgba(0, 0, 0, 1) 25%,
187 rgba(0, 0, 0, 0) 37.5%);
188 mask: linear-gradient(to bottom,
189 rgba(0, 0, 0, 0) 0%,
190 rgba(0, 0, 0, 1) 12.5%,
191 rgba(0, 0, 0, 1) 25%,
192 rgba(0, 0, 0, 0) 37.5%);
193 }
194
195 .gradient-blur > div:nth-of-type(1) {
196 z-index: 2;
197 backdrop-filter: blur(1px);
198 -webkit-mask: linear-gradient(to bottom,
199 rgba(0, 0, 0, 0) 12.5%,
200 rgba(0, 0, 0, 1) 25%,
201 rgba(0, 0, 0, 1) 37.5%,
202 rgba(0, 0, 0, 0) 50%);
203 mask: linear-gradient(to bottom,
204 rgba(0, 0, 0, 0) 12.5%,
205 rgba(0, 0, 0, 1) 25%,
206 rgba(0, 0, 0, 1) 37.5%,
207 rgba(0, 0, 0, 0) 50%);
208 }
209
210 .gradient-blur > div:nth-of-type(2) {
211 z-index: 3;
212 backdrop-filter: blur(2px);
213 -webkit-mask: linear-gradient(to bottom,
214 rgba(0, 0, 0, 0) 25%,
215 rgba(0, 0, 0, 1) 37.5%,
216 rgba(0, 0, 0, 1) 50%,
217 rgba(0, 0, 0, 0) 62.5%);
218 mask: linear-gradient(to bottom,
219 rgba(0, 0, 0, 0) 25%,
220 rgba(0, 0, 0, 1) 37.5%,
221 rgba(0, 0, 0, 1) 50%,
222 rgba(0, 0, 0, 0) 62.5%);
223 }
224
225 .gradient-blur > div:nth-of-type(3) {
226 z-index: 4;
227 backdrop-filter: blur(4px);
228 -webkit-mask: linear-gradient(to bottom,
229 rgba(0, 0, 0, 0) 37.5%,
230 rgba(0, 0, 0, 1) 50%,
231 rgba(0, 0, 0, 1) 62.5%,
232 rgba(0, 0, 0, 0) 75%);
233 mask: linear-gradient(to bottom,
234 rgba(0, 0, 0, 0) 37.5%,
235 rgba(0, 0, 0, 1) 50%,
236 rgba(0, 0, 0, 1) 62.5%,
237 rgba(0, 0, 0, 0) 75%);
238 }
239
240 .gradient-blur > div:nth-of-type(4) {
241 z-index: 5;
242 backdrop-filter: blur(8px);
243 -webkit-mask: linear-gradient(to bottom,
244 rgba(0, 0, 0, 0) 50%,
245 rgba(0, 0, 0, 1) 62.5%,
246 rgba(0, 0, 0, 1) 75%,
247 rgba(0, 0, 0, 0) 87.5%);
248 mask: linear-gradient(to bottom,
249 rgba(0, 0, 0, 0) 50%,
250 rgba(0, 0, 0, 1) 62.5%,
251 rgba(0, 0, 0, 1) 75%,
252 rgba(0, 0, 0, 0) 87.5%);
253 }
254
255 .gradient-blur > div:nth-of-type(5) {
256 z-index: 6;
257 backdrop-filter: blur(16px);
258 -webkit-mask: linear-gradient(to bottom,
259 rgba(0, 0, 0, 0) 62.5%,
260 rgba(0, 0, 0, 1) 75%,
261 rgba(0, 0, 0, 1) 87.5%,
262 rgba(0, 0, 0, 0) 100%);
263 mask: linear-gradient(to bottom,
264 rgba(0, 0, 0, 0) 62.5%,
265 rgba(0, 0, 0, 1) 75%,
266 rgba(0, 0, 0, 1) 87.5%,
267 rgba(0, 0, 0, 0) 100%);
268 }
269
270 .gradient-blur > div:nth-of-type(6) {
271 z-index: 7;
272 backdrop-filter: blur(32px);
273 -webkit-mask: linear-gradient(to bottom,
274 rgba(0, 0, 0, 0) 75%,
275 rgba(0, 0, 0, 1) 87.5%,
276 rgba(0, 0, 0, 1) 100%);
277 mask: linear-gradient(to bottom,
278 rgba(0, 0, 0, 0) 75%,
279 rgba(0, 0, 0, 1) 87.5%,
280 rgba(0, 0, 0, 1) 100%);
281 }
282
283 .gradient-blur::after {
284 content: "";
285 z-index: 8;
286 backdrop-filter: blur(64px);
287 -webkit-mask: linear-gradient(to bottom,
288 rgba(0, 0, 0, 0) 87.5%,
289 rgba(0, 0, 0, 1) 100%);
290 mask: linear-gradient(to bottom,
291 rgba(0, 0, 0, 0) 87.5%,
292 rgba(0, 0, 0, 1) 100%);
293 }
294</style>
295```
296
297## Customization knobs
298- Direction: flip `to top` ↔ `to bottom`.
299- Height: adjust `.gradient-blur` height percentage.
300- Strength: change blur values (0.5px → 64px).
301- Steps: add/remove layers to control smoothness.
302
303## Common pitfalls
304- `backdrop-filter` needs content behind it; it will not blur a flat background.
305- High blur values are GPU-heavy; reduce steps on low-end devices.
306- Ensure `pointer-events: none` stays to avoid blocking clicks.
307
308## Questions to ask when specs are missing
309- Should the blur start from the top or bottom?
310- How tall should the blur area be?
311- Is performance a concern on lower-end devices?