Tag: Contrast

Quick Tips for High Contrast Mode

Sarah Higley has some CSS tricks up her sleeve for dealing with High Contrast Mode on Windows, which I learned is referred to as WHCM.

Here’s the first trick:

[…] if the default CSS outline property doesn’t give you the visual effect you want [in WHCM] for focus states, there’s a very simple fix. Instead of overriding default browser focus styles with outline: none, make it transparent instead: outline 3px solid transparent.

That will essentially do nothing outside of WHCM, but in WHCM, it will be a thick white border, which is a strong, good visual focus style.

Direct Link to ArticlePermalink

The post Quick Tips for High Contrast Mode appeared first on CSS-Tricks.

CSS-Tricks

, , , ,

The Contrast Triangle

Chip Cullen:

Let’s say you’re building a site, and you’re working with a designer. They come to you with some solid designs, and you’re ready to go. You’re also a conscientious front end developer and you like to make sure the sites you build are accessible. The designs you’re working from have some body copy, but you notice that the links inside the body copy are missing underlines.

You are now in The Contrast Triangle.

The “triangle” meaning a three-sided comparison:

  • The contrast between the background and text
  • The contrast between the background and links
  • the contrast between text and links

I would think this matters whether you underline links or not, but I take the point that without underlines the problem is worse.

I’d also argue the problem is even more complicated. You’ve also got to consider the text when it is selected, and make sure everything has contrast when that is the case too. And the hover states, active states, visited states, and focus states. So it’s really like hexacontakaienneagon of contrast or something.

Direct Link to ArticlePermalink

The post The Contrast Triangle appeared first on CSS-Tricks.

CSS-Tricks

,
[Top]

Understanding Web Accessibility Color Contrast Guidelines and Ratios

What should you do when you get a complaint about the color contrast in your web design? It might seem perfectly fine to you because you’re able to read content throughout the site, but to someone else, it might be a totally different experience. How can put yourself in that person’s shoes to improve their experience?

There are some relatively easy ways to test contrast. For example, you can check the site on your phone or tablet in bright sunlight, or add a CSS filter to mimic a grayscale view). But… you don’t have to trust your eyes. Not everyone has your exact eyes anyway, so your subjective opinion can possibly be a faulty measurement. 

You can mathematically know if two colors have enough contrast between them. 

The W3C has a document called Web Content Accessibility Guidelines (WCAG) 2.1 that covers  successful contrast guidelines. Before we get to the math, we need to know what contrast ratio scores we are aiming to meet or exceed. To get a passing grade (AA), the contrast ratio is 4.5:1 for most body text and 3:1 for larger text. 

How did the W3C arrive at these ratios?

The guidelines were created for anyone using a standard browser, with no additional assistive technology. The contrast ratios that the WCAG suggests were based initially on earlier contrast standards and adjusted to accommodate newer display technologies, like antialiased text, so content would be readable by people with a variety of visual or cognitive difficulties, whether it be due to age, sickness, or other losses of visual acuity.  

We’re basically aiming to make text readable for someone with 20/40 vision, which is equivilent to the vision of someone 80 years old. Visual acuity of 20/40 means you can only read something at 20 feet away that someone with perfect 20/20 vision could read if it was 40 feet away.

So, say your design calls for antialiased text because it looks much smoother on a screen. It actually sacrifices a bit of contrast and ding your ratio. The WCAG goes into more detail on how scoring works.

There are other standards that take contrast in consideration, and the WCAG used some of these considerations to develop their scoring. One is called the Human Factors Engineering of Computer Workstations (ANSI/HFES 100-2007) was published in 2007 and designated as an American standard for ergonomics. It combined and replaced two earlier standards that were created by separate committees. The goal of the combined standard was to accommodate 90% of computer users, and cover many aspects of computer use and ergonomics, including visual displays and contrast. So, that means we have physical screens to consider in our designs.

What does the ratio mean?

The contrast ratio explains the difference between the lightest color brightness and the darkest color brightness in a given range. It’s the relative luminance of each color.

Let’s start with an egregious example of a teal color text on a light gray background. 

