Buttons: Default vs. disabled states are not differentiable when adjacent to each other (light mode and dark mode)
Categories
(Toolkit :: UI Widgets, defect)
Tracking
()
| Accessibility Severity | s2 |
People
(Reporter: nstroud, Unassigned)
References
(Blocks 1 open bug)
Details
(Keywords: access, Whiteboard: [recomp-nova])
Notes
This issue exists:
- in the Nova Component library Figma
- with the Nova pref turned ON and OFF
STR
Figma check
- Open the 'Buttons' page in the Nova Components library Figma
- Find the button components
- Starting with the default variant in the first column, grab the hex codes of the fill colors for the disabled buttons and the default buttons in light mode
- Use any color contrast checking tool and plug in the hex code values to test. (WebAIM Contrast Checker link in case you need a contrast checker)
- Now, repeat steps 3 and 4 for the remaining variants: ghost, muted, destructive, and primary (columns 2-5)
- Move over to the dark mode buttons and repeat steps 3 through 5
--
Storybook check
- Open Nightly
- Visit the 'Default' buttons
- This should take you to the 'Default' buttons Storybook page in dark mode. In the bottom half of the page, click on the 'Controls' tab
- Locate
disabled- there should be a toggle button with 'False' and 'True' - When grabbing the hex code for a disabled state, change the toggle to 'True'. For the default state, change the toggle to 'False'
- From here, grab the hex codes of the fill colors for the disabled button and the default button.
- Use any color contrast checking tool and plug in the hex code values to test. (WebAIM Contrast Checker link in case you need a contrast checker)
- Now, grab the hex codes of the border colors and/or text colors
- With these hex codes, repeat step 7
- Return to the 'Default' Storybook page and change from dark mode to light mode
- Repeat steps 6 through 9
- Once you've finished both tests, open a new tab and go to
about:config - Click the 'Accept the Risk and Continue' button
- In the textbox, type 'nova'
- Find
browser.nova.enabledand change the pref value. So if it's 'true' change it to 'false' and vice versa. - Return to the Storybook tab with the 'Default' button
- Repeat steps 6 through 10
You have now completed color contrast checks between the disabled and default states for text buttons in the default variant, in light and dark mode, with the Nova pref ON and OFF. To do this test for the remaining variants in the default and disabled states, visit the muted buttons page, destructive buttons page, and primary buttons page in Storybook
Note: There is no page for ghost text buttons in Storybook but there are ghost text buttons in Figma
Actual
Storybook / Light Mode / Nova ON / Default variant
disabled fill #f7f6fb + default fill #f7f6fb
Contrast ratio: 1:1
disabled border #9c7fe5 + default border #764edd
Contrast ratio: 1.68:1
disabled text #585763 + default text #161423
Contrast ratio 2.55:1
Figma / Light Mode / Default variant
disabled fill #FFF + default fill #FFF
Contrast ratio: 1:1
disabled border #9F83E7 + default border #764EDD
Contrast ratio: 1.76:1
disabled text #5C5B65 + default text #161423
Contrast ratio 2.71:1
Storybook / Dark Mode / Nova ON / Default variant
disabled fill #131215 + default fill #131215
Contrast ratio: 1:1
disabled border #8773B9 + default border #B89CFF
Contrast ratio: 1.78:1
disabled text #B6B5B9 + default text #FCFBFF
Contrast ratio 1.97:1
Figma / Dark Mode / Default variant
disabled fill #252428+ default fill #252428
Contrast ratio: 1:1
disabled border #8C78BE + default border #B89CFF
Contrast 1.66:1
Figma / Light Mode / Ghost variant
disabled text #5C5B65 + default text #161423
Contrast ratio 2.71:1
Figma / Dark Mode / Ghost variant
disabled text #BBBABE + default text #FCFBFF
Contrast ratio 1.87:1
Storybook / Dark Mode / Nova ON / Muted variant
disabled fill #3E3D41 + default fill #515054
Contrast ratio: 1.34:1
disabled text #B6B5B9 + default text #FCFBFF
Contrast ratio 1.97:1
Figma / Dark Mode / Muted variant
disabled fill #444347 + default fill #515054
Contrast ratio: 1.22:1
disabled text #BBBABE + default text #FCFBFF
Contrast ratio 1.87:1
Figma / Light Mode / Muted variant
disabled fill #E2E2E5 + default fill #D6D5DA
Contrast ratio: 1.12:1
disabled text #5C5B65 + default text #161423
Contrast ratio 2.71:1
Storybook / Light Mode / Nova ON / Destructive variant
disabled fill #D36882 + default fill #C52D4F
Contrast ratio 1.57:1
disabled text #FCFCFD + default text #FFFFFF
Contrast ratio 1.02:1
Storybook / Light Mode / Nova OFF / Destructive variant
disabled fill #E68AA2 + default fill #CF1748
Contrast ratio 2.2:1
disabled text #FFFFFF + default text #FFFFFF
Contrast ratio 1:1
Storybook / Dark Mode / Nova ON / Destructive variant
disabled fill #B86571 + default fill #FF8998
Contrast ratio 1.8:1
disabled text #1F1E22 + default text #252428
Contrast ratio 1.07:1
Storybook / Dark Mode / Nova ON / Destructive variant
disabled fill #8E4C58 + default fill #FF7E8E
Contrast ratio 2.59:1
disabled text #18171D + default text #15141A
Contrast ratio 1.02:1
Figma / Light Mode / Destructive variant
disabled fill #D76C84 + default fill #C52D4F
Contrast ratio 1.64:1
disabled text #FFF + default text #FFF
Contrast ratio 1:1
Figma / Dark Mode / Destructive variant
disabled fill #BD6B76 + default fill #FF8998
Contrast ratio 1.67:1
disabled text #252428 + default text #252428
Contrast ratio 1:1
Storybook / Light Mode / Nova ON / Primary variant
disabled fill #9B90BA + default fill #764EDD
Contrast ratio 1.81:1
disabled text #FCFCFD + default text #FFFFFF
Contrast ratio 1.02:1
Storybook / Light Mode / Nova OFF / Primary variant
disabled fill #7EAFFC + default fill #0062FA
Contrast ratio 2.28:1
disabled text #FFF + default text #FFF
Contrast ratio 1:1
Storybook / Dark Mode / Nova ON / Primary variant
disabled fill #0D737F + default fill #00CADB
Contrast ratio 2.77:1
disabled text #18171D + default text #15141A
Contrast ratio 1.02:1
Storybook / Dark Mode / Nova OFF / Primary variant
disabled fill #6F648D + default fill #B89CFF
Contrast ratio 2.37:1
disabled text #1F1E22 + default text #252428
Contrast ratio 1.07:1
Figma / Light Mode / Primary variant
disabled fill #9F94BC + default fill #764EDD
Contrast ratio 1.9:1
disabled text #FFF + default text #FFF
Contrast ratio 1:1
Figma / Dark Mode / Primary variant
disabled fill #746992 + default fill #B89CFF
Contrast ratio 2.21:1
disabled text #252428 + default text #252428
Contrast ratio 1:1
Expected
Adjacent states are considered differentiable if:
- at least one shared visual part (such as a border or fill) has a color contrast ratio of 3:1 or higher
- or one component's state contains a non-color visual indicator (e.g., checked vs. unchecked).
Components in a hover state are considered differentiable by the location of a pointer
Updated•12 days ago
|
Updated•12 days ago
|
One thing recomp team would like to clarify with the accessibility team is the WCAG requirement behind this issue, as we haven’t been able to find a specific WCAG criterion requiring 3:1 contrast between adjacent enabled and disabled controls. In particular, WCAG’s contrast criteria generally exempt inactive/disabled UI components. Because of that, we’d also like to confirm whether access-s2 is the appropriate severity here.
One proposed improvement is to reduce the disabled-state opacity from 70% to 50%, which UX agreed could be a valid option. Before moving forward with that, we should verify that it doesn’t introduce a separate contrast issue between the button text and background.
We’re planning to discuss this with the accessibility team during the UX/a11y sync this week and confirm the expected behavior and severity.
| Reporter | ||
Comment 3•6 days ago
|
||
(In reply to akulyk from comment #2)
One thing recomp team would like to clarify with the accessibility team is the WCAG requirement behind this issue, as we haven’t been able to find a specific WCAG criterion requiring 3:1 contrast between adjacent enabled and disabled controls. In particular, WCAG’s contrast criteria generally exempt inactive/disabled UI components. Because of that, we’d also like to confirm whether access-s2 is the appropriate severity here.
correct, WCAG does not explicitly lay anything out over state to state contrast of adjacent components. inactive/disabled UI components are exempt from contrast guidelines according to WCAG. however, we should aim for for high contrast regardless in order to make these easy to perceive.
One proposed improvement is to reduce the disabled-state opacity from 70% to 50%, which UX agreed could be a valid option. Before moving forward with that, we should verify that it doesn’t introduce a separate contrast issue between the button text and background.
In the UX + A11y call, we discussed that this would be okay so long as text contrast is not getting worse with disabled buttons. I played around with changing opacity to 50% on disabled buttons and the text contrast worsens with several buttons, especially in light mode.
Light mode: text contrast ratio for disabled buttons
Default - 3.46:1 (#ffffff background + #8a8991 text)
Ghost - 3.46:1 (#ffffff background + #8a8991 text)
Muted - 2.88:1 (#eaeaec background + #8a8991 text)
Destructive - 2.29:1 (#e296a7 background + #ffffff text)
Primary - 2.02:1 (#bab2cf background + #ffffff text)
Dark mode: text contrast ratio for disabled buttons
Default - 4.86:1 (#252428 background + #919094 text)
Ghost - 4.86:1 (#252428 background + #919094 text)
Muted - 3.55:1 (#3b3a3e background + #919094 text)
Destructive - 2.75:1 (#925760 background + #252428 text)
Primary - 2.24:1 (#5e5674 background + #252428 text)
Comment 4•1 day ago
|
||
Fixing the contrast issue of Light mode Muted, Destructive, Primary and Dark mode Destructive, Primary seems to be out of scope for this because there isn't a WCAG requirement for this case. If we want our own guidelines (which I think we do), we should define and state those. The guidelines part should be handled in a follow up.
This bug should handle fixing the original issue: Default vs. disabled button states are not differentiable when adjacent to each other. Fixing the original issue as a stop gap while we figure out how to effectively handle disabled text contrast issue, that seems like a good enough plan to me.
Description
•