Skip to content

Factor in alpha when calculating contrast #2843

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed

Factor in alpha when calculating contrast #2843

wants to merge 2 commits into from

Conversation

xi
Copy link

@xi xi commented Mar 15, 2016

Since #2754 the contrast function is based on the definition from WCAG. This is great, but it can still be improved by also considering the alpha.

The most referenced article on this topic is probably the one by Lea Verou where she explains how you can find the minimum and maximum possible contrast ratios. Note however that recently a bug was found in the way the minimum was calculated (siege-media/contrast-ratio#16).

Transparent background colors are usually used on top of images with a wide range of possible colors. So I think using the minimum possible contrast for transparent colors is sensible.

In order to calculate it you need to know which color is foreground and which one is background. Implementing this in less would require breaking changes, so I tried to find a way around. My solution is to use the average of contrastMin(a, b) and contrastMin(b, a). The new implementation works exactly like the old one for fully opaque colors and returns more meaningful results for transparent colors.

@Synchro
Copy link
Member

Synchro commented Mar 15, 2016

The problem is that you can't know the background colour - imagine a transparent button floated over an image - there isn't a sensible way of picking a colour to refer to as the background, and you have no way of knowing it in advance anyway (where Lea refers to the margin of error), because Less processing happens before rendering that would put you in a sitation where you could find out. The contrast function does include transparency in its calculation but because of this issue, it's mostly pointless.

In your code you allow for two colours and it uses the transparency in both of them - but that's not the end of the story - it doesn't take into account the third (or more) colours that are behind both of them. This is essentially the same problem we have already, but involving more colours.

Also I think we're meant to be avoiding adding more things like this in core - it should be in a plugin.

@matthew-dean
Copy link
Member

Also I think we're meant to be avoiding adding more things like this in core - it should be in a plugin

That seems right. To be fair, plugins still need a lot more documentation, but regardless, this is too minimal an problematic to be added to core. And probably any other "color-related" functions should be plugins in the future.

@matthew-dean
Copy link
Member

Closing as not belonging in core.

@xi
Copy link
Author

xi commented Mar 16, 2016

Closing as not belonging in core.

ok, that's fine with me.

there isn't a sensible way of picking a colour to refer to as the background, and you have no way of knowing it in advance anyway (where Lea refers to the margin of error)

That is not true. As I explained above, I assume that the third color is not a single color but an image because this is the most common case. For this reason I pick the minimum possible contrast. The algorithm I proposed here to calculate this minimum is the exact same that I also implemented in Lea's tool in the referenced issue.

@seven-phases-max
Copy link
Member

The algorithm itself (estimate worst/best case by using white and black backgrounds) does make sense indeed. Though taking into account the weird state of the function itself, it's indeed would be more safe to keep this in a plugin yet. For now we don't even have an agreement of how breaking we could go or how to handle that breaking at all :)... Indeed at some point a separate "new amazing colour functions" plugin as a replacement for the core functions might work as a better a the least bothering solution).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants