A CSS halftone pattern is one repeating gradient
Each dot is a radial-gradient that is solid up to the dot radius and transparent half a pixel later. background-size sets the cell, so the browser tiles the dot into a grid. The extra half pixel keeps the edges smooth.
.halftone {
background-image: radial-gradient(circle, #1f3a5f 3px, transparent 3.5px);
background-size: 14px 14px;
mask-image: linear-gradient(to bottom, #000 15%, transparent);
}
The halftone effect comes from the fade
Printed halftone fades by shrinking dots. In CSS, a mask-image gradient fades the pattern instead: the dots stay solid where the mask is black and disappear where it turns transparent. Choose a linear direction, or fade to the edges with a radial mask. "Solid until" sets how much of the area keeps full dots before the fade starts.
Rotating the screen angle
A gradient grid cannot rotate on its own, so for any angle other than 0° the dots move to a ::before layer that is rotated with transform. The layer is a square as wide as the host's width plus height, which covers the host at every angle. The mask stays on the parent, so the fade direction does not rotate with the dots. A 45° grid is the classic halftone look.
Browser support
radial-gradient, mask-image and SVG patterns work in all current versions of Chrome, Edge, Firefox and Safari. The rotated CSS layer uses container query units (cqw, cqh), supported since 2023. The generated CSS also includes the -webkit-mask-image prefix for older Safari.