Backgrounds✨ Premium

Duotone Image Filter

On hover, grayscale + contrast desaturates the content and a mix-blend-mode: color gradient overlay tints it in two tones — any visual as duotone, pure CSS.

CSSBlend ModeFilter

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

Portfolio gallery — Visual cards in brand duotone — Duotone Image Filter example 1

① Portfolio gallery — Visual cards in brand duotone

WhenA project or artwork grid displays heterogeneous visuals: the user hovers a card to see the signature brand color.
WhyDuotone instantly applies brand identity to any visual — neutral tones at rest let varied images coexist; hover reveals a unifying color without changing the layout.
SettingsGradient indigo → pink (135deg, #6366f1, #ec4899). contrast(1.3) for deeper blacks. Transition 0.4s for a snappy response.
Hero section — Abstract background in full-zone duotone — Duotone Image Filter example 2

② Hero section — Abstract background in full-zone duotone

WhenA landing page hero with a background of colored shapes or textures shifts to brand colors as soon as the pointer enters the zone.
WhyOn a large surface, the effect creates a strong atmosphere change without moving a single element — the page stays quiet at rest, the hover reveals brand color unexpectedly.
SettingsBrand gradient (e.g. #0ea5e9 → #7c3aed). Transition 0.8s for a cinematic fade. grayscale(0.85) for a partial, softer duotone.
Team card — Avatar in brand duotone on hover — Duotone Image Filter example 3

③ Team card — Avatar in brand duotone on hover

WhenA 'Our team' page lists portraits or illustrations: hovering a card tints the visual in brand colors.
WhyDuotone unifies heterogeneous portraits under a common brand treatment and delivers a sophisticated visual response without movement or card-flip effects.
SettingsPrimary → secondary gradient from your design system. contrast(1.1). Transition 0.5s. Place card text outside .duotone-content so it is not filtered.

How it works

On hover of .duotone-container, two CSS rules fire simultaneously. .duotone-content receives filter: grayscale(1) contrast(1.2): all pixels are converted to greyscale, then contrast is amplified to widen the gap between light and dark areas — the raw material for a duotone.

The overlay .duotone-overlay, positioned absolute with inset: 0, transitions from opacity: 0 to 1. It carries mix-blend-mode: color and background: linear-gradient(135deg, #6366f1, #ec4899). This blend mode applies the hue and saturation of the gradient layer to the luminance of the desaturated content below: light tones take the color of one gradient end, dark tones the other — the photographic duotone effect.

The two transitions are independent: transition: filter .6s on .duotone-content and transition: opacity .6s on .duotone-overlay. pointer-events: none on the overlay ensures it never captures mouse events. No JavaScript is involved: everything relies on the CSS cascade and the :hover pseudo-class.

Accessibility

  • No @media (prefers-reduced-motion) in the code — the filter and opacity transitions (0.6 s) still run even when the OS requests reduced motion. Add this manually based on your audience.
  • The effect relies solely on :hover — no :focus or :focus-within pseudo-class. Keyboard users cannot trigger the duotone in its current form.
  • mix-blend-mode: color changes displayed colors but not the semantic structure: screen readers access text and ARIA roles normally, independently of the effect.
  • The .duotone-container carries no role or aria-label — if the visual conveys information, add role="img" aria-label="…".
  • The .duotone-label (white text on dark background) meets WCAG AA at rest. Under the active color overlay, verify the contrast ratio with your specific duotone colors.

Browser compatibility

Requires CSS filter level 1 and mix-blend-mode — both supported in modern browsers since 2016–2017. Zero external dependencies.

Chrome 41+✓ Full
Firefox 35+✓ Full
Safari 9.1+✓ Full
Edge 79+✓ Full
Mobile iOS 9.1+✓ Full
Android Chrome✓ Full

On Edge < 79 (no <code>mix-blend-mode</code>), content turns greyscale on hover but without a color tint — the overlay renders as an opaque solid rectangle. On IE 11, <code>filter</code> is not supported: hover has no visual effect. No JS error in either case.

The code

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

index.html — structure
<div class="duotone-container">
  <div class="duotone-content">
    <!-- Insert here: img, video, CSS shapes, SVG… -->
  </div>
  <div class="duotone-overlay"></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 on .duotone-overlay linear-gradient(135deg, #6366f1, #ec4899) The two duotone colors and the gradient angle. Replace hex values with your brand colors; change the angle (0deg → 180deg) for direction.
mix-blend-mode on .duotone-overlay color Blend mode. color = hue+saturation from the layer onto the luminance below. Alternatives: hue (without saturation), multiply (darkens), overlay (strong contrast).
grayscale() in filter on :hover grayscale(1) Desaturation level from 0 to 1. Reduce to 0.7–0.9 for a partial duotone that lets original colors show through.
contrast() in filter on :hover contrast(1.2) Contrast boost. Raise to 1.4–1.5 for deep blacks and bright whites; lower to 1.0 for a neutral effect.
opacity on .duotone-container:hover .duotone-overlay 1 Color tint intensity. Reduce to 0.6–0.8 for a subtle tint that lets original colors show through beneath.
transition-duration on filter and opacity .6s Hover transition length. .3s = snappy, 1s = slow fade. Update both values to keep them in sync.

FAQ

Yes. Place any <img>, <video>, <svg>, or HTML block inside .duotone-content — the CSS filter applies to the entire rendered subtree. Caveat: cross-origin images without a CORS header may not be filtered in some browsers (canvas/CSS security restriction). Content inside an <iframe> is also inaccessible to the parent CSS.
The code uses only :hover. For keyboard accessibility, add :focus-within in parallel: .duotone-container:hover .duotone-content, .duotone-container:focus-within .duotone-content { filter: grayscale(1) contrast(1.2) } — and make the container focusable with tabindex="0" or ensure an interactive element (link, button) is inside.
Replace the gradient with a solid color on .duotone-overlay: background: #6366f1. Light pixels take that hue, dark pixels stay dark (mix-blend-mode: color preserves luminance). For a saturated monochrome with mix-blend-mode: multiply, the overlay background must be white — light areas stay white, dark areas take the tint.