Text fields' borders fail 3:1 in every theme but High contrast #305

Closed
opened 2026-10-19 12:39:51 -07:00 by rays · 2 comments
Owner

Text fields and selects draw their edge with border:1px solid var(--line) on a var(--bg) fill (web/app.css:565-567). --line is a separator colour and sits about 1.2-2:1 against what surrounds the field, and the fill is about 1.0-1.25:1, so in most themes a field is hard to tell from the panel it is on (in Glass the fill matches the bar exactly). Its focus state is a 1px change of that border to the accent, with the outline removed (:569), where every other control gets the 2px ring (:482).

Measured in Playwright on the search box, border against the bar around it (non-text needs 3:1):

dark light
Modern 1.57 1.45
Dracula 1.67 1.30
Material 1.83 1.55
Adwaita 1.29 1.18
Flat Remix 1.44 1.41
Paper 1.34
Nordic 1.36 1.30
Catppuccin 1.92 1.49
Gruvbox 1.86 1.37
Solarized 1.57 1.33
High contrast 7.46 7.46
Classic 1.99
Glass 1.73 1.30

tests/contrast.js has no rule for a field's edge, so nothing caught it. The sign-in page has the same problem with its own copy of the palette.

Found in an interface review (2026-10-19). WCAG 1.4.11.

Fix: a field-border role of its own, not --line, which separators also use and which need not be 3:1. One way that covers every theme at once: --field derived from each theme's own colours (color-mix(in oklab, var(--fg) N%, var(--bg))), with the pair added to tests/contrast.js. Delete outline:0 on :569 so fields get the same focus ring as everything else.

Text fields and selects draw their edge with `border:1px solid var(--line)` on a `var(--bg)` fill (`web/app.css:565-567`). `--line` is a separator colour and sits about 1.2-2:1 against what surrounds the field, and the fill is about 1.0-1.25:1, so in most themes a field is hard to tell from the panel it is on (in Glass the fill matches the bar exactly). Its focus state is a 1px change of that border to the accent, with the outline removed (`:569`), where every other control gets the 2px ring (`:482`). Measured in Playwright on the search box, border against the bar around it (non-text needs 3:1): | | dark | light | |---|---|---| | Modern | 1.57 | 1.45 | | Dracula | 1.67 | 1.30 | | Material | 1.83 | 1.55 | | Adwaita | 1.29 | 1.18 | | Flat Remix | 1.44 | 1.41 | | Paper | | 1.34 | | Nordic | 1.36 | 1.30 | | Catppuccin | 1.92 | 1.49 | | Gruvbox | 1.86 | 1.37 | | Solarized | 1.57 | 1.33 | | High contrast | 7.46 | 7.46 | | Classic | | 1.99 | | Glass | 1.73 | 1.30 | `tests/contrast.js` has no rule for a field's edge, so nothing caught it. The sign-in page has the same problem with its own copy of the palette. Found in an interface review (2026-10-19). WCAG 1.4.11. Fix: a field-border role of its own, not `--line`, which separators also use and which need not be 3:1. One way that covers every theme at once: `--field` derived from each theme's own colours (`color-mix(in oklab, var(--fg) N%, var(--bg))`), with the pair added to `tests/contrast.js`. Delete `outline:0` on `:569` so fields get the same focus ring as everything else.
rays added the bug label 2026-10-19 12:39:51 -07:00
Author
Owner

The dialogs have the same failure, in the same 24 of 25 palettes and at the same values, measured in Playwright: Add a feed's Keywords (#nkw), Download latest's count (#dcount), a feed's Settings Address (#surl), New signal's description (#sgdesc), OPML's paste box (#opmlText), and Settings' Hide items mentioning (#sblock) and API token name (#tokname). They use the same rule, so one fix to web/app.css:565-569 covers them. The off switch is #308.

The dialogs have the same failure, in the same 24 of 25 palettes and at the same values, measured in Playwright: Add a feed's Keywords (`#nkw`), Download latest's count (`#dcount`), a feed's Settings Address (`#surl`), New signal's description (`#sgdesc`), OPML's paste box (`#opmlText`), and Settings' Hide items mentioning (`#sblock`) and API token name (`#tokname`). They use the same rule, so one fix to `web/app.css:565-569` covers them. The off switch is #308.
Author
Owner

Fixed in 6ec2c35: a new --field, each theme's --fg mixed into its --bg in OKLab (--fieldmix, 60%, 65-80% for Adwaita light, Nordic, Catppuccin, Gruvbox light and Solarized light), edges text boxes, selects, chips and the OPML box, phones included. tests/contrast.js holds it to 3:1 on bg, panel, panel2 and raise in every palette, and fails if it drops. Fields lost outline:0 and take the same focus ring as every other control. --line is unchanged. Deployed in ipx-web (1.2.1-dev).

Fixed in 6ec2c35: a new `--field`, each theme's `--fg` mixed into its `--bg` in OKLab (`--fieldmix`, 60%, 65-80% for Adwaita light, Nordic, Catppuccin, Gruvbox light and Solarized light), edges text boxes, selects, chips and the OPML box, phones included. tests/contrast.js holds it to 3:1 on bg, panel, panel2 and raise in every palette, and fails if it drops. Fields lost `outline:0` and take the same focus ring as every other control. `--line` is unchanged. Deployed in ipx-web (1.2.1-dev).
rays closed this issue 2026-10-19 13:13:47 -07:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: rays/ipx#305