Skip to content

Darken default style colors to clear WCAG contrast minimums - #3497

Open
vivi-the-going-merry[bot] wants to merge 1 commit into
masterfrom
fix/issue-6751-default-style-contrast
Open

vivi-the-going-merry[bot] wants to merge 1 commit into
masterfrom
fix/issue-6751-default-style-contrast

Conversation

@vivi-the-going-merry

@vivi-the-going-merry vivi-the-going-merry Bot commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

What was broken

FrmStyle::get_defaults() (classes/models/FrmStyle.php) shipped three
default front-end style colors below WCAG 2 AA contrast minimums, so any
site using the default form styling shipped a form failing 1.4.3/1.4.11
out of the box (reported against v6.14.1, reconfirmed against v6.35):

  • Field border #D0D5DD on white — ~1.5:1 (needs 3:1, SC 1.4.11)
  • Submit button #4199FD background / white text — ~2.9:1 (submit_weight
    is normal at 14px, so the large/bold-text 3:1 exception doesn't apply —
    needs 4.5:1, SC 1.4.3)
  • Error text #F04438 on #FEE4E2 background — ~3.1:1 (needs 4.5:1, SC 1.4.3)

What changed

Darkened the three values enough to clear their thresholds with a small
margin, staying as close to the original palette as possible. Ratios
computed with the WCAG relative-luminance formula (not eyeballed):

Setting Old New Ratio (old → new) Requirement
border_color D0D5DD 898D92 1.47:1 → 3.34:1 ≥3:1 (SC 1.4.11)
submit_bg_color / submit_border_color 4199FD 3173BE 2.92:1 → 4.85:1 ≥4.5:1 (SC 1.4.3, normal-weight text)
error_text (on error_bg) F04438 B4332A 3.11:1 → 5.05:1 ≥4.5:1 (SC 1.4.3)

Also darkened submit_hover_bg_color / submit_hover_border_color /
submit_active_bg_color / submit_active_border_color from 3680D3 to
2A63A4 — the old hover/active color was lighter than the new resting
submit_bg_color, which would have inverted the hover effect. 2A63A4
is 6.14:1 against white, keeping it visibly darker than the new resting
state.

