mix-blend-mode: Text That Recolors Itself Against Any Background
Blend modes have a reputation as Photoshop tourism, but three specific recipes earn permanent spots in real projects - plus one property (isolation) you must know before shipping any of them.
Recipe 1: self-inverting text
A fixed logo or scroll-progress label that stays readable as it passes over dark and light sections:
.fixed-label {
color: white;
mix-blend-mode: difference;
}
difference inverts against whatever is behind: white text over white background renders black, over black renders white, over a photo it becomes a high-contrast negative. Zero JavaScript scroll-detection, works mid-transition, pixel-accurate. (It's an effect - the inverted colors are funky over saturated images - but for monochrome UI chrome it's shockingly practical.)
Recipe 2: marker-pen highlights
mark {
background: #fde047;
mix-blend-mode: multiply; /* text shows THROUGH the highlight like real ink */
}
Without the blend, a background behind text just sits behind it. With multiply, the yellow darkens what's underneath the way translucent marker does - descenders and serifs stay crisp inside the highlight. Subtle, and once you see the comparison you can't unsee it.
Recipe 3: duotone images without image editing
.duotone {
background-image: url(speaker.jpg);
background-size: cover;
background-color: #4f46e5;
background-blend-mode: luminosity; /* image brightness, brand hue */
filter: grayscale(1) contrast(1.1); /* optional: tighten the effect */
}
background-blend-mode is mix-blend-mode's sibling that blends an element's own background layers together - image against tint color, no compositing with outside content. Whole team pages get on-brand treatment from arbitrary photos, in CSS, swappable per theme.
The must-know: blending leaks, isolation stops it
mix-blend-mode blends with everything behind the element in its stacking context - including the page background and elements you never intended. Symptoms: difference text inverting against the body color through a "transparent" card, effects changing when an ancestor gains a transform. The fix is scoping:
.hero {
isolation: isolate; /* new stacking context: blending stops at this boundary */
}
isolation: isolate creates a stacking context with no other side effects - the dedicated tool for "blend inside this box, not with the world". (Stacking contexts explain half of all blend-mode surprises; the full map is here.)
Support: universal for years, including background-blend-mode. Performance is fine for UI-scale use; just avoid blending enormous fixed layers during scroll on low-end mobile. Used sparingly - one difference label, marker highlights, branded imagery - blend modes read as craft rather than gimmick.
Full-stack web developer sharing practical tutorials and building tools that ship.
Got something on your mind?
My inbox is open - no forms disappearing into the void here.
- Just say hello Found a tutorial useful? Spotted a mistake? Tell me.
- Hire me for a project Have something custom in mind? Let's talk scope and timelines.
- Product support Bought something here? I'll help you get it running.
I usually reply within 1-2 business days.