<h1>Title of Your Awesome Site</h1>
h1 {   background-color: #1ABC9C;   color: #888888; }
Yikes!

It’s worth calling out that some tools, like WordPress, provide a helpful warning for this when there’s a poorly contrasted text and background combination. In the case of WordPress, a you get notice in the sidebar.

“This color combination may be hard for people to read. Try using a brighter background color and/or a darker text color.”

“OK,” you say. “Perhaps you think that teal on gray color combination is not exactly great, but I can still make out what the content says.“ (I’m glad one of us can because it’s pretty much a muddy gray mess to me.)

The contrast ratio for that fine piece of hypertext is 1.47:1.

I wanted a better understanding of what the contrast scores were actually checking and came to find that it requires the use of mathematics… with a side of understanding the differences between human and computer vision.  This journey taught me about the history of computer vision and a bit about biology, and gave me a small review of some math concepts I haven’t touched since college.

Here’s the equation:

(L1 + 0.05) / (L2 + 0.05)
  • L1 is the relative luminance of the lighter of the colors.
  • L2 is the relative luminance of the darker of the colors.

This seems simple, right? But first we need to determine the relative luminance for each color to get those variables.

OK, back to relative luminance

We mentioned it in passing, but it’s worth going deeper into relative luminance, or the relative brightness of any color expressed into a spectrum between 0 (black) and 1 (white).

To determine the relative luminance for each color, we first need to get the RGB notation for a color. Sometimes we’re working with HEX color values and need to covert that over to RGB. There are online calculators that will do this for us, but there’s solid math happening in the background that makes it happen. Our teal hex color, #1ABC9C, becomes an RGB of 26, 188, 156.

Next, we take each value of the RGB color and divide each one by 255 (the max integer of RGB values) to get a linear value between 0 and 1. 

So now with our teal color it looks like this:

Component Equation Value
Red 26/255 0.10196078
Green 188/255 0.73725490
Blue 156/255 0.61176471

Then we apply gamma correction, which defines the relationship between a pixel’s numerical value and its actual luminance, to each component part of the RGB color. If the linear value of a component is less than .03938, we divide it by 12.92. Otherwise, we add .055 and divide the total by 1.055 and take the result to the power of 2.4.

Our gamma corrected color components from our teal color end up like this:

Component Equation Value
Red ((0.10196078 +.055)/1.055) ^ 2.4 0.01032982
Green ((0.73725490 +.055)/1.055) ^ 2.4 0.50288646
Blue ((0.61176471 +.055)/1.055) ^ 2.4 0.33245154

This part of our equation comes from the formula for determining relative luminance.

We just sort of sped past gamma correction there without talking much about it and what it does. In short, it translates what a computer “sees” into the human perception of brightness. Computers record light directly where twice the photons equals twice the brightness. Human eyes perceive more levels of light in dim conditions and fewer in bright conditions. The digital devices around us make gamma encoding and decoding calculations all the time. It’s used to show us things on the screens that match up to our perception of how things appear to our eyes.

Finally, we multiply the different colors by numbers that signify how bright that color appears to the human eye. That means we determine the luminance of each color by multiplying the red component value by .2126, the green component value by .7152, and the blue component by .0722 before adding all three of those results together. You’ll note that green gets the highest value here,

So, one last time for teal:

Component Equation Value
Red 0.01032982  X 0.2126 0.00219611973
Green 0.50288646  X 0.7152 0.35966439619
Blue 0.33245154  X 0.0722 0.02400300118

…and add them together for luminance!

L1 = 0.00219611973 + 0.35966439619 + 0.02400300118 = 0.38586352

If we do the same to get our L2 value, that gives us 0.24620133.

We finally have the L1 and L2 values we need to calculate contrast. To determine which value is  L1 and and which is L2 , we need to make sure that the larger number (which shows the lighter color) is always L1 and is divided by the smaller/darker color as L2.

Now compare that result with the WCAG success criterias. For standard text size, between 18-22 points, a minimul result of 4.5 will pass with a grade of AA. If our text is larger, then a slightly lower score of  3 will do the job. But to get the highest WCAG grade (AAA), we have to have a contrast ratio result of at least 7. Our lovely combination fails all tests, coming far under 4.5 for regular text or 3 for headline style text. Time to choose some better colors!

I’m so glad we have computers and online tools to do this work for us! Trying to work out the details step-by-step on paper gave me a couple weeks of frustration. It was a lot of me getting things wrong when comparing results to those of automated contrast checkers.

Remember how teachers in school always wanted you to show your math work to prove how you got to the answer? I made something to help us out.

If you view this demo with the console open, you’ll see the math that goes into each step of the calculations. Go ahead, try our two example colors, like #1ABC9C and #888888.

I just want my page to have proper contrast, what do I do?!

There are a variety of accessibility resources that you can can audit your site. Here’s a list I put together, and there’s another list here on CSS-Tricks.

But here are a few tips to get you started.

First, identify areas that are not serving your accessibility needs.

The WAVE accessibility tool is a good place to start. Run your site through that and it will give you contrast results and help identify trouble areas.

Yay, passing scores!

Follow the suggestions of the audit

Use best practices to improve your scores, and remove the errors. Once you identify contrast errors, you can try out some different options right there in the WAVE tool. Click on the color box to pop open a color picker. Then play around until the errors go away, and you’ll know what you can replace in your code.

Run the test again

This way, you can make sure your changes improved things. Congratulations! You just made your product better for all users, not just ones affected by the accessibility errors!

What comes next is up to you!

You can make it easier on yourself and start all new products with the goal of making them accessible. Make accessibility guidelines part of your requirements for both technology and design. You’ll save yourself potentially hundreds of hours of remediation, and potential legal complaints. U.S. government and education websites are required to comply, but other industries are often taken to task for not making their sites equally available for all people.

If you have the option, consider using established and tested frameworks and web libraries (like Bootstrap or Google’s Material Design) that have already figured out optimum contrast theme colors. In many cases, you can take just what you need (like only the CSS) or at least review their color palettes to inform choices. You should still check the contrast though because, while most standard text options in a framework may follow contrast ratio WCAG suggestions, things like alert and message styles may not. (I’m looking at you, Bootstrap!)

Derek Kay has reviewed a list of web frameworks with a focus on accessibility, which I suggest you read if you are looking for more options. The U.S. Web Design System shows one way to solve color/contrast puzzles using their CSS token system that labels colors to make contrast differences super clear), but they also link to several very good resources for improving and understanding contrast.

