Skip to content

Light-mode site footer falls short of WCAG AA once the 70% opacity is composited #201

Description

@quantecon-services

Found while reviewing the comment rewrite in #200, which restates the footer's contrast reasoning.

styles/quantecon.css fades the whole site footer with opacity: 0.7 on .article .qe-site-footer, reproducing the lecture footer's own opacity. The declared colours pass AA, but the composited ones are what the reader sees, and in light mode two of them do not. The footer renders at 0.9rem (14.4px) normal weight, so the 4.5:1 normal-text floor applies — the 3:1 large-text allowance does not.

Element Declared Composited on white @ 0.7 Contrast AA
footer body text #444444 rgb(124 124 124) 4.17:1
footer links #0072bc rgb(77 156 208) 3.01:1

Both come straight from the rules as written — .article .qe-site-footer { color: #444; opacity: 0.7 } at (0,2,0) with no light-mode override, and .article .qe-site-footer a { color: #0072bc } — so nothing else in the cascade changes them.

Dark mode already got this treatment. The comment directly above the dark rule does exactly this arithmetic and acts on it:

#0072bc drawn at the footer's 70% opacity on the #222 content panel is about 2.2:1; blue-300 lands near 5.0:1 at the same opacity.

which is why .dark .article .qe-site-footer a is #93c5fd (5.04:1 composited, confirmed). The same two lines of arithmetic were never run for light mode.

Is this inherited? Partly. The opacity: .7 and the 14.4px size are the lecture footer's, measured off python-programming.quantecon.org, so in the strict sense this is the same two-theme question as #172. But this theme has already diverged from the inherited values in this exact block, for this exact reason, on the dark side — alongside three other deliberate accessibility divergences (the outline's undimmed resting entries at 10.3:1 where the Sphinx panel composites to 4.47:1; the outline's active state carrying weight and a rule so it is not colour-only, per WCAG 1.4.1; the flat 18px content size with a rem root, avoiding the Sphinx px-root's 1.4.4 problem). So the working rule this codebase already follows is match the lecture builds, except where matching them fails WCAG — and the light footer is the one place that rule was written down and then not applied.

Options

  1. Fix light to match the standard dark already meets. Minimum-change candidates that keep the faded look, since the opacity is doing the design work — each is the value whose composited result clears 4.5:1, the blue held to #0072bc's own hue and saturation:

    Element Today Composited today Candidate Composited candidate
    body text #444444 4.17:1 #3b3b3b 4.54:1
    links #0072bc 3.01:1 #00436f 4.55:1

    Those are minimum-change values, not a design proposal — #00436f is a much darker blue than the brand #0072bc, and at 70% opacity there is no way around that. If it reads too dark, the alternative is to lift the opacity on the text while keeping it on the badge.

    Or drop opacity: 0.7 and declare the faded colours directly — but the badge image is meant to fade with everything else, which is why the opacity is on the element in the first place, so this changes the badge too.

  2. Fix in both themes, as option 1 of Five light-mode code token colours fall short of WCAG AA contrast #172 proposes for the code palette. Keeps strict parity, costs a coordinated PR and a baseline refresh in both.

  3. Accept and record. The footer is secondary chrome — licence text and attribution, not reading copy. If that is the call, the comment should say so explicitly rather than leaving the arithmetic done for dark only.

Two things I could not settle without a render, both worth checking before deciding:

  • Dark footer body text. The element carries dark:text-qetext-dark-muted (#a6a6a6) while .article .qe-site-footer sets color: #444. Both are (0,2,0), so Tailwind's layer order decides, and the comment on the component rule claims it "overrides the element's utilities outright". If #444 really wins in dark mode it composites to 1.4:1, which the screenshots suggest is not what renders — so the utility is presumably winning and the true figure is #a6a6a6 @ 0.7 = 3.92:1, still under AA. Worth confirming either way, since one of those two readings is a bug and the other is a third row for the table above.
  • Whether real lecture footers carry text links at all, or only the licence badge image. The fixture footer is badge-plus-prose; the a rule exists, so links are expected, but the 3.01:1 figure only bites where there is link text. An image-only badge link is exempt.

Where it fits: not a parity gate — like #172 this is a deliberate-divergence decision, not a mismatch with the current sites. No dependency on #200, which only describes these values; it changes none of them.

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

    Labels

    discussOpen-ended team deliberation or a decision to be made

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions