Accessibility
Accessibility is built into the components (native <details> / <dialog>, ARIA on the navbar toggle, keyboard tables on each interactive page). This page covers the framework-wide helpers.
Screen-reader text
.screen-reader-text hides an element visually but keeps it in the accessibility tree — for extra context on a link, a <caption>, a form-control group label.
Find out more about jellyfish species — visually identical to a plain link; inspect it or turn on a screen reader to find the extra text.
Focus outlines
Buttons, links and form controls get a clear :focus-visible outline for keyboard users; it's suppressed for pointer users (form fields keep theirs, per spec). Tab through these:
A plain linkThe outline is --jf-accessibility-focus-color — override it at :root or a scope.
Contrast linter
Every colour pair Jellyfish generates is scored against the WCAG 2.x contrast ratio at build time — each palette shade against its --jf-color-on-* text colour, plus buttons, chips, callouts, tables, .bg-* surfaces, <mark>, and the dark-mode text-on-canvas pairs. Anything below the threshold prints a Sass @warn naming the pair and its score. Treat a warning as a failing test — it means a colour you added can't be read on the surface it's paired with.
WCAG: palette on-colour contrast has pairs below 4.5:1:
on-brand-400: #ffffff on #7fb8a4 scores 2.31:1
Run it over your own pairs with the same mixin the framework uses — pass a list of (label text background) triples and a context name:
.promo {
color: get-color-raw(primary, 900);
background: get-color-raw(primary, 100);
@include contrast-lint(
("promo text" get-color-raw(primary, 900) get-color-raw(primary, 100)),
"promo"
);
}
Both arguments must be literal colours, so use get-color-raw() rather than get-color() — a var() reference can't be scored at build time. Settings: $contrast-lint (off switch), $contrast-lint-warn (score silently), $contrast-lint-threshold (default 4.5; 3 for the AA large-text exception).
The linter only sees pairs it's handed. Anything where you set a colour without telling it what's behind — a .text-{family} utility, a hand-written rule — is yours to check.
Reduced motion & forced colours
- prefers-reduced-motion: reduce zeroes every framework transition (the indeterminate progress bar slows instead of stopping).
- In Windows High Contrast mode the masked chevron, progress bar and modal buttons repaint from system colours so they stay visible.
Font-size control
Give any button data-font-size="smaller|default|larger|largest". The bundled accessibility.js adds the matching .font-size-* class to <html> (a multiplier on --jf-root-font-size, so the whole rem scale grows), stores the choice in localStorage["jf-font-size"], and sets aria-pressed on the active button. Handled by delegation (CSP-safe); window.setRootFontSize('larger') is exposed for scripts.
-->
Adjust text size: