A blend mode changes how an element composites with what's painted behind it instead of simply covering it. Hightouch UI uses them sparingly and for specific jobs — they are a scalpel, not a paintbrush. Reach for one only when compositing solves a problem that a color token can't.
Two modes are in use today: multiply keeps grey surfaces legible on grey
backdrops, and luminosity renders illustrations in greyscale. normal is the
default (no blending) and the escape hatch.
The grey fill of a subtle badge, or the grey hover/active state of a ghost
(tertiary) control, is a light grey. When one of those surfaces lands on an
already-grey backdrop — a hovered table row, a highlighted menu item, a
focused list option — an opaque grey painted on top of a grey barely reads. The
element washes out and loses its shape.
mix-blend-mode: multiply fixes this by compositing the two greys into a darker
grey, so the edge stays visible — without hand-picking a second set of "on grey"
color tokens.
The subtle badge and tertiary buttons ship with this blend already applied via
the shared neutralSurfaceBlend fragment, so you don't opt in per instance:
A tertiary (ghost) button is transparent at rest, fills to gray.200 on hover,
and gray.300 on press. On a white page those greys read fine, but inside a
hovered row — which is itself grey — they'd wash out. Multiply darkens each fill
against the row so the affordance stays visible. The illustration below composites
the three fills onto a grey (base.background) row:
And live — hover the real controls on a white row (the blend is a no-op) versus a grey row (the hover fill darkens instead of vanishing):
multiply against white is the identity operation (result = source × 1), so on
the default white backgrounds these surfaces render pixel-for-pixel as they
did before. The blend only does anything once there's a non-white backdrop, and
on the very light greys we hover with (gray.50 / gray.100) the darkening is
subtle — exactly enough to keep the edge visible.
subtle badge,
the ghost (tertiary) Button / IconButton.multiply against a non-white backdrop turns a white fill transparent
(white × backdrop = backdrop). A surface that is deliberately white — the
ghost badge, or a button whose hover lifts to white — is meant to stand out
against grey, so blending would make it vanish into the row. These keep
mixBlendMode: normal and rely on their border for definition.info, success, warning, error, upsell). They
don't wash out on grey and multiply would muddy the hue.mixBlendMode="normal".EmptyState renders its illustration in greyscale when imageFilter is set to
"blackAndWhite", using mix-blend-mode: luminosity. Luminosity keeps the
image's light-and-dark structure while taking its color from the surface behind
it — so a full-color illustration reads as a calm, monochrome graphic that sits
quietly inside the empty state.
Compare the same illustration with the filter unset (full color) and set to
blackAndWhite:
Everything not listed above uses normal (no blend). It's also how you opt a
single instance out of a blend it would otherwise inherit — for example a
subtle badge placed on a dark or saturated surface:
subtle badges and tertiary buttons —
it's automatic.mixBlendMode="normal" when a neutral surface sits on a
dark or saturated background.multiply to a surface with an explicit white fill — it will
disappear against grey.multiply to saturated (intent-colored) surfaces — it muddies
the hue.