Skip to main content

contrast-matrix

CI PyPI Python License: Apache-2.0

A CI-first WCAG color-contrast matrix checker for design tokens, with no browser or network required.

Quickstart

pip install contrast-matrix
contrast-matrix check matrix.json
contrast-matrix check matrix.yaml --format sarif --level aaa

JSON support uses only the Python standard library. Install contrast-matrix[yaml] to read YAML. The exit status is 0 when every token passes, 1 when any token fails, and 2 for usage or input errors.

Input schema

The root object has backgrounds, tokens, and an optional thresholds map:

thresholds: {normal: 4.5, large: 3.0, aaa_normal: 7.0}
backgrounds:
  surface: "#ffffff"
  surface-alt: "#f4f4f5"
  overlay: "rgba(0,0,0,0.6) over #3b82f6"
tokens:
  - name: text-primary
    color: "#18181b"
    over: [surface, surface-alt]
    level: normal
  - name: text-on-overlay
    color: "rgba(255,255,255,0.9)"
    over: [overlay]
    level: large

Background keys are arbitrary names. Colors accept CSS #rgb, #rgba, #rrggbb, #rrggbbaa, rgb(), rgba(), hsl(), and hsla(). Derived expressions accept foreground over background and mix(first, second, t), where t ranges from 0 to 1. Each token requires a unique name, a color, a non-empty over list of background names, and a threshold level. Built-ins are normal (4.5), large (3.0), aaa_normal (7.0), and aaa_large (4.5); the threshold map can add or override names. --level aaa maps normal and large to their AAA counterparts, while --fail-under N overrides every token's threshold.

Derived expressions may use background names as operands (for example, rgba(0,0,0,.5) over surface); references may be nested or chained, and unknown or cyclic references are rejected as input errors.

Why a matrix?

Pairwise checkers answer whether one foreground works on one background. Design tokens often render on several surfaces, including translucent and derived colors. This tool evaluates every declared pair and reports the minimum ratio and the background that produced it, making the worst case an explicit, deterministic CI result.

The calculation follows WCAG 2.x: sRGB channels are linearized, relative luminance uses the 0.2126/0.7152/0.0722 coefficients, and contrast is (Llight + 0.05) / (Ldark + 0.05). Alpha foregrounds are composited before comparison. This implements the WCAG 2.x contrast formula; it is not an APCA/WCAG 3 implementation.

Output

--format table prints a compact summary. json emits the complete sorted result, including all pairs. sarif emits SARIF 2.1.0 findings for failed tokens. Inputs, tokens, backgrounds, and JSON keys are ordered deterministically so repeated runs produce clean diffs. See examples.

Development

python -m pip install -e '.[dev]'
pytest -q

License

Apache-2.0.

Built and maintained by Gexiro Global Enterprises Ltd.

Part of the Gexiro open-source toolkit.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

contrast_matrix-0.1.0.tar.gz (17.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

contrast_matrix-0.1.0-py3-none-any.whl (14.5 kB view details)

Uploaded Python 3

File details

Details for the file contrast_matrix-0.1.0.tar.gz.

File metadata

  • Download URL: contrast_matrix-0.1.0.tar.gz
  • Upload date:
  • Size: 17.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.13

File hashes

Hashes for contrast_matrix-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8a7f9a5ecc7fd14cfaccace36be34b757b318aa1c2a2cb32b002c1fcb147a88f
MD5 4fbd86ef246afacf0729afef7c6fe5d8
BLAKE2b-256 38e01c88e9d5e842d110b41deee6138ad319ac88355a4558c5e444acd53d4ca0

See more details on using hashes here.

File details

Details for the file contrast_matrix-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for contrast_matrix-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8ee4d6a2edf9b607eaf9984246c90dcd0d366ba5391c052cd2bb23bba0657801
MD5 6179c609c1090d0559008061f704a237
BLAKE2b-256 c4f6d9c9a14f7a9a388bf494305fd2f91e126a0a060988f4b42a6c218e03b443

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page