-3

Let's suppose I have a td, like this:

<td class="nice-text">Cell Text</td>

I would like to make sure that my text is visible, whatever the background of the td is. If we suppose that the background color is stored inside data-background, like this:

<td class="nice-text" data-background="#000000"></td>

and we add the following rule to our CSS:

.nice-text[data-background=\\#000000] {
    color: white;
}

then the color will be white if #000000 is chosen. But there are extremely many colors close to #000000. Since it is clearly unfeasible to write a CSS rule for all such colors and Javascript would be used here only in case of desperation, is there a possibility to use a selector which defines a group of colors which are close to black and set color: white; for them?

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175

2 Answers2

4

is there a possibility to use a selector which defines a group of colors which are close to black

No. Selectors doesn't have any knowledge of color whatsoever.

You're going to have to write your own algorithm to determine whether the foreground color should be light or dark based on the background color. And if you're trying to get things done, that means JavaScript. If you're trying to develop a CSS-only proof-of-concept for the sake of experimentation, you can take a stab at emulating regular expressions (assuming they are, as you seem convinced, possible to implement using Selectors) and seeing if what you end up with resembles an actual color-matching algorithm and produces accurate and consistent results. If you do come up with a solution that actually works, without cheating by changing the attribute value to something that makes it as easy as writing a non-algorithmic selector, feel free to post an answer with a case study.

My point is that Selectors doesn't offer a feature that's designed for your specific use case, and whatever time that might get put into developing what is essentially a hack is probably better spent on an actual, practical solution.

I tend to not believe comments without backup info.

Look, I could link you to the spec, but I'm not going to be able to link you to any particular section of the spec, simply because the spec doesn't mention such functionality anywhere, for the sole reason that the working group never considered speccing such a feature in the first place. It is up to you whether or not you want to accept this fact. Neither I nor the authors of the spec nor the people who work on layout engines nor anyone else in the working group is obligated to justify to you or anyone else whether or not a non-existent feature would be feasible to spec, implement, test, and ship.

Of course, if you want to get really pedantic, there's technically nothing stopping the working group from proposing, say, a functional pseudo-class that takes a string that represents a color as an argument and matches elements based on the criteria you've listed above. In fact, you are free to implement Selectors yourself (or take a ready-made albeit non-standard implementation such as Sizzle) and implement such a feature if you're so inclined. But if you really want an informed opinion from an expert, it is highly unlikely that such a feature would be useful to a wide enough audience to warrant all the development time and effort on part of browser vendors or the working group.

Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • @Lajos Arpad: That doesn't mean anything. As far as Selectors is concerned the hex value is nothing more than a string of 7 arbitrary characters that happen to mean something to you. – BoltClock Jun 29 '16 at 16:59
  • @LajosArpad there is no way to select a range of colors in css using selectors – Adam Buchanan Smith Jun 29 '16 at 16:59
  • If it starts with 0, or the third number is 0 or the fifth number is 0 for instance – Lajos Arpad Jun 29 '16 at 17:00
  • **"You're going to have to write your own algorithm to determine whether the foreground color should be light or dark based on the background color."** Is exactly what needs to happen – Adam Buchanan Smith Jun 29 '16 at 17:00
  • @AdamBuchananSmith, I can write such an algorithm, but wonder whether it is possible in CSS. If you read my question, you will see that Javascript code for this purpose is just for case of desperation. – Lajos Arpad Jun 29 '16 at 17:02
  • @AdamBuchananSmith, I tend to not believe comments without backup info. – Lajos Arpad Jun 29 '16 at 17:03
  • @LajosArpad: Why not set another attribute as what you need (say whitish, blackish whatever). Since you are anyway setting attributes on color selection/change, this sounds more reasonable to me. – Harry Jun 29 '16 at 17:04
  • @Harry, I am interested about the answer to my question, not about work-arounds. – Lajos Arpad Jun 29 '16 at 17:04
  • @LajosArpad so the up-votes on this answer is not enough? Guess you will be waiting for a css answer for awhile lol – Adam Buchanan Smith Jun 29 '16 at 17:06
  • 1
    @LajosArpad: I guess you haven't realized that you already HAVE your answer. It is NOT possible with CSS. Anyways, good luck finding one that suits what you have in mind. – Harry Jun 29 '16 at 17:07
  • @Harry, I believe it is possible with regular expression in the selector – Lajos Arpad Jun 29 '16 at 17:08
  • @AdamBuchananSmith, no, science is not democracy. – Lajos Arpad Jun 29 '16 at 17:08
  • @LajosArpad good luck, be patient one day this might be possible, today is not the day. – Adam Buchanan Smith Jun 29 '16 at 17:12
  • I upvoted your answer, as it clearly describes an educated opinion, but I am not sure it is correct. – Lajos Arpad Jun 29 '16 at 18:01
0

It's possible, but not in pure CSS. If you can bring in some javascript this solution may work for you. It's not perfect, but it's pretty good. Basically, this function will evaluate the hex color that you pass it and return simply 'black' or 'white' depending on the hex.

In JavaScript:

function getContrastYIQ(hexcolor){
    var r = parseInt(hexcolor.substr(0,2),16);
    var g = parseInt(hexcolor.substr(2,2),16);
    var b = parseInt(hexcolor.substr(4,2),16);
    var yiq = ((r*299)+(g*587)+(b*114))/1000;
    return (yiq >= 128) ? 'black' : 'white';
}

I have a working example here https://jsfiddle.net/nzcyjhz3/2/

hardba11
  • 1,478
  • 15
  • 27