I'm facing the problem that users can change background colours for HTML components which sometimes conflict with text colours they can't change (or more generally, background and text colour are visually too similar). As a result, the text may become invisible (or difficult to see) if those colours are visually close enough.
See below where's there's a triangle (=text)...
...which only becomes more visible on hover.
(the user could also have also opted for a grey background which would have made this even worse)
I've tried to tinker with filters (e.g. filter: brightness(50%) contrast(150%);
or filter: saturate(0) grayscale(1) brightness(.7) contrast(1000%) invert(1)
as suggested here), but that's sensitive to the selected colours (i.e. may not work in all cases of background and text colour combinations). Is there a way (in CSS, without JS as shown here) that would change the text colour slightly (ideally, the "type of colour" itself is somewhat maintained), so that text on conflicting (too close) background and text colours becomes visible?
I realise that this question is asking for 2 things (1. detecting the conflict and 2. resolving the conflict by applying some sort of filter (or others)). If some suggestions are made for how to resolve the conflicting colours (2.), I'd already be happy.
mix-blend-mode: difference
Without mix-blend-mode: difference;
With mix-blend-mode: difference;
This article demonstrates a CSS method for switching the (text) color between black and white based on the (perceived) luminance of the background color. So it’s not exactly what you’re asking for, but it’s close.
A simpler alternative you could consider is using a contrasting text-shadow
to improve readability when the text and background colours are similar.
:root {
--clr-white-80: rgb(255 255 255 / 0.8);
}
body {
background: lightsalmon;
font-size: 2.5em;
}
p {
color: peru;
margin: 0;
}
.p2 {
text-shadow: 0 0 5px var(--clr-white-80);
}
.p3 {
text-shadow: 0 0 20px var(--clr-white-80);
}
.p4 {
text-shadow: 2px 2px 0 var(--clr-white-80);
}
<p class="p1">Is this readable?</p>
<p class="p2">What about now?</p>
<p class="p3">Or with a larger spread</p>
<p class="p4">Or with an offset</p>