Now Reading
Why some GitHub labels illegible

Why some GitHub labels illegible

2023-03-13 07:18:53

Be aware
This represents the state of GitHub labels on 2023-03-11, which could have been fastened within the
meantime.

The issue

On GitHub, it’s potential to pick the colour of a label when assigning it to a pull request or a difficulty. When utilizing GitHub with the Gentle default theme, the colour of the textual content on these labels is dependent upon the brightness of the colour used: The darker the colour of the label the brighter the colour of the textual content of the label and vice versa. Right here’s how this appears like:

The default github labels

In actual fact for most colours, the textual content on the label will probably be both black or white. Digging into the
CSS that’s used for the Gentle theme, we discover the logic to determine on the colour of the textual content. Assuming the colour of the
label is in
--label-r, --label-g and --label-r, we now have

--perceived-lightness: calc( ((var(--label-r) * 0.2126) + (var(--label-g) * 0.7152)) / 255 )
--lightness-threshold: 0.453
--lightness-switch: max(0, min(calc((var(--perceived-lightness) - var(--lightness-threshold)) * -1000), 1))

after which the colour for the font is set by

colour:hsl(0deg, 0%, calc(var(--lightness-switch) * 100%))

So if the sRGB worth of the colour is (r,g,b) within the vary [0, 255]^3, a perceived-lightness is calculated by the linear equation

perceived_lightness = lambda r, g, b: (0.2126*r + 0.7152*g +  0.0722*b)/255

and primarily the textual content of the label will probably be coloured white if perceived-lightness<0.453 and black in any other case. Nonetheless, when the perceived-lightness may be very near the brink, we don’t set off the min or max and truly get some form of gray colour for the label.

Taking for instance, taking the colour #3bb6b3 = (59, 182, 179), we get a perceived-lightness of (0.2126*59 + 0.7152*182 + 0.0722*179)/255 = 0.6103..., which is approach above the brink, therefore the textual content for this colour will probably be rendered in black.
For various shades of the identical colour we calculate as follows:

label colour perceived-lightness lightness-switch textual content colour
2b8685 0.4493.. 1 ffffff
2b8786 0.4524.. 0.5741.. 929292
2c8786 0.4532.. 0 000000
3bb6b3 0.6103.. 0 000000

Four labels with different shades of the same color

For #2b8786, we multiply 0.5741... by 255 to get 146 or 0x92. This gray #929292 is already fairly onerous to learn, see beneath for worse circumstances of that habits.

Let’s have a look at the above formulation geometrically.
We begin with an sRGB colour dice, with could be visualized like that:

The worth the place perceived-lightness equals the lightness-threshold is a aircraft slicing by means of the dice:

The intersection between the dice and the aircraft is a parallelogram, and we are able to make an orthonormal projection to 2 dimensions to get a transparent have a look at it:

A colorful parallelogram; the intersection between the color cube nad the perceived-lightness equals threshold plane

Since these are the colours is the brink the place GitHub’s algorithm switches from white to black for the textual content, each must be equally readable in opposition to that background. Nonetheless, at the very least to my eyes, the white textual content is extra readable:

A colorful parallelogram with white text
A colorful parallelogram with black text

Additionally word how the brightness isn’t uniform for these colours.
So what’s is happening? Nicely, CSS colours are understood to be within the sRGB colour area, however the method used is meant for linear RGB see sRGB – Wikipedia.
Due to this fact the right calculation in must be (in pseudo-code):


def linear_from_srgb_channel(c):
    return c/12.92 if c <= 0.04044823627710819170430880 else ((c + 0.055)/1.055)**2.4
def linear_from_srgb(r, g, b):
    return tuple(map(linear_from_srgb_channel, (r, g, b)))

improved_perceived_lightness = lambda r, g, b: perceived_lightness(*linear_from_srgb(r, g, b))

That exhibits that not doing the conversion to normally skews in the direction of utilizing black textual content an excessive amount of.

That is one drawback with the colour of the textual content of the labels. One other drawback the textual content for labels with a colour very near the brink will really be some shade of gray. I don’t know what the thought behind that’s, however it results in fairly unreadable labels, for example:

Two unreadable github labels

You possibly can check out these labels in a test repo. Within the Gentle default theme they’re essentially the most illegible label I may discover. In Darkish default theme they render wonderful, which could result in individuals really selecting these colour for his or her labels, even when there’s a preview within the person interface.

The answer…

… for the issue with gray textual content:

By no means make the textual content colour of labels gray, all the time determine for both white or black relying on that threshold, so change the code to one thing like

 --lightness-switch: calc(var(--perceived-lightness) < var(--lightness-threshold) ? 1 : 0);

In all probability additionally verify first if --lightness-switch is used elsewhere within the code.

… for the issue with utilizing the fallacious colour area:

A fast repair can be to vary the --lightness-threshold to one thing just a little bigger.

Alternatively, when sticking with the --lightness-threshold one must do the right calculations taking sRGB to linear RGB as described above.

I submitted a bug report back to GitHub; hopefully it will get fastened quickly!


Animations made with SwissGL with the assistance of Alexander Mordvintsev.

Source Link

What's Your Reaction?
Excited
0
Happy
0
In Love
0
Not Sure
0
Silly
0
View Comments (0)

Leave a Reply

Your email address will not be published.

2022 Blinking Robots.
WordPress by Doejo

Scroll To Top