Auto-Contrast Font Color to Background

Auto-contrast Font Color to Background

More as an experiment than otherwise:

Set the text with a background inherit, to get the background of the base; then clip it to the text, and then apply some filters to it:

.test {
width: 800x;
height:220px;
font-size: 200px;
background-image: url(bosque.jpg);
color: white;
position: relative;
}

.inner {
position: relative;
background-image: inherit;
-webkit-background-clip: text;
color: transparent;
-webkit-filter: invert() sepia();
}

fiddle

(Only working in webkit)

Check also this ones:

animated madness

contrast animation

UPDATE: We have new ways to handle this. See a demo using mix-blend-mode: difference

div {  font-size: 300px;  color: gray;  mix-blend-mode: difference;}body {  background-image: url(http://placekitten.com/900/600);}
<div>TEST</div>

Contrast minimum for background color if the bg conveys meaning

Yes your icon would be counted as part of a control.

It is covered under Success Criterion 1.4.11: Non-text Contrast

Technique G207 has all the info you need, but basically a contrast ratio of 3:1 with surroundings is not necessary (but preferable) and a contrast ratio of 3:1 for the icon with the background is what you need.

Also just for clarity, ensure that "fail status" has a different icon etc. Don't use just colour for meaning (I am sure you know this just how I read your question made me just double check! "since the green color conveys success status") in case someone is colour blind.

invert text color based on background in css

You could also apply this styling to the element you'd like to invert the colors of:

filter: invert(1);
mix-blend-mode: difference;

It especially works if you need to base the difference on a child or a element further away, not a parent or a close element.

I used it with a custom cursor (the black circle), which made it contrast nicely with the elements behind. Sample pen here: https://codepen.io/m3t4lch7/pen/VwwOKNd

Cursor with inverted colors

How to decide font color in white or black depending on background color?

Building on my answer to a similar question.

You need to break the hex code into 3 pieces to get the individual red, green, and blue intensities. Each 2 digits of the code represent a value in hexadecimal (base-16) notation. I won't get into the details of the conversion here, they're easy to look up.

Once you have the intensities for the individual colors, you can determine the overall intensity of the color and choose the corresponding text.

if (red*0.299 + green*0.587 + blue*0.114) > 186 use #000000 else use #ffffff

The threshold of 186 is based on theory, but can be adjusted to taste. Based on the comments below a threshold of 150 may work better for you.


Edit: The above is simple and works reasonably well, and seems to have good acceptance here at StackOverflow. However, one of the comments below shows it can lead to non-compliance with W3C guidelines in some circumstances. Herewith I derive a modified form that always chooses the highest contrast based on the guidelines. If you don't need to conform to W3C rules then I'd stick with the simpler formula above. For an interesting look into the problems with this see Contrast Ratio Math and Related Visual Issues.

The formula given for contrast in the W3C Recommendations (WCAG 2.0) is (L1 + 0.05) / (L2 + 0.05), where L1 is the luminance of the lightest color and L2 is the luminance of the darkest on a scale of 0.0-1.0. The luminance of black is 0.0 and white is 1.0, so substituting those values lets you determine the one with the highest contrast. If the contrast for black is greater than the contrast for white, use black, otherwise use white. Given the luminance of the color you're testing as L the test becomes:

if (L + 0.05) / (0.0 + 0.05) > (1.0 + 0.05) / (L + 0.05) use #000000 else use #ffffff

This simplifies down algebraically to:

if L > sqrt(1.05 * 0.05) - 0.05

Or approximately:

if L > 0.179 use #000000 else use #ffffff

The only thing left is to compute L. That formula is also given in the guidelines and it looks like the conversion from sRGB to linear RGB followed by the ITU-R recommendation BT.709 for luminance.

for each c in r,g,b:
c = c / 255.0
if c <= 0.04045 then c = c/12.92 else c = ((c+0.055)/1.055) ^ 2.4
L = 0.2126 * r + 0.7152 * g + 0.0722 * b

The threshold of 0.179 should not be changed since it is tied to the W3C guidelines. If you find the results not to your liking, try the simpler formula above.

How to change Text color depending on background so that there is good contrast between the two colors

you can use computeLuminance() of Color class. Something like this:

@override
Widget build(BuildContext context) {
var backgroundColor = Colors.orange; // this color could be anything
var foregroundColor = backgroundColor.computeLuminance() > 0.5 ? Colors.black : Colors.white;

return Scaffold(
body: Center(
child: Container(
padding: const EdgeInsets.all(12),
color: backgroundColor,
child: Text("Hello World", style: TextStyle(color: foregroundColor)),
),
),
);
}

Of course you need to play around with the luminance IF-statement ... 1.0 is white and 0.0 is black. Yellow for instance is something about 0.8.

Change text color based on brightness of the covered background area?

Interesting resources for this:

  • W3C - Ensure that foreground and background color combinations provide sufficient contrast
  • Calculating the Perceived Brightness of a Color

Here's the W3C algorithm (with JSFiddle demo too):

const rgb = [255, 0, 0];
// Randomly change to showcase updatessetInterval(setContrast, 1000);
function setContrast() { // Randomly update colours rgb[0] = Math.round(Math.random() * 255); rgb[1] = Math.round(Math.random() * 255); rgb[2] = Math.round(Math.random() * 255);
// http://www.w3.org/TR/AERT#color-contrast const brightness = Math.round(((parseInt(rgb[0]) * 299) + (parseInt(rgb[1]) * 587) + (parseInt(rgb[2]) * 114)) / 1000); const textColour = (brightness > 125) ? 'black' : 'white'; const backgroundColour = 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')'; $('#bg').css('color', textColour); $('#bg').css('background-color', backgroundColour);}
#bg {  width: 200px;  height: 50px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="bg">Text Example</div>


Related Topics



Leave a reply



Submit