Backgrounds✨ Premium

Halftone Effect

Pure two-state SVG filter: smooth gradient at rest, halftone pattern via posterisation and erosion on hover — fluid transition, zero JavaScript.

SVG FilterHoverHalftone

You'll get access to the interactive demo with a free account.

This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Backgrounds has 50 effects, including 6 free. Explore the category →

3 usage examples

Full-screen hero — Interactive halftone background — Halftone Effect example 1

① Full-screen hero — Interactive halftone background

WhenA full-width hero section or landing page where the gradient background is itself the visual subject — users discover the effect as they move the cursor.
WhyThe gradient spans the entire surface, giving the halftone filter the space it needs to produce a legible, striking pattern. Overlay text sits outside the filter and stays crisp.
SettingsfeComponentTransfer 6 values → 3 values; feMorphology radius 1 → 5; 135° violet–pink–amber gradient (#6366f1 / #ec4899 / #f59e0b) for maximum posterised-band richness.
Editorial card — Visual header with halftone reveal — Halftone Effect example 2

② Editorial card — Visual header with halftone reveal

WhenA card component (article, project, profile) whose coloured header transforms into a halftone on hover, within a content grid.
WhyContained within a small surface, the effect is subtle at rest and striking on hover — it visually singles out the focused card without being aggressive.
SettingsfeMorphology radius 1 → 6 for stronger contrast on a small surface; gradient matching the product colour palette; transition .3s for a snappier response.
Event poster — Risograph texture on hover — Halftone Effect example 3

③ Event poster — Risograph texture on hover

WhenA large digital banner for a festival, exhibition, or concert: the poster covers the full surface and hovering reveals a halftone pattern evoking screen-print texture.
WhyThe effect's print/screen-print register is used in its natural context — an event poster justifies the large surface and ties the hover gesture to the 'discovery' of a printed texture, coherent with cultural and artistic visual languages.
Settings160° coral–pink–violet gradient (#f97316 / #ec4899 / #7c3aed) for a risograph look; feMorphology radius 2 → 8 for a coarser, more assertive pattern on a large surface; feComponentTransfer 5 values → 3 values.

How it works

The effect is entirely declarative — zero JavaScript. A hidden off-screen <svg> element defines two named <filter> elements, and CSS switches between them on hover via filter: url(#halftone-filter) (rest) and filter: url(#halftone-filter-hover) (hover).

feComponentTransfer with feFuncR/G/B type="discrete" quantizes each colour channel into discrete steps. At rest, 6 values (0 0.2 0.4 0.6 0.8 1) lightly posterize the gradient into bands. On hover, 3 values (0 0.5 1) reduce the spectrum to three sharp colour blocks — each pixel snaps to black, mid-tone, or full colour.

feMorphology operator="erode" then erodes the coloured regions inward by radius pixels. With radius="1" at rest the effect is barely noticeable. With radius="5" on hover, erosion carves spaces between the posterized blocks: on a 135° gradient, bands shrink into isolated lines or dots, producing the visible halftone pattern.

The visual transition is handled by transition: filter .4s in pure CSS. Both <filter> elements coexist in the DOM, and the browser interpolates the render between rest and hover states without any script.

Accessibility

  • No prefers-reduced-motion support in the provided code — the filter .4s transition fires on hover without checking the OS preference. For accessible projects add @media (prefers-reduced-motion: reduce) { .halftone-content { transition: none } }.
  • No automatic looping animation: the effect is only active while the user hovers — no requestAnimationFrame or timer runs in the background.
  • The base code exposes no ARIA attributes on the container. If the background is purely decorative, add aria-hidden="true" to the filter <svg> and the .halftone-container; if it is semantic, use role="img" and aria-label.
  • White text contrast on the default violet–pink–amber gradient exceeds 4.5:1 on dark areas (violet) but may drop below that on light areas (amber) — check with a contrast tool before changing the palette.
  • The SVG filter creates no spurious focusable elements: the tab order remains intact.

Browser compatibility

Requires SVG Filter Effects (feComponentTransfer, feMorphology) — natively supported in all modern browsers since 2015.

Chrome 18+✓ Full
Firefox 35+✓ Full
Safari 6+✓ Full
Edge 18+✓ Full
Mobile iOS✓ Full
Android Chrome✓ Full

If <code>filter: url(#id)</code> is not recognised (IE11), the gradient renders without the halftone effect — no JS errors, the page stays functional.

The code

HTML structure to paste into your page (CSS + JS available with a premium account):

index.html — structure
<svg aria-hidden="true" style="position:absolute;width:0;height:0">
  <defs>
    <filter id="halftone-filter"><!-- feComponentTransfer discrete + feMorphology erode radius="1" --></filter>
    <filter id="halftone-filter-hover"><!-- feComponentTransfer discrete + feMorphology erode radius="5" --></filter>
  </defs>
</svg>
<div class="halftone-container">
  <div class="halftone-content">
    <!-- text overlay or empty (gradient only) -->
  </div>
</div>
🔒 Unlock the full code — from €2.99 the first month

Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
background (CSS .halftone-content) linear-gradient(135deg, #6366f1, #ec4899, #f59e0b) Gradient colours and angle. Replace with your brand palette or with background-image: url(…) — the SVG filter applies to the final rendered output regardless of the background type.
135deg (gradient angle) 135deg Gradient direction and therefore the orientation of halftone bands: 0° = top→bottom, 90° = left→right, 45° = reverse diagonal.
tableValues (feComponentTransfer — rest) "0 0.2 0.4 0.6 0.8 1" Posterisation steps at rest. 6 values = fine bands, subtle effect. Add intermediate values for more refinement; reduce for a bolder graphic look.
tableValues (feComponentTransfer — hover) "0 0.5 1" Steps on hover. "0 1" = full binarisation (black/white), very strong. "0 0.33 0.67 1" = 4 blocks, softer. Calibrate to the desired intensity.
radius (feMorphology — rest) 1 Erosion at rest in pixels. 0 is invalid (use 0.5+); 1–2 is nearly invisible; 3+ thins the bands even in the rest state.
radius (feMorphology — hover) 5 Erosion on hover. 3 = subtle halftone, 5–7 = well-separated bands or dots, 10+ = nearly invisible (avoid). Calibrate to the container size.
transition: filter .4s (CSS) .4s Duration and easing of the transition between states. .2s = near-instant response, .8s ease-in-out = progressive cinematic morphing.

FAQ

filter: url(#halftone-filter) applies to the element's final rendered output regardless of source: <img>, background-image: url(…), or <video>. Replace background: linear-gradient(…) on .halftone-content with your image and the SVG filter applies identically.
feMorphology erode with a decimal radius (e.g. 2.5) is rounded differently by each SVG engine. Use integer values (1, 2, 3…) for consistent cross-browser output. Minor quantisation differences in feComponentTransfer are normal and expected.
Remove the rule .halftone-container:hover .halftone-content { filter: url(#halftone-filter-hover) } and point the rest CSS directly at #halftone-filter-hover, or define a third <filter id="halftone-static"> with your desired permanent values and assign it to .halftone-content.