xhiroga / aws-peacock-management-console

Browser Extension to show account alias and change color of AWS Management Console, even if AWS SSO.
MIT License
84 stars 10 forks source link

Low contrast ratio for certain background colors #88

Open KojiAndoJC opened 1 week ago

KojiAndoJC commented 1 week ago

What is the problem?

When setting navigationBackgroundColor to #4e9a06, the text displays with low contrast. The contrast ratio falls below the AA rating, triggering a warning in Chrome DevTools. Screenshot 2024-09-21 164949

Reproduction Steps

Set the configuration JSON as follows:

[
  {
    "env": {
      "account": "your_account_id"
    },
    "style": {
      "navigationBackgroundColor": "#4e9a06"
    }
  }
]

Sign in Method

Browser Name

Chrome

Browser Version

129.0.6668.59 (Official Build) (64-bit)

Other information

The current logic for determining foreground color is as follows:

  1. Color constants:

    const AWSUI_COLOR_GRAY_300 = '#d5dbdb'
    const AWSUI_COLOR_GRAY_900 = '#16191f'
  2. Luminance calculation:

    
    const getLuminance = (r: number, g: number, b: number) =>
    (0.299 * r + 0.587 * g + 0.114 * b) / 255

const isLuminant = (color: string): boolean | undefined => { const rrggbb = color.match( /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})$/ ) if (rrggbb) { const r = parseInt(rrggbb[1], 16) const g = parseInt(rrggbb[2], 16) const b = parseInt(rrggbb[3], 16) return getLuminance(r, g, b) > 0.5 } // (snip) }


3. Foreground color selection:
```ts
const foregroundColor = isLuminant(navigationBackgroundColor)
  ? AWSUI_COLOR_GRAY_900
  : AWSUI_COLOR_GRAY_300

Causes of the low contrast issue:

  1. The lighter color (#d5dbdb) is darker than the default white (#ffffff), resulting in lower contrast.

  2. The threshold for determining darker foreground color usage is not optimized.

Contrast calculation: The contrast ratio is calculated using the following equation (source: https://web.dev/learn/accessibility/color-contrast):

(L1 + 0.05) / (L2 + 0.05)
Where:
L1 is the relative luminance of the lighter color
L2 is the relative luminance of the darker color

To find the optimal threshold, we can calculate the middle point (L_middle) by solving:

(L1 + 0.05) / (L_middle + 0.05) = (L_middle + 0.05) / (L2 + 0.05)
L_middle = sqrt((L2 + 0.05) * (L1 + 0.05)) - 0.05

Using the current getLuminance function:

The isLuminant function should use this L_middle as a threshold instead of 0.5.

In this case, the luminance of the background color (#4e9a06) is 0.44864313725490196, which is ≥ L_middle. This causes isLuminant to return true, resulting in the use of the darker foreground color and, consequently, higher contrast.

For more precise contrast calculations, the luminance should be calculated using a different formula, as described in this article: https://css-tricks.com/understanding-web-accessibility-color-contrast-guidelines-and-ratios/

Please note that I'm not an expert in color theory or accessibility standards, so my understanding and calculations might be incorrect. I welcome any corrections or additional insights from those more knowledgeable in this area.

xhiroga commented 6 days ago

Thank you for your insightful feedback on our color contrast logic, @KojiAndoJC san!

I agree that improvements are needed. I plan to align our implementation with the CSS Color Module Level 6 specification, specifically the contrast-color() function.

However, as browser support is currently limited, we'll implement a similar logic within our repository. This approach will allow us to enhance our color contrast immediately while preparing for future adoption of the official CSS specification. Your contribution is greatly appreciated!

KojiAndoJC commented 4 days ago

Thank you for your response, @xhiroga. I agree that the contrast-color() solution is smart!

While you're considering implementing similar logic, I realized there's one more point I'd like to add. Even though the logic I suggested would result in higher contrast, some users might prefer the current foreground color. To accommodate these users, it might be helpful to implement a foregroundColor configuration option. This way, users could choose between the automatic high-contrast selection and their preferred color, offering more flexibility.

As I'm not fully familiar with the entire codebase or all use cases, I think it's best to wait for your implementation. However, I'm happy to provide any additional feedback or clarification if needed.