We took a deeper dive here than perhaps you ever really need to know, but understanding what a contrast ratio is and what it actually means should help you remember to keep contrast in mind when designing future sites, web apps, and other software.

Having a clearer understanding of what the contrast ratio means helps me to remember who poor contrast can affect, and how to improve web and mobile products overall.

I’m not the ultimate subject expert on contrast, just a very, very curious girl who sometimes has issues reading things on the web with low contrast.

If you have any additional thoughts, corrections or further research to share, please leave a comment and I’ll amend this article! The fuller our understanding of the needs and requirements of our sites is, the better we can plan improvements and ultimately serve the needs of our audiences.

The post Understanding Web Accessibility Color Contrast Guidelines and Ratios appeared first on CSS-Tricks.

CSS-Tricks

, , , , ,
[Top]

A Whole Bunch of Places to Consider Contrast in a Single Paragraph

When we’re thinking about choosing colors in design, we’re always thinking about accessibility. Whenever colors touch, there is contrast and, if we’re talking about the color contrast of text, it needs to be high enough to be readable. This benefits people with a variety of visual disabilities, but also everyone appreciates easily readable text.

Let’s look at the color contrast considerations of just a single paragraph!

A link in a paragraph is probably set in another color to distinguish it as a link.

This link color has insufficient color contrast.

Focusable elements, like links, need to have focus styles as well. By default, we’ll probably get a fuzzy blue outline, so we’ll need to check that that has sufficient color contrast. And if we customize it, that customization will need good color contrast as well.

