My old CSS theme for Melior on World Anvil had an unoptimized colour palette. It didn't meet the Web and Content Accessibility Guidelines (WCAG) in several places that I was using it, and some colours I rarely even used which clogged up my CSS and probably slowed things down.
I wanted to see how bad it was so of course I made a Google Sheet for it.
# Contrast Ratio
First I wanted to understand how the colour contrast was calculated in order to see where I went wrong and make a sheet to help me calculate better options.
> [!info]+ Contrast ratio [^1]
> **(L1 + 0.05) / (L2 + 0.05)**, where
> - L1 is the relative luminance of the lighter of the colours, and
> - L2 is the relative luminance of the darker of the colours.
> [!info]+ Relative Luminance [^2]
> The relative brightness of any point in a colourspace, normalized to **0 for darkest black and 1 for lightest white**
> _Note 1:_ For the sRGB colourspace, the relative luminance of a colour is defined as L = 0.2126 * **R** + 0.7152 * **G** + 0.0722 * **B** where **R**, **G** and **B** are defined as:
> - if RsRGB <= 0.03928 then **R** = RsRGB/12.92 else **R** = ((RsRGB+0.055)/1.055) ^ 2.4
> - if GsRGB <= 0.03928 then **G** = GsRGB/12.92 else **G** = ((GsRGB+0.055)/1.055) ^ 2.4
> - if BsRGB <= 0.03928 then **B** = BsRGB/12.92 else **B** = ((BsRGB+0.055)/1.055) ^ 2.4
>
> and RsRGB, GsRGB, and BsRGB are defined as:
> - RsRGB = R8bit/255
> - GsRGB = G8bit/255
> - BsRGB = B8bit/255
>
> The "^" character is the exponentiation operator.
# Formulas
How I calculated the relative luminance for the colours I used in my palette:
| | `A` | `B` | `C` | `D` | `E` |
| :---: | :-------------: | :---: | :---: | :---: | :------------------: |
| `1` | **Name** | **R** | **G** | **B** | **Relative Luminance** |
| `2` | light | 240 | 240 | 240 | 0.87 |
| `3` | dark | 35 | 35 | 40 | 0.02 |
This is what I came up with for the formula in `E1`:
```xls
=0.2126*(IF((B1/255)<=0.03928,(B1/255)/12.92,(((B1/255)+0.055)/1.055)^2.4))+0.7152*(IF((C1/255)<=0.03928,(C1/255)/12.92,(((C1/255)+0.055)/1.055)^2.4))+0.0722*(IF((D1/255)<=0.03928,(D1/255)/12.92,(((D1/255)+0.055)/1.055)^2.4))
```
In a clearer view:
```xls
=
0.2126*(
IF((B1/255)<=0.03928,
(B1/255)/12.92,
(((B1/255)+0.055)/1.055)^2.4))
+0.7152*(
IF((C1/255)<=0.03928,
(C1/255)/12.92,
(((C1/255)+0.055)/1.055)^2.4))
+0.0722*
(IF((D1/255)<=0.03928,
(D1/255)/12.92,
(((D1/255)+0.055)/1.055)^2.4))
```
Now that I have the relative luminance values I can do the contrast ratio formula to compare two colours. I also did a quick search of my css to pull up a count of how many times each variable name was used in theme. Oof 😬
I also added a visual reference of the relative luminance using HSL colours: 0 for hue, 0 for saturation, and the relative luminance \*100 for the luminosity. From this I could visually see that the majority of the colours were *really* dark and barely distinguishable from each other.
![[2023-06-08 WACG colours of old theme.png|Spreadsheet showing the RGB values and relative luminance of colours used in my old CSS theme, along with a column that shows how many times each colour was used in the theme]]
Now I wanted to see the contrast between each of these colours to find out what combinations were a fail, pass at AA, or success at AAA standards.
# Success Criteria
> [!info]+ Success Criterion 1.4.3 Contrast (Minimum) [^3]
> ##### Level AA
> - **Text:** contrast ratio of at least 4.5:1
> - **Large Text:** contrast ratio of at least 3:1
> [!info]+ Success Criterion 1.4.6 Contrast (Enhanced) [^4]
> #### Level AAA
> - **Text:** contrast ratio of at least 7:1
> - **Large Text:** contrast ratio of at least 4.5:1
# Analysis
### Old Theme Colours
I made a `VLOOKUP` table to see the contrast ratios.
Formula in `J5` is `=INDEX(B5:B28)` and formula in `K4` is `=TRANSPOSE(B5:B28)` which copies the list of variables to the main column and top row (saves me having to type it all out).
In `K5` the formula is a `VLOOKUP`. First it looks up the variables and compares the relative luminance to see which one is darker (white = 0, black = 1) and then it does the calculation of the **contrast ratio**.
```xls
=IF(VLOOKUP($J5,$B$5:$F,5,false)<VLOOKUP(K$4,$B$5:$F,5,false),(VLOOKUP(K$4,$B$5:$F,5,false)+0.05)/(VLOOKUP($J5,$B$5:$F,5,false)+0.05),(VLOOKUP($J5,$B$5:$F,5,false)+0.05)/(VLOOKUP(K$4,$B$5:$F,5,false)+0.05))
```
![[2023-06-08 WACG colours of old theme - analysis.png|Spreadsheet showing a table that checks the contrast ratio of each colour in my old css theme]]
I used conditional formatting to see which combinations were suitable for:
- AA large text combinations only
- AA standard combinations (or AAA large text only)
- AAA standard combinations
# New Palette
I reassessed what colours I actually wanted to use and wrote up *what* I wanted to use them for like using yellow/orange tones for interactive elements like links, hover/active states.
I used [Adobe Color's Contrast Checker](https://color.adobe.com/create/color-contrast-analyzer) accessibility tool to double check my adjustments as I went along because it has a really neat feature that suggests the nearest compatible adjustment.
![[2023-06-08 WACG colours of new theme - analysis.png]]
I'm really happy with my final results, even if I can still see a few more tweaks to be made (like how variables `I` and `ID` are quite similar) :D
---
# Sources
[^1]: https://www.w3.org/TR/WCAG20/#contrast-ratiodef
[^2]: https://www.w3.org/TR/WCAG20/#relativeluminancedef
[^3]: https://www.w3.org/TR/WCAG21/#contrast-minimum
[^4]: https://www.w3.org/TR/WCAG21/#contrast-enhanced