styled-components / polished

A lightweight toolset for writing styles in JavaScript ✨
https://polished.js.org/
MIT License
7.63k stars 209 forks source link

Calculating color lightness with YIQ #224

Closed ravinggenius closed 7 years ago

ravinggenius commented 7 years ago

This is a feature request.

I have found YIQ to be an excellent algorithm for calculating the apparent lightness of a color. I would like to have a function isLight(color) which implements YIQ (just returns true or false). A second function would also be helpful for picking an appropriate contrast for a given color, maybe ifIsLight(color, light = '#000', dark = '#FFF').

I'm happy to provide the implementation if there is interest. I find myself having to implement this in nearly every project I'm on these days.

bhough commented 7 years ago

Hi @ravinggenius I believe we already have a solution about to be released for this using the W3C spec for contrast. Take a look at #185 and to #163 and let me know if that handles your use case. Hoping to get those finished up and merged in this week.

ravinggenius commented 7 years ago

I don't think #192 is using the same algorithm (YIQ), but the goal appears to be the same. Really what I'm after is the ability to pass in a background color and know if I should use dark or light text.

I'm closing this with the assumption #192 will work for me, though I would prefer arguments to customize the return value.

bhough commented 7 years ago

@ravinggenius Are you wanting to customize the color format you want returned?

ravinggenius commented 7 years ago

Not really. I was thinking it might be useful to accept optional values to return instead of always black or white. So instead of this...

const readableColor = (backgroundColor) => {
  // ...
  return isLight ? 'black' : 'white';
};

Allow passing (optional) dark/light colors, but default to black/white...

const readableColor = (backgroundColor, dark = 'white', light = 'black') => {
  // ...
  return isLight ? light : dark;
};
LawJolla commented 7 years ago

@ravinggenius I thought about that implementation (I normally use gray instead of black), but given how easy it is to write a wrapper function, I think the simplicity of black or white is clearer.

const colorWrapper = readableColor(color) === '#000' ? '#333' : '#999'