We’ll also need a hover state for mouse users. Here, I’ll use a background effect that covers about half the text. When you do something like that, the effect needs to be strong enough to be noticeable on hover, and the contrast needs to work on both backgrounds.

It’s not ultra common, but you can style :visited links as well. The styling is somewhat limited (you can’t change opacity or background, for example, because it’s a security concern), but you can change the color. If you do that, it also needs proper contrast. Perhaps we could yank the color differentiation away with color: inherit; to somewhat de-emphasize the link but still indicate it.

Another thing to consider is people highlighting text. On my machine, I have it set up to highlight in an orange color by default (it’s normally a light blue on macOS).

Hopefully, the link colors hold up under any highlight color choice a user might have. They tend to be very light shades.

The text selection colors on macOS Catalina

You can control text selection color through CSS as well with ::selection { background: purple; }. If you’ve done that, you have to check all your colors again to make sure you’ve gotten sufficient contrast.

You can try to take measures into your own hands by changing both color and background.

But note that the link inside the text has lost some of its contrast here. We could keep going down the rabbit hole by setting new colors on a::selection and every other element that has its own colorations within the text.

I’d say a good rule of thumb is to go very light if you’re going to do a custom highlighting color and then not do any further customizations specifically for the selected text.


The idea for this post came from some bug reports I’ve gotten from people reporting that links are hard to read on this site when highlighting text, then focusing a link. I tried fixing it by getting more elaborate, but there are limits to what you can do.

::selection a:focus { /* nope */ } a:focus::selection  { /* nope */ } a::selection:focus  { /* nope */ }

It’s better handled by doing less than more.


I recently read Ethan Muller’s Designing for Design Systems post and he makes a similar point about contrast, but across a color spectrum rather than across contexts. For example, your blue link color might work just fine on a few of your design system colors, but not so much on others.

There are a couple things that might help with this.

  • The generic advice of “every time you declare a background-color, declare a color” might help.
  • I’ve used parent-level classes like on-light to change colors of things broadly inside light-colored containers.
  • I’ve used a Sass mixin to help make it easier to change links and the link states, so I’m more apt to do it when changing backgrounds.
