Saturday, February 18, 2017

Calculating contrast ratios of text

In a comment on my other article about how web pages are becoming hard to read, Shaun referenced the W3C Web Content Accessibility Guidelines. They provide an algorithm to determine if your text meets minimum accessibility guidelines.

The W3C definition of the contrast ratio requires several calculations: given two colors, you first compute the relative luminance of each (L1 and L2) then calculate the contrast ratio. The ratio will fall in the range 1 to 21 (typically written 1:1 or 21:1). The higher the contrast ratio, the more the text will stand out against the background. For example, black text on a white background has a contrast ratio of 21:1.

The W3C says body text should have a contrast ratio of at least 4.5:1, with headings at least 3:1. But that seems to be the bare minimum. The W3C also recommends at least 7:1 for body text and at least 4.5:1 for headings.

Calculating this can be a chore, so it's best to automate it. Shaum implemented the algorithm in XSLT so he could test the various colors in websites. I created a similar implementation using Bash. It's a little ugly, but I thought I'd share it here:

First, you need a way to input colors. I wanted something that could interpret different representations of colors: in html and css, black is the same as #000 or #000000 or rgb(0,0,0). When evaluating the readability of my text, I might want to use any of these.

Fortunately, there's a neat tool in GNOME to provide that input. GNOME Zenity is a scripting tool to display GTK+ dialogs. It supports many modes to read input and display results. One of the input modes is a color selector, which you use this way:
zenity --color-selection
You can give it other options to set the window title and provide a default color. Zenity returns the selected color on standard output. You can even set a default color. So to present two dialogs, one to read the text color and another to read the background color, you simply do this:
color=$( zenity --title 'Set text color' --color-selection --color='black' )
background=$( zenity --title 'Set background color' --color-selection --color='white' )
Zenity returns values like rgb(255,140,0) and rgb(255,255,255), which is fortunate because the W3C calculation for luminance requires values in the range 0 to 255. I wrote a simple function to pull apart the RGB values. There are probably simpler ways to parse RGB, but a quick and easy way is to let awk split the values at the comma. That means a value like rgb(255,140,0) gets split into rgb(255 and 140 and 0) so the R value is a substring starting at the fifth character, G is the second element, and B is a substring up to the last parenthesis.

Once I have the RGB values, then I calculate the luminance using bc. The funky math with e() and l() are to get around a limitation in bc. Specifically, the formula requires a fractional power, and bc can only do integer powers. But if you follow the math, you can get there using e() and l():
function luminance()
{
        R=$( echo $1 | awk -F, '{print substr($1,5)}' )
        G=$( echo $1 | awk -F, '{print $2}' )
        B=$( echo $1 | awk -F, '{n=length($3); print substr($3,1,n-1)}' )

        echo "scale=4
rsrgb=$R/255
gsrgb=$G/255
bsrgb=$B/255
if ( rsrgb <= 0.03928 ) r = rsrgb/12.92 else r = e( 2.4 * l((rsrgb+0.055)/1.055) )
if ( gsrgb <= 0.03928 ) g = gsrgb/12.92 else g = e( 2.4 * l((gsrgb+0.055)/1.055) )
if ( bsrgb <= 0.03928 ) b = bsrgb/12.92 else b = e( 2.4 * l((bsrgb+0.055)/1.055) )
0.2126 * r + 0.7152 * g + 0.0722 * b" | bc -l
}
Once you have the luminance value of the text color and background color, you can compute the contrast ratio. The W3C formula to do this is quite simple, but requires knowing which is the lighter and darker colors. This is an extra step in bc. I wrote this Bash function to calculate the ratio based on two colors:
function contrast()
{
        echo "scale=2
if ( $1 > $2 ) { l1=$1; l2=$2 } else { l1=$2; l2=$1 }
(l1 + 0.05) / (l2 + 0.05)" | bc
}
With those functions, it's fairly straightforward to write a Bash script that reads two colors, then computes the contrast ratio. My script also uses Zenity to output the data:
#!/bin/sh

# read color and background color:

color=$( zenity --title 'Set text color' --color-selection --color='black' )
if [ $? -ne 0 ] ; then
        echo '** color canceled - assume black'
        color='rgb(0,0,0)'
fi

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

# compute luminance:

function luminance()
{

}

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

# compute contrast

