Encode the hero ratio, not the full 3840x2160 plate.
How Do You Convert a 4K PNG to WebP for the Web Without Banding?
Crop first, then encode WebP at quality 80 to 90 with 4:4:4. Dither long gradients. Never ship the 12 MB PNG as the hero.
Crop the hero to the ratio you will ship, then encode that crop as WebP. For a gradient or synthwave sky, use quality 80 to 90, 4:4:4 chroma, and a light dither. For a hard-edged HUD, quality 75 to 85 is enough and the file will be small. Do not run a default "save for web" that converts to 4:2:0 and then wonder why the sunset became stripes.
The 3840x2160 PNG stays the master. The WebP is a derivative. The still-hero page decides how many crops. This page decides how those crops are encoded.
Why banding shows up, and how to see it before a client does
Banding is posterization. An 8-bit channel has 256 steps. A long, smooth ramp from #02040a to #1a3a6a over 2000 pixels only needs a handful of those steps per hundred pixels. PNG's lossless store keeps each step as a clean ridge. A lossy encoder that also subsamples chroma will merge ridges into 20-pixel stripes. You will see them on a cheap laptop in a dark room, which is exactly where a dark hero lives.
Check at 100 percent on a hardware-calibrated display if you have one, and on a phone with the brightness down. Fit-to-window hides bands. A CSS background-size: cover on a 1440p monitor will show them again.
Two different plates, two different risks:
- Soft ramps, fog, space nebula, sunset grids: high banding risk. Spend bitrate. Dither.
- 1-pixel cyan lines on black: low banding risk, high ringing risk if you over-sharpen or use a tiny quality number. Keep edges; do not dither so hard the black becomes noise.
Never encode the full 3840 width if the largest <img> is 2400. You are spending bytes on pixels the browser will throw away, and the extra area is more ramp for bands to live in. Crop first.
Stay in sRGB. A convert-to-Display-P3-then-WebP round trip is how colors shift and then band. Assume sRGB on the source and on the export.
Commands and settings that stay boring
cwebp, the reference encoder:
cwebp -q 85 -m 6 -af -sharp_yuv -metadata none input.png -o hero-1600x900.webp
-q 85 is a starting point. If you still see ridges on a ramp, go to 90 before you go to lossless. Lossless WebP of a 2400-px gradient can still be a megabyte, which may be acceptable for a flagship hero and is too much for a blog.
-sharp_yuv reduces chroma smear on cyan HUD lines. If a neon edge grows a pink fringe, this flag is the first thing to turn on.
If your build of cwebp exposes a preset, try picture or drawing for HUD plates and photo or default for ramps. Do not use the lowest preset to hit a 50 KB budget on a 2400-px sunset. Raise the budget.
Squoosh and Photoshop's "WebP (lossy, quality 80)" are fine if you watch two things: quality, and whether the tool silently converts to a smaller preview. Export at 1x the pixel size you named.
FFmpeg, when that is the tool on the machine:
ffmpeg -i input.png -c:v libwebp -q:v 85 -preset photo -pix_fmt yuva420p hero.webp
If that 4:2:0 encode bands, switch to a pipeline that can do 4:4:4, or bump quality, or add a 1-bit blue-noise dither in Photoshop (Filter > Noise > Add Noise, 0.4 to 0.8 percent, monochromatic, Gaussian) on a 16-bit copy of the ramp, then flatten to 8-bit and encode. The noise breaks the ridges. On a HUD plate, skip that noise; it dirties the black.
AVIF is a different page and a different decoder budget. If you do not have a fallback WebP or JPEG, do not ship AVIF as the only hero. This page is WebP because that is the file most CMS stacks will actually serve.
Targets that usually look honest:
- Desktop hero 2400 px wide, soft plate: 250 to 450 KB at q 85 to 90.
- Desktop hero, HUD plate: 80 to 200 KB at q 80.
- Mobile 1200 px crop: 80 to 200 KB.
- Open Graph 1200x630: JPEG quality 80 is more compatible than WebP. Different file, same crop discipline.
Strip text metadata on the WebP if the CMS displays XMP as a caption. Keep the color interpretation sRGB.
If marketing later wants motion in the same hole, use the still WebP as the poster and send them to Unique Live Wallpaper. Do not animate the WebP with a CSS filter and call it a loop.
Ramps want quality and dither. HUD lines want sharp YUV.
Banding is 8-bit ridges plus 4:2:0. Fit-to-window will lie to you.
q 85 to 90, dither a 16-bit copy, stay sRGB. Budget 250 to 450 KB at 2400 px.
q 75 to 85, sharp_yuv, no film grain on the black.
100 percent, dim room, phone and laptop. If you see stripes, raise q before you give up.