Skip to content

Form control borders fall below 3:1 non-text contrast in the light theme #15397

Description

@bpmore

Bug description

In the light theme, the borders that define form controls sit closer to 1.5:1 than to the 3:1 that WCAG requires for non-text contrast. The border is the only thing marking where a field begins and ends, and the switch off-state track is the only thing distinguishing off from on.

Measured on /cp/playground, ratios computed from resolved oklch values composited over the actual panel backdrop:

Element Ratio Colour Against
text input border 1.48:1 oklch(0.871 0.006 286.286) #ffffff
textarea border 1.48:1 same #ffffff
combobox trigger border 1.48:1 same #ffffff
checkbox border 1.99:1 oklab(0.705 … / 0.75) #ffffff
switch OFF track 1.27:1 oklch(0.92 0.004 286.32) #ffffff

Required: 3.00:1.

The interesting part is that the codebase already contains the right value. Input.vue ships border-gray-300 as the default and border-gray-500 behind a with-contrast: variant:

https://github.com/statamic/cms/blob/v6.31.0/resources/js/components/ui/Input/Input.vue#L100

gray-500 (#71717b) measures 3.1:1 on white and would pass. It just isn't the default.

Switch.vue has the same pattern (with-contrast:border-gray-500!):

https://github.com/statamic/cms/blob/v6.31.0/resources/js/components/ui/Switch.vue

WCAG 2.1 SC 1.4.11 Non-text Contrast (Level AA).

How to reproduce

  1. composer create-project statamic/statamic
  2. Visit /cp/playground in the light theme
  3. Sample the border colour of a text input and the background of an unchecked switch, and compare each against the panel background

Or use any contrast checker on #d4d4d8 vs #ffffff -> 1.48:1.

Suggested fix

Promote the existing with-contrast values to the defaults: border-gray-500 for inputs, textareas, comboboxes and checkboxes, and an equivalent step-down for the switch off-track.

Dark theme — now measured

I originally reported that dark-theme non-text contrast could not be measured reliably. It can, and it fails too. Measured by sampling rendered pixels from a screenshot rather than resolving CSS, with the method validated by reproducing every light-theme figure above exactly.

Ratio Element Measured Backdrop
1.59:1 text input border #3f3f47 #1e1e21
1.70:1 textarea border #3f3f47 #18181b
1.70:1 combobox trigger border #3f3f47 #18181b
1.70:1 switch OFF track #3f3f47 #18181b
3.67:1 checkbox border #71717b #18181b

The checkbox is the one that passes — and it does so using #71717b, which is exactly the grey-500 value suggested as the fix for the light theme above. So the passing colour already exists in the design system; it is simply not applied to inputs, textareas, comboboxes or the switch track in either theme.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions