Science and technology

Make web sites extra readable with a shell script

If you need individuals to search out your web site helpful, they want to have the ability to learn it. The colours you select on your textual content can have an effect on the readability of your web site. Unfortunately, a well-liked pattern in internet design is to make use of low-contrast colours when printing textual content, comparable to grey textual content on a white background. Maybe that appears actually cool to the net designer, however it’s actually onerous for many people to learn.

The W3C supplies Web Content Accessibility Guidelines, which incorporates steerage to assist internet designers choose textual content and background colours that may be simply distinguished from one another. This is named the “contrast ratio.” The W3C definition of the distinction ratio requires a number of calculations: given two colours, you first compute the relative luminance of every, then calculate the distinction ratio. The ratio will fall within the vary 1 to 21 (usually written 1:1 to 21:1). The greater the distinction ratio, the extra the textual content will stand out towards the background. For instance, black textual content on a white background is very seen and has a distinction ratio of 21:1. And white textual content on a white background is unreadable at a distinction ratio of 1:1.

The W3C says body text ought to have a distinction ratio of no less than four.5:1 with headings no less than three:1. But that appears to be the naked minimal. The W3C additionally recommends no less than 7:1 for physique textual content and no less than four.5:1 for headings.

Calculating the distinction ratio generally is a chore, so it is best to automate it. I’ve accomplished that with this useful Bash script. In normal, the script does these items:

  1. Gets the textual content colour and background colour
  2. Computes the relative luminance of every
  3. Calculates the distinction ratio

Get the colours

You might know that each colour in your monitor might be represented by crimson, inexperienced, and blue (R, G, and B). To calculate the relative luminance of a colour, my script might want to know the crimson, inexperienced, and blue elements of the colour. Ideally, my script would learn this info as separate R, G, and B values. Web designers may know the particular RGB code for his or her favourite colours, however most people do not know RGB values for the completely different colours. Instead, most individuals reference colours by names like “red” or “gold” or “maroon.”

Fortunately, the GNOME Zenity instrument has a color-picker app that permits you to use completely different strategies to pick a colour, then returns the RGB values in a predictable format of “rgb(R,G,B)”. Using Zenity makes it simple to get a colour worth:

colour=$( zenity --title 'Set textual content colour' --color-selection --color='black' )

In case the person (by chance) clicks the Cancel button, the script assumes a colour:

if [ $? -ne zero ] ; then
        echo '** colour canceled .. assume black'
        colour='rgb(zero,zero,zero)'
fi

My script does one thing much like set the background colour worth as $background.

Compute the relative luminance

Once you’ve gotten the foreground colour in $colour and the background colour in $background, the following step is to compute the relative luminance for every. On its web site, the W3C provides an algorithm to compute the relative luminance of a colour.

For the sRGB colorspace, the relative luminance of a colour is outlined as
L = zero.2126 * R + zero.7152 * G + zero.0722 * B the place R, G and B are outlined as:

if RsRGB <= zero.03928 then R = RsRGB/12.92
else R = ((RsRGB+zero.055)/1.055) ^ 2.four

if GsRGB <= zero.03928 then G = GsRGB/12.92
else G = ((GsRGB+zero.055)/1.055) ^ 2.four

if BsRGB <= zero.03928 then B = BsRGB/12.92
else B = ((BsRGB+zero.055)/1.055) ^ 2.four

and RsRGB, GsRGB, and BsRGB are outlined as:

RsRGB = R8bit/255

GsRGB = G8bit/255

BsRGB = B8bit/255

Since Zenity returns colour values within the format “rgb(R,G,B),” the script can simply pull aside the R, B, and G values to compute the relative luminance. AWK makes this a easy process, utilizing the comma as the sector separator (-F,) and utilizing AWK’s substr() string perform to choose simply the textual content we would like from the “rgb(R,G,B)” colour worth:

R=$( echo $colour | awk -F, '' )
G=$( echo $colour | awk -F, 'print $2' )
B=$( echo $colour | awk -F, 'n=size($three); print substr($three,1,n-1)' )

(For extra on extracting and displaying knowledge with AWK, Get our AWK cheat sheet.)

Calculating the ultimate relative luminance is greatest accomplished utilizing the BC calculator. BC helps the easy if-then-else wanted within the calculation, which makes this half easy. But since BC can not instantly calculate exponentiation utilizing a non-integer exponent, we have to do some further math utilizing the pure logarithm as an alternative:

echo "scale=four
rsrgb=$R/255
gsrgb=$G/255
bsrgb=$B/255
if ( rsrgb <= zero.03928 ) r = rsrgb/12.92 else r = e( 2.four * l((rsrgb+zero.055)/1.055) )
if ( gsrgb <= zero.03928 ) g = gsrgb/12.92 else g = e( 2.four * l((gsrgb+zero.055)/1.055) )
if ( bsrgb <= zero.03928 ) b = bsrgb/12.92 else b = e( 2.four * l((bsrgb+zero.055)/1.055) )
zero.2126 * r + zero.7152 * g + zero.0722 * b"
| bc -l