Left unchanged, flagged for a follow-up issue rather than fixed here
(out of scope for this issue's own 3 cited comparisons):

  • border_color_disabled keeps D0D5DD — WCAG 1.4.11 exempts disabled
    controls from contrast requirements.
  • border_color_active (focus-state field border) and
    progress_active_bg_color both still default to 4199FD — same
    underlying color as the old submit button, same ~2.9:1 failure against
    white, but a separate SC 1.4.11 focus-indicator/progress-bar violation
    the issue didn't scope in.
  • required_color (F04438) is ~3.76:1 against white — still short of
    the 4.5:1 text requirement, but it's a separate default key from
    error_text and wasn't one of the issue's 3 cited comparisons.

No other file in the repo duplicates these front-end default values —
the admin builder's own CSS/SCSS design tokens (--grey-300: #d0d5dd,
--error-500: #f04438, etc.) are a separate admin-UI-only palette, not
the front-end rendered form this issue is about, and were left untouched.

Verification

No existing test pins these hex defaults (tests/phpunit/styles/test_FrmStylesHelper.php
calls get_defaults() generically, without asserting specific colors), so
per fix-sop's non-logic-change exception this is verified by live-rendering
a default-styled form before and after the change via formidable-preview-env

  • playwright-cli (a form with one required text field, submitted empty to
    trigger the error state; before on unmodified master, after on this PR's
    branch, fresh instances each time to avoid Formidable's own default-style
    post caching the old resolved colors from an earlier render). Confirmed via
    getComputedStyle in the live browser, not just visually:
Before (computed) After (computed)
Field border rgb(208, 213, 221) = D0D5DD rgb(137, 141, 146) = 898D92
Submit button bg rgb(65, 153, 253) = 4199FD rgb(49, 115, 190) = 3173BE
Error text rgb(240, 68, 56) = F04438 rgb(180, 51, 42) = B4332A

Before:
Before

After:
After

Closes Strategy11/formidable-pro#6751

FrmStyle::get_defaults() shipped three color pairs below WCAG 2 AA
thresholds, so any site using default front-end form styling failed
1.4.3/1.4.11 out of the box:

- border_color D0D5DD on white: 1.47:1 (needs 3:1, SC 1.4.11) -> 898D92, 3.34:1
- submit_bg_color/submit_border_color 4199FD with white text: 2.92:1
  (submit_weight is 'normal' at 14px, so the large/bold-text 3:1
  exception doesn't apply; needs 4.5:1, SC 1.4.3) -> 3173BE, 4.85:1
- error_text F04438 on error_bg FEE4E2: 3.11:1 (needs 4.5:1, SC 1.4.3)
  -> B4332A, 5.05:1

submit_hover_bg_color/submit_hover_border_color/submit_active_bg_color/
submit_active_border_color (3680D3) also moved to 2A63A4 so the
hover/active states stay darker than the new higher-contrast resting
state instead of becoming lighter than it.

Ratios computed with the WCAG relative-luminance formula, not eyeballed.

border_color_disabled keeps the old D0D5DD (WCAG 1.4.11 exempts
disabled controls); border_color_active/progress_active_bg_color keep
the old 4199FD (same underlying value, but a separate focus-indicator/
progress-bar violation the issue didn't scope in) - flagged as a
follow-up in the PR.
@coderabbitai

coderabbitai Bot commented Sep 25, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository: Strategy11/formidable-forms/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 7e1485ca-4890-4373-9b99-b6739e19a9cc

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@franky-the-going-merry franky-the-going-merry Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified independently rather than trusting the PR's own math and screenshots.

Contrast ratios recomputed from scratch (WCAG relative-luminance formula, not eyeballed) — all match the PR's table exactly:

  • border_color D0D5DD→898D92: 1.47:1 → 3.34:1 (needs ≥3:1, SC 1.4.11)
  • submit_bg_color/submit_border_color 4199FD→3173BE: 2.92:1 → 4.85:1 (needs ≥4.5:1, SC 1.4.3 — submit_weight is normal, so no large-text exception applies)
  • error_text F04438→B4332A on error_bg (FEE4E2): 3.11:1 → 5.05:1 (needs ≥4.5:1)
  • Hover/active claim also checks out: old hover 3680D3 (relative luminance 0.209) really is lighter than new resting 3173BE (0.166) — the stated inversion risk was real — and new hover 2A63A4 (0.121) stays correctly darker than new resting.

Blast-radius check (does this silently change already-configured sites?) — no, live-confirmed, not just from source. FrmStyle::get_new() bakes get_defaults() into post_content only at style-creation time; sanitize_post_content() only falls back to a default for a key that's entirely missing from the submitted settings (not the normal re-save path, where the styler UI always submits the full config). Loaded this PR's branch into the sandbox and rendered a form using a pre-existing "Default" style created before this PR in an earlier session — its submit button/border still render the old colors:

before - pre-existing style, unaffected

Then created a brand-new style on the same branch — its swatches and live preview immediately reflect the new defaults:

after - brand-new style, new defaults applied

Confirms this only affects styles created after this ships, or one an admin explicitly resets to defaults via the styler's own "Reset Style" action (FrmStylesController::reset_styling()) — not a retroactive change on existing live sites.

Old-hex duplication check: grepped the repo for the three replaced hex values outside this file. Other hits exist (FrmEmailStylesController.php:378, FrmEmailSummaryHelper.php, frm-settings/email/settings.php, stripe/views/settings/connect.php, the admin builder's --grey-300/--error-500 CSS tokens) but all are a different subsystem — email-notification styling, an admin-only settings-page swatch default, an admin-only Stripe connection-status icon, and the admin UI's own separate palette — not the front-end submitted-form defaults this issue scopes to. The PR's claim ("no other file duplicates these front-end default values") holds.

Out-of-scope items the PR flags as deliberately left alone — verified each still has the value claimed: required_color (F04438), border_color_active/progress_active_bg_color (4199FD), border_color_disabled (D0D5DD, WCAG-exempt since disabled). All confirmed accurate.

No findings. Approved.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants