13

I'm looking for a technique where we could programmatically pick the best color contrast to apply on text over HTML elements of different (unpredictable) background colors.

Since the HTML elements will have different colors, we're looking for a technique that will be able to determine what is the color of the content behind the text, and then adapt the text's color to use the one with the best contrast.

I'm quite sure this can't be CSS only, I've looked for Jquery solutions but couldn't find any... anyone has a clue?

[UPDATE] : Based on the first replies, I guess I need to rephrase. Imagine that I'm building a image sharing service and I want to allow people to tag on the pictures themselves. The pictures can be of any color. How can I pick up the right color of the tags, for each different picture?

1

6 Answers 6

14

I think this might save any future researchers a little time, this works perfectly for me. Plug in the red green and blue values into the function and it outputs "dark-text" or "light-text".

var darkOrLight = function(red, green, blue) { var brightness; brightness = (red * 299) + (green * 587) + (blue * 114); brightness = brightness / 255000; // values range from 0 to 1 // anything greater than 0.5 should be bright enough for dark text if (brightness >= 0.5) { return "dark-text"; } else { return "light-text"; } } 

Using some code from http://particletree.com/notebook/calculating-color-contrast-for-legible-text/ from @David's answer.

Sign up to request clarification or add additional context in comments.

1 Comment

Have a look to this JQuery plugin github.com/joggink/jquery-colorcontrast which seems to implement the said function. Be careful (currently) the plugin is not iterating ; you need to call 'each' by yourself
2

Take a look at http://www.0to255.com . Just a moment's glance at the gradients the site presents will light you right up. You'll have to puzzle, but only for about 20 seconds. It's a great site for such problems and a terrific source of ideas for programmatic solutions. And there's no math involved: just plug in some bytes for rgb vals and go.

4 Comments

+1 for the useful resource, although i'm not sure it particularly answers the question!
Thanks for the link, but that doesn't say how I can actually get the color under the text!
Ah, yes. I see now that I jumped ahead. You have to use Javascript and DHTML and DOM. In Javascript, find the object whose text color you are going to need to change; extract the background-color attribute from that object; and then proceed to choose a color for the tag text. Is that closer to the answer you're looking for?
@Julien Genestoux -- As to images: personally, I would never even think of trying to integrate colors in a photograph to produce a kind of composite background-color against which to display tag text in a contrasting color. Instead, I would always put a blob of white on top of the photo and display black tag text on that white blob. Just my opinion; there are without doubt cool algorithms that will calculate a good approximation of a average background color. Nut, just speaking for myself, I would not attempt such a thing.
2

There is now a property called mix-blend-mode in CSS (currently just in draft) that can be used to achieve something similar to what you want.

.contrasting-text { mix-blend-mode: difference; } 

CodePen someone has put together demonstrating this: https://codepen.io/thebabydino/pen/JNWqLL

Comments

0

This is my fav resource to calculate the "readability" (contrast ratio) of two colors.

the W3C suggests a contrast ratio of at least 5:1 exists between text and background behind the text http://www.w3.org/TR/2007/WD-WCAG20-TECHS-20070517/Overview.html#G18

From the page:

The compliance rate shown above is the highest compliance rate met. The WCAG 2.0 level AA and proposed Section 508 refresh compliance level is based on achieving a contrast ratio of 3:1 for text with a size of 18 points (14 points if bolded) or larger or 4.5:1 for text with a size less than 18 points. The WCAG 2.0 level AAA compliance level is meet when a contrast ration of 7:1 is achieved for text less than 18 points and 4.5:1 for text 18 points (14 points if bolded) or larger.

4 Comments

Sorry, but that's not answering the question. Yes, that would be if I was able to tell the color under my text, but I'm not. How can I?
You can read out the current background color of the element using JavaScript: $('.myclass').css('background-color') with that value you can calculate the contrast level of any other color. I'm assuming you want to use jQuery since you mentions looking for it.
2 problems : how do I determine the "myid"? What if it's an image?
If your background is an image, I would not try to automate processing the colors client side (with canvas) - I'd look at a server side solution as it will have less cross browser issues and scale better.
0

Here's another approach I got from GitHub where they apply on the color of issue's labels. It actually relies on CSS custom properties with some calculations.

.hx_IssueLabel { --label-r:0; --label-g:0; --label-b:0; --lightness-threshold:0.453; --perceived-lightness:calc(((var(--label-r) * 0.2126) + (var(--label-g) * 0.7152) + (var(--label-b) * 0.0722)) / 255); --lightness-switch:max(0, min(calc((var(--perceived-lightness) - var(--lightness-threshold)) * -1000), 1)); background:rgb(var(--label-r), var(--label-g), var(--label-b)); color:hsl(0, 0%, calc(var(--lightness-switch) * 100%)); } 

You will need to set the RGB channel separately in custom properties for the background color, then the text color will run from black to white by changing the lightness channel in HSL color. The lightness is calculated by an algorithm that receives RGB as inputs.

Comments

-1

In just one line this solves the problem:

function getContrast50($hexcolor) { return (hexdec($hexcolor) > 0xffffff/2) ? 'white':'black'; } 

If the contrast need to be reversed just swicth white with black and it does the trick. In php.

1 Comment

As previous comment states, this is PHP code, not Javascript. hexdec function exists in PHP, not in JS

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.