function contrast()
{

}

rel=$( contrast $lum1 $lum2 )

# print results

( echo "Color is $color on $background"
echo "Contrast ratio is $rel"

if [ ${rel%.*} -ge 4 ] ; then
        echo "Ok for body text"
else
        echo "Not good for body text"
fi
if [ ${rel%.*} -ge 3 ] ; then
        echo "Ok for title text"
else
        echo "Not good for title text"
fi) | zenity --text-info --title='Contrast Ratio'
With this script, I have a handy way to calculate the contrast ratio of two colors: text color vs background color. For black text on a white background, the contrast ratio is 21.00, the most visible. The #333 dark gray on white has a contrast ratio of 12.66, which is fine. And the lighter #808080 gray on white has a contrast ratio of 3.95, too low for normal text but acceptable for large text like headings. Very light #ccc gray on white has a contrast ratio of 1.60, which is way too low.

Wednesday, February 15, 2017

I can't read your website

An article at Backchannel discusses an interesting trend in website design, and how the web became unreadable. It's a good read, but I'll summarize briefly:

Web pages are becoming too hard to read.

Put another way, a popular trend in web design is to use low-contrast text. Maybe that looks really cool, but it is also really hard to read. From the article: "I thought my eyesight was beginning to go. It turns out, I’m suffering from design."

I've noticed this trend too, and I do find it hard to read certain websites. Even this blog used to use a #333 dark grey text on white, just because I thought it looked better that way. And to be honest, others were doing it, so I did it too. But when I changed the text to black on white, I find my blog easier to read. I hope you do too.

The colors you choose for your text can affect the readability of your site. This is directly connected to usability.

Don't believe me? Here is a sample paragraph, repeated using different colors.

White on black:
Space: the final frontier. These are the voyages of the starship Enterprise. Its continuing mission: to explore strange new worlds, to seek out new life and new civilizations, to boldly go where no one has gone before.
Black on white:
Space: the final frontier. These are the voyages of the starship Enterprise. Its continuing mission: to explore strange new worlds, to seek out new life and new civilizations, to boldly go where no one has gone before.
White on dark gray:
Space: the final frontier. These are the voyages of the starship Enterprise. Its continuing mission: to explore strange new worlds, to seek out new life and new civilizations, to boldly go where no one has gone before.
Dark grey on white:
Space: the final frontier. These are the voyages of the starship Enterprise. Its continuing mission: to explore strange new worlds, to seek out new life and new civilizations, to boldly go where no one has gone before.
White on gray:
Space: the final frontier. These are the voyages of the starship Enterprise. Its continuing mission: to explore strange new worlds, to seek out new life and new civilizations, to boldly go where no one has gone before.
Gray on white:
Space: the final frontier. These are the voyages of the starship Enterprise. Its continuing mission: to explore strange new worlds, to seek out new life and new civilizations, to boldly go where no one has gone before.
Which one do you find easiest to read?

Saturday, February 11, 2017

Experimenting with LibreOffice 5.3

I finally installed LibreOffice 5.3 to try it out. (This is actually version 5.3.0.3.) This version comes with a new interface called MUFFIN, which I wrote about as LibreOffice updating its user interface.

MUFFIN stands for My User Friendly Flexible INterface. Because someone clearly wanted that acronym to spell "MUFFIN." The new interface is still experimental, so you'll need to activate it through Settings→Advanced. When you restart LibreOffice, you can use the View menu to change modes. The new interface has several modes:
  1. Default
  2. Single Toolbar
  3. Sidebar
  4. Notebookbar
You can probably guess what the first three modes are about. These just tweak the interface in different ways, but I'd say it's still very "LibreOffice-y."

The last mode, Notebookbar, is interesting. This is very similar in concept to the Microsoft Office Ribbon. People who come from an Office background and are used to how Ribbon behaves, and how it changes based on what you are working on, should like the Notebookbar setting.

And in Notebookbar, you have a few options:
  1. Contextual groups
  2. Contextual single
  3. Tabbed
For me, "Tabbed" was the default when I activated Notebookbar. LibreOffice functions are divided into different tabs, which are clearly labelled. New tabs appear and disappear as suits the context of what you are working on. For example, if you insert a table, then when you go into the table, you get a "Table" tab, with different table-oriented actions like adding a new row or column.

