0

I've been using the contrast function for the first time and think it's buggy.

On this page, I find the following explanation:

contrast(@color1, @darkcolor, @lightcolor);
    // outputs @darkcolor, when @color1 have more than 43% Luma
    // if not it outputs @lightcolor

I have these 2 Colors:

@gBlue: #2196F3;
@gLightBlue: #03A9F4;

The first color has 60 Luma and the second one has 65 Luma. I expect Less to give me the @lightcolor for both colors. But that's not the result I'm getting!

Lessphp returns the @darkcolor for @gBlue and the @lightcolor for @gLightBlue.

Can anyone tell me why it does this? Is this a bug? Why don't I get the @lightcolor in both cases?

enter image description here

Harry
  • 87,580
  • 25
  • 202
  • 214
Shimakuro
  • 314
  • 1
  • 2
  • 10
  • 1
    Instead of a convoluted paragraph vaguely describing the input and output, can you simply post your code, the expected output, and the actual output? – deceze Sep 25 '15 at 15:16
  • 1
    As per the Less `luma` function both those colors have less than 43% luma. First is around 28% and second around 34%. Both are less than 43% and hence it should output the lightcolor. So your end expectation seems correct but the luma values given in question aren't. – Harry Sep 25 '15 at 15:16
  • @deceze i cant send the output code now. i am not alowed to send the url of our project anyone =( – Shimakuro Sep 25 '15 at 15:21
  • 1
    All we need is a small code sample, not a complete file! – deceze Sep 25 '15 at 15:21
  • @Shimakuro: I just checked in the online LessPHP compiler and it does seem to output the dark color (which is weird because the official Less.js and Less.PHP compilers seem to give the desired output). I agree with deceze's comment too, you must post atleast the relevant code block (or a minimal sample that can be shared). – Harry Sep 25 '15 at 15:23
  • Element in LightBlue: http://i.imgur.com/aTGCeFT.png (White Text) Element in Blue: http://i.imgur.com/bA9LKNH.png (Black Text) Code: http://i.imgur.com/gjXJECo.png – Shimakuro Sep 25 '15 at 15:28

1 Answers1

1

Note: The source code for v0.5.0 shows that lessphp is also now checking luma values instead of lightness (used in v0.4.0) and hence upgrading to the latest version should also solve the problem.

This doesn't seem to be a bug but rather a difference in terms of how the contrast function works in Less.js, Less.PHP and lessphp (upto v0.4.0).

In Less.js and Less.PHP, the contrast function decides on output color based on the luma value of the reference color. The luma values of the 2 colors given in question are less than 43% and hence they output the @lightcolor. You can check the output of the below code at Less2CSS.org (Online Less.js compiler) and Online Less.PHP compiler.

#sample{
  color:contrast(@color1, @darkcolor, @lightcolor);
  luma-color1: luma(@color1);
  luma-color2: luma(@color2);
}

@color1: #2196F3;
@color2: #03A9F4;
@darkcolor: black;
@lightcolor: white;

The lessphp documentation however describes the contrast function as follows: (looks like the doc is not updated with v0.5.0 changes)

contrast(color, dark, light) — if color has a lightness value greater than 50% then dark is returned, otherwise return light.

The lightness value for the first color is 54% while that for the second color is 48%. Because of this, lessphp outputs the @darkcolor when the first color is used as reference and @lightcolor when the second color is used as reference.

You can try the below code at the Online lessphp compiler for v0.4.0 to see what I mean:

#sample{
  color:contrast(@color2, @darkcolor, @lightcolor);
  lightness-color1: lightness(@color1);
  lightness-color2: lightness(@color2);
}

@color1: #2196F3;
@color2: #03A9F4;
@darkcolor: black;
@lightcolor: white;

It could very easily be that lessphp introduced the contrast function at first based on lightness value before the official Less (the JS version) compiler implemented the same function but based it on luma instead of lightness value. The below statement could be found in the Less documentation:

This function works the same way as the contrast function in Compass for SASS. In accordance with WCAG 2.0, colors are compared using their gamma-corrected luma value, not their lightness.

Harry
  • 87,580
  • 25
  • 202
  • 214
  • Ok i think i understand... but then... is the contrast function totaly useless for me =/ to much colors they are to dark for black color =/ Can i tell less php that he have to use dark color when color have 75 up to 100% luma? Ore exist any other way to tell him in this particular case, that he have to use white font color? – Shimakuro Sep 25 '15 at 15:38
  • 1
    @Shimakuro For `lessphp` you can just set explicit threshold value when you call it, e.g.: `contrast(@color2, @darkcolor, @lightcolor, @youownthreshold);`. Strictly speaking the function is somewhat weird in either Less implementation (for example in `less.js` its default `43%` is actually quite unreasonable for typical luma values because originally it was chosen for luminance values. The other weirdness is that the function compares only one color, and if it does not passes the trigger, the second color is returned regardless of its actual contrast). – seven-phases-max Sep 25 '15 at 18:35
  • @seven-phases-max: Are you sure the thresholds work in lessphp? I tried in the online compiler at Leafo and it doesn't seem to make any difference :( – Harry Sep 26 '15 at 06:44
  • 2
    @Harry It may depend on the actuall version, there're three versions wide-sppread today (legacy 0.3.9, and more up-to-date 0.4.0 and 0.5.0 - probably only 0.5.0 has modern `contrast` - I'm don't know for sure (it's better to check sources to make sure, [indeed](https://github.com/leafo/lessphp/blob/v0.4.0/lessc.inc.php#L1170) in 0.4.0 it's old version yet)). – seven-phases-max Sep 26 '15 at 08:47
  • @seven-phases-max: Yes, indeed. Thanks for the link. I saw that the v0.5.0 code actually checks for luma unlike 0.4.0 which checks for lightness (from HSL). – Harry Sep 26 '15 at 08:55