@mixin linkStyleText($ linkColor) {   a {     // Update generic link styles with $ linkColor     &:hover,     &:focus {       // Also change the hover/focus styles, probably by altering $ linkColor programatically     }   } }  .variation {    background: $ someNewBGColor;    linkStyleText($ someNewLinkColor) }

Well, thanks for coming on this journey with me. It just occurred to me that color contrast isn’t quite as simple as checking a single link color on a background to make sure it passes. There might be a dozen or more things to check depending on how many things you colorize in your body copy.

The font in these screenshots is Ibarra Real Nova, which was just recently released on Google Fonts.

The post A Whole Bunch of Places to Consider Contrast in a Single Paragraph appeared first on CSS-Tricks.

CSS-Tricks

, , , , , ,
[Top]

Weekly Platform News: Contrast Ratio Range, replaceAll Method, Native File System API

In this week’s roundup: Firefox’s new contrast checker, a simpler way to lasso substrings in a string, and a new experimental API that will let apps fiddle with a user’s local files.

Firefox shows the contrast ratio range for text on a multicolored background

According to Success Criterion 1.4.3 of the Web Content Accessibility Guidelines (WCAG), text should have a contrast ratio of at least 4.5. (A lower contrast ratio is acceptable only if the text is 24px or larger.)

If the background of the text is not a solid color but a color gradient or photograph, you can use the special element picker in Firefox’s Accessibility panel to get a range of contrast ratios based on the element’s actual background.

(via Šime Vidas)

Replacing all instances of a substring in a string

The new JavaScript replaceAll method makes it easier to replace all instances of a substring in a string without having to convert the substring to a regex first, which is “hard to get right since JavaScript doesn’t offer a built-in mechanism to escape regular expression patterns.”

// BEFORE str = str.replace(/foo/g, "bar");  // AFTER str = str.replaceAll("foo", "bar");

This new string method has not yet shipped in browsers, but you can start using it today via Babel (since it’s automatically polyfilled by @babel/preset-env).

(via Mathias Bynens)

Try out the Native File System API in Chrome

The Native File System API, which is experimentally supported in Chrome, allows web apps to read or save changes directly to local files on the person’s computer. The app is granted permission to view and edit files in a specific folder via two separate prompts.

You can try out this new feature by visiting labs.vaadin.com in Chrome on desktop.

(via Thomas Steiner)

More news…

sunday-issue-18.png

Read more news in my weekly newsletter for web developers. Pledge as little as $ 2 per month to get the latest news from me via email every Monday.

More News →

The post Weekly Platform News: Contrast Ratio Range, replaceAll Method, Native File System API appeared first on CSS-Tricks.

CSS-Tricks

, , , , , , , , , ,
[Top]

Color contrast accessibility tools

Accessibility is all the rage these days, specifically when it comes to color contrast. I’ve stumbled upon a couple of tools this week that I think are pretty nifty for helping make sure that all of the text on our websites is legible regardless of what background color they might have.

First up is the Accessible Color Generator which happens to be a wonderful tool for picking alternative colors. Let’s say you’re working on a brand with color X. You can generate a host of other complimentary colors like this:

Next up is Contrast, a rather great MacOS app that sits in the menu bar at all times and helps identify accessible color pairings based on WCAG Guidelines. This one is particularly useful if you happen to be a designer:

This reminds me of a wonderful post about how the Lyft design team re-approached the way they use color in their app. Kevyn Arnott explains:

Color, at least on the surface, appears almost naively simple, yet as it scales across larger products it becomes unbelievably complex. You have thousands of people building products all at once, and those products are all heavily reliant on color. This puts a lot of pressure on the color system to ensure that all the products are being created consistently, but very hard to implement since it’s all too easy to apply colors on a one-off basis.

The team then went ahead and built ColorBox.io which lets you systematically build out a ton of colors for your design systems work. It’s pretty nifty!

Plus the folks over at GOV.UK made their own color accessibility tool called Contrast Checker which (as you have guessed by the name) helps check the contrast between the background of an element and the page itself:

And, of course, there’s the trusty WebAIM contrast checker, which is a go-to for many developers out there.

So far, we’ve looked at tools that check contrast. But there is a class of tooling that can automate accessible contrasts during development. Josh Bader wrote up an approach that enforces high contrast by pairing CSS custom properties with the calc() function. Facundo Corradini did something similar that switches font color based on the background color behind it.

Oh! And we may have something to look forward to with the color-adjust property. It is proposed in the CSS Color Module Level 4 specification and could give browsers more control to adjust color values that are declared in the stylesheet. It’s not really geared towards color contrast, but there’s something interesting about handing off the responsibility of rendering color values to the browser based on certain conditions.

The post Color contrast accessibility tools appeared first on CSS-Tricks.

CSS-Tricks

, , ,
[Top]

CSS Variables + calc() + rgb() = Enforcing High Contrast Colors

As you may know, the recent updates and additions to CSS are extremely powerful. From Flexbox to Grid, and — what we’re concerned about here — Custom Properties (aka CSS variables), all of which make robust and dynamic layouts and interfaces easier than ever while opening up many other possibilities we used to only dream of.

The other day, I was thinking that there must be a way to use Custom Properties to color an element’s background while maintaining a contrast with the foreground color that is high enough (using either white or black) to pass WCAG AA accessibility standards.

It’s astonishingly efficient to do this in JavaScript with a few lines of code:

var rgb = [255, 0, 0];  function setForegroundColor() {   var sum = Math.round(((parseInt(rgb[0]) * 299) + (parseInt(rgb[1]) * 587) + (parseInt(rgb[2]) * 114)) / 1000);   return (sum > 128) ? 'black' : 'white'; }

This takes the red, green and blue (RGB) values of an element’s background color, multiplies them by some special numbers (299, 587, and 144, respectively), adds them together, then divides the total by 1,000. When that sum is greater than 128, it will return black; otherwise, we’ll get white. Not too bad.

The only problem is, when it comes to recreating this in CSS, we don’t have access to a native if statement to evaluate the sum. So,how can we replicate this in CSS without one?

Luckily, like HTML, CSS can be very forgiving. If we pass a value greater than 255 into the RGB function, it will get capped at 255. Same goes for numbers lower than 0. Even negative integers will get capped at 0. So, instead of testing whether our sum is greater or less than 128, we subtract 128 from our sum, giving us either a positive or negative integer. Then, if we multiply it by a large negative value (e.g. -1,000), we end up with either very large positive or negative values that we can then pass into the RGB function. Like I said earlier, this will get capped to the browser’s desired values.

Here is an example using CSS variables:

:root {   --red: 28;   --green: 150;   --blue: 130;    --accessible-color: calc(     (       (         (var(--red) * 299) +         (var(--green) * 587) +         (var(--blue) * 114) /         1000       ) - 128     ) * -1000   ); }  .button {   color:     rgb(       var(--accessible-color),       var(--accessible-color),       var(--accessible-color)     );   background-color:     rgb(       var(--red),       var(--green),       var(--blue)     ); }

If my math is correct (and it’s very possible that it’s not) we get a total of 16,758, which is much greater than 255. Pass this total into the rgb() function for all three values, and the browser will set the text color to white.

At this point, everything seems to be working in both Chrome and Firefox, but Safari is a little cranky and gives a different result. At first, I thought this might be because Safari was not capping the large values I was providing in the function, but after some testing, I found that Safari didn’t like the division in my calculation for some reason.

Taking a closer look at the calc() function, I noticed that I could remove the division of 1,000 by increasing the value of 128 to 128,000. Here’s how that looks so far:

:root {   --red: 28;   --green: 150;   --blue: 130;    --accessible-color: calc(     (       (         (var(--red) * 299) +         (var(--green) * 587) +         (var(--blue) * 114)       ) - 128000 /* HIGHLIGHT */     ) * -1000   ); }  .button {   color:     rgb(       var(--accessible-color),       var(--accessible-color),       var(--accessible-color)     );   background-color:     rgb(       var(--red),       var(--green),       var(--blue)     ); }

Throw in a few range sliders to adjust the color values, and there you have it: a dynamic UI element that can swap text color based on its background-color while maintaining a passing grade with WCAG AA.

See the Pen
CSS Only Accessible Button
by Josh Bader (@joshbader)
on CodePen.

Putting this concept to practical use

Below is a Pen showing how this technique can be used to theme a user interface. I have duplicated and moved the --accessible-color variable into the specific CSS rules that require it, and to help ensure backgrounds remain accessible based on their foregrounds, I have multiplied the --accessible-color variable by -1 in several places. The colors can be changed by using the controls located at the bottom-right. Click the cog/gear icon to access them.

See the Pen
CSS Variable Accessible UI
by Josh Bader (@joshbader)
on CodePen.

There are other ways to do this

A little while back, Facundo Corradini explained how to do something very similar in this post. He uses a slightly different calculation in combination with the hsl function. He also goes into detail about some of the issues he was having while coming up with the concept:

Some hues get really problematic (particularly yellows and cyans), as they are displayed way brighter than others (e.g. reds and blues) despite having the same lightness value. In consequence, some colors are treated as dark and given white text despite being extremely bright.

What in the name of CSS is going on?

He goes on to mention that Edge wasn’t capping his large numbers, and during my testing, I noticed that sometimes it was working and other times it was not. If anyone can pinpoint why this might be, feel free to share in the comments.

Further, Ana Tudor explains how using filter + mix-blend-mode can help contrast text against more complex backgrounds. And, when I say complex, I mean complex. She even goes so far as to demonstrate how text color can change as pieces of the background color change — pretty awesome!

Also, Robin Rendle explains how to use mix-blend-mode along with pseudo elements to automatically reverse text colors based on their background-color.

So, count this as yet another approach to throw into the mix. It’s incredibly awesome that Custom Properties open up these sorts of possibilities for us while allowing us to solve the same problem in a variety of ways.

The post CSS Variables + calc() + rgb() = Enforcing High Contrast Colors appeared first on CSS-Tricks.

CSS-Tricks

, , , , ,
[Top]