Fixes Tint, Shade, and Contrast Alpha Interference Issue #26
Conversation
poke @ianstormtaylor |
@ianstormtaylor any progress? |
@ianstormtaylor I guess you are super busy and you maybe don't do css anymore. Could you add collaborator to this module and transfert it maybe? |
Oh shoot for some reason I thought that you were a collaborator on this one already @MoOx! I'm definitely happy to add you and anyone else who wants to maintain it. |
Excellent, thanks @ianstormtaylor. I need to take another look at this to refresh my memory on what I was up to. But @MoOx you wanna give this another look and a |
My time is limited but I gave a quick look: it seems you know what you are talking about, so I will go for merge if you are still confident that this PR is a proper bugfix. |
Finally had a look at this to get myself back up to speed. All looks good. Tests still passing. Gonna merge. |
The problem
The
tint
,shade
, andcontrast
adjusters incorrectly modify the alpha value of the base color.Current results:
Expected results:
From usage and reading the spec, I expected
tint
,shade
, andcontrast
to leave the alpha value of the base color as is.The cause
These three adjusters make use of
Color.mix
. Tint and shade do so here https://github.com/ianstormtaylor/css-color-function/blob/master/lib/adjusters.js#L41 and contrast here https://github.com/ianstormtaylor/css-color-function/blob/master/lib/adjusters.js#L82Looking at Qix-/color, the
mix
method is ported from the Sassmix
https://github.com/Qix-/color/blob/0.11.3/index.js#L295 According to the Sass docs http://sass-lang.com/documentation/Sass/Script/Functions.html#mix-instance_method themix
method mixes color channels and the alpha channel.Reading through the Color Level 4 spec, it seems like the only adjusters that should modify the alpha value of the base color are
alpha
andblenda
.My solution in this PR
First, I wrote failing tests for tint, shade, and contrast. A thing to note about both Tint and Shade is that order mattered. If
tint
/shade
came beforealpha
, the expected result was produced. Ifalpha
came first, the unexpected value was produced.Code changes; What I did in both the
blend
method and within thecontrast
method was hold on to the initial alpha value of the base color. Then set the alpha to1
, then callColor.mix
. After themix
was complete, set the alpha back to the initial alpha value.This ensures
Color.mix
does not attempt to mix an alpha value less than one.Background
I first hit this issue in tylergaw/colorme#3. Found it first in the colorme.io UI just from usage. Fiddled with the adjusters enough and found the pattern. From there, I just followed the thread until I bumped into the
Color.mix
usage.I have a PR in for colorme pointing it to my branch of css-color-function tylergaw/colorme#6 for now. And that branch is deployed at
https://colorme.io
Thanks, let me know if there's anything else you want me to tweak.