Here are a few quick screenshots of the different tabs in Notebookbar. The "Home" tab is the default, so that's my first screenshot:








I haven't experimented too much with the other modes in Notebookbar, but "Contextual single" gives you a single action bar loaded with icons. I find it too busy, even though there's a lot of empty space in it. The single bar just "feels" too busy.

"Contextual groups" is closer to what you might think of as the "Microsoft Office Ribbon." Rather than adding new tabs to expose new functionality, the Notebookbar changes the content of the bar to add features as they are needed. If you insert a new table, then a table style menu appears. Exit the table, and the Notebookbar removes the table style menu in favor of other actions.

I'll need more time to explore and experiment with Notebookbar. My first impression is that I like it, and that I prefer tabs to contextual groups. I may share more on this blog as I continue to learn the new interface.

Friday, February 10, 2017

Microsoft's next Windows RT

Apologies for the brief diversion while I discuss Windows.

The Inquirer recently wrote about a future version of "Windows Cloud" that Microsoft will (one day) push its users to, probably whether or not you want it, just as they pushed their Windows 7 users to Windows 10. The difference is that the new operating system isn't really what you think of as "Windows." Instead, it's more like a Chromebook.

Now, I have no problem with the Google Chromebook. The Chromebook has a lot of great use-applications. The platform becomes irrelevant. Instead of a traditional operating system, you get a desktop and a web browser. All your applications are in "the Cloud," so Google's G Suite for your word processor, spreadsheet, and presentation software (think Word, Excel, and Powerpoint). Your email is in Gmail. And anything else you want to do is on a website somewhere. It's a great platform for a highly mobile world.

My wife has a Chromebook, and she loves it! In fact, she's thinking it's time to upgrade to the new Chromebook that's coming out soon.

I used to run a Chromebook when I was the campus CIO at a small university; I ran Linux on my desktop, but for meetings I usually brought my Chromebook.

At that same university, I envisioned that we would someday replace our meeting room PCs with Chromeboxes (the desktop version of a Chromebook) or Chromebits (a "micro" version of a Chromebox that plugs directly into an HDMI slot on a display). And we probably could have replaced many of our classroom PCs and general lab PCs with Chromeboxes or Chromebits; as a Google campus, all our apps were in Google's Cloud, so G Suite and Gmail.

Chromebooks ($200) and Chromeboxes ($150) and Chromebits ($100) are great Cloud-integrated systems at a low price. But that's the trick: the core assumption is that everything is in the Cloud. You don't run local applications on a Chromebook. You can't install applications on a Chromebook.

And now Microsoft seems set to move into this space, as well. The difference is that "Windows Cloud" (as they call it) will be a Cloud-integrated system with the "Windows" label on it. And people expect to install applications on "Windows."

The Inquirer article makes a great point here, both acknowledging why Microsoft would want to move to Windows Cloud, while questioning the wisdom of doing so:
There is a logic to Microsoft's entry into this market. Google's Chromebooks do well in certain markets, thanks to their low cost and zippy speeds on even low power processors, and Microsoft would naturally want to swipe some of that market.

However, despite improvements to Windows Universal Apps, explaining to the average consumer that they can't run their existing programs on their new computer is going to be as problematic as ever, and calling it "Windows 10" is going to mess with people's heads, as quite clearly, it isn't.

It feels like Microsoft are missing the point. If you buy a Chromebook, you know what you are getting. But if you buy a Windows machine, you have 30 years of heritage and expectation attached to the brand and people aren't going to be happy if you deliver a new version with less.
That last paragraph says it all. I think if Microsoft wanted to do a "Cloud-integrated" system like this, it would be better to avoid the "Windows" name. Maybe adopt the "Surface" name, like "Surface Cloud." Or leverage the "Edge" web browser name, and call it the "Edgebook" or something along those lines. At least then, users would carry different expectations to the new product.

Maybe this is a signal that it's time for Microsoft to retire the "Windows" label. Sure, Microsoft probably does want to shift it's operating system into the Cloud (whether or not that's a good thing, I'll leave that to you) but keeping the "Windows" label will hold them back. Learn from the disaster of "Windows RT" where users quickly discovered that while it looked like Windows and felt like Windows, you couldn't install "Windows" applications on it. With a new name, Microsoft can shift user expectations.