This passes a number of directions to BC, together with the if-then-else statements which are a part of the relative luminance method. BC then prints the ultimate worth.

Calculate the distinction ratio

With the relative luminance of the textual content colour and the background colour, now the script can calculate the distinction ratio. The W3C determines the contrast ratio with this method:

(L1 + zero.05) / (L2 + zero.05), the place
L1 is the relative luminance of the lighter of the colours, and
L2 is the relative luminance of the darker of the colours

Given two relative luminance values $r1 and $r2, it is easy to calculate the distinction ratio utilizing the BC calculator:

echo "scale=2
if ( $r1 > $r2 ) l1=$r1; l2=$r2 else
(l1 + zero.05) / (l2 + zero.05)"
| bc

This makes use of an if-then-else assertion to find out which worth ($r1 or $r2) is the lighter or darker colour. BC performs the ensuing calculation and prints the outcome, which the script can retailer in a variable.

The closing script

With the above, we will pull every thing collectively right into a closing script. I take advantage of Zenity to show the ultimate lead to a textual content field:

#!/bin/sh
# script to calculate distinction ratio of colours

# learn colour and background colour:
# zenity returns values like 'rgb(255,140,zero)' and 'rgb(255,255,255)'

colour=$( zenity --title 'Set textual content colour' --color-selection --color='black' )
if [ $? -ne zero ] ; then
        echo '** colour canceled .. assume black'
        colour='rgb(zero,zero,zero)'
fi

background=$( zenity --title 'Set background colour' --color-selection --color='white' )
if [ $? -ne zero ] ; then
        echo '** background canceled .. assume white'
        background='rgb(255,255,255)'
fi

# compute relative luminance:

perform luminance()
awk -F, 'n=size($three); print substr($three,1,n-1)' )

        echo "scale=four
rsrgb=$R/255
gsrgb=$G/255
bsrgb=$B/255
if ( rsrgb <= zero.03928 ) r = rsrgb/12.92 else r = e( 2.four * l((rsrgb+zero.055)/1.055) )
if ( gsrgb <= zero.03928 ) g = gsrgb/12.92 else g = e( 2.four * l((gsrgb+zero.055)/1.055) )
if ( bsrgb <= zero.03928 ) b = bsrgb/12.92 else b = e( 2.four * l((bsrgb+zero.055)/1.055) )
zero.2126 * r + zero.7152 * g + zero.0722 * b"

lum1=$( luminance $colour )
lum2=$( luminance $background )

# compute distinction

perform distinction()
bc

rel=$( distinction $lum1 $lum2 )

# print outcomes

( cat<<EOF
Color is $colour on $background

Contrast ratio is $rel
Contrast ratios can vary from 1 to 21 (generally written 1:1 to 21:1).

EOF

if [ $rel%.* -ge four ] ; then
        echo "Ok for body text"
else
        echo "Not good for body text"
fi
if [ $rel%.* -ge three ] ; then
        echo "Ok for title text"
else
        echo "Not good for title text"
fi

cat<<EOF

The W3C says this:

1.four.three Contrast (Minimum): The visible presentation of textual content and pictures of textual content has a distinction ratio of no less than four.5:1, apart from the next: (Level AA)

    Large Text: Large-scale textual content and pictures of large-scale textual content have a distinction ratio of no less than three:1;

    Incidental: Text or pictures of textual content which are a part of an inactive person interface element, which are pure ornament, that aren't seen to anybody, or which are a part of an image that accommodates important different visible content material, haven't any distinction requirement.

    Logotypes: Text that's a part of a emblem or model identify has no minimal distinction requirement.

and:

1.four.6 Contrast (Enhanced): The visible presentation of textual content and pictures of textual content has a distinction ratio of no less than 7:1, apart from the next: (Level AAA)

    Large Text: Large-scale textual content and pictures of large-scale textual content have a distinction ratio of no less than four.5:1;

    Incidental: Text or pictures of textual content which are a part of an inactive person interface element, which are pure ornament, that aren't seen to anybody, or which are a part of an image that accommodates important different visible content material, haven't any distinction requirement.

    Logotypes: Text that's a part of a emblem or model identify has no minimal distinction requirement.
EOF
) | zenity --text-info --title='Relative Luminance' --width=800 --height=600

At the tip, I like to incorporate reference details about the W3C suggestions as a reminder for myself.

The Zenity colour picker does all of the onerous work of deciphering colours, which the person can choose by clicking within the colour wheel or by getting into a price. Zenity accepts commonplace hex colour values used on web sites, like #000000 or #000 or rgb(zero,zero,zero) (all of these are black). Here’s an instance calculation for black textual content on a white background:

Zenity additionally understands commonplace colour names like cadetblue or orange or gold. Enter the colour identify in Zenity then hit Tab, and Zenity will convert the colour identify right into a hex colour worth, as on this instance calculation for black textual content on a gold background:

 

Most Popular

To Top