Skip to main content

designlint-py

Python License: MIT

HTML/CSS accessibility and design linter for contrast, touch targets, heading hierarchy, form labels, and leaked secrets. Stdlib-only -- no parser dependencies.

Python port of @mukundakatta/designlint. The JS sibling has the broader ruleset (responsive images, viewport meta, etc.); this Python port focuses on the spec's five rule families and uses the standard library's html.parser for HTML walking.

Install

pip install designlint-py

Usage

from designlint import lint

html = """
<html>
  <body>
    <p style="color: #ccc; background-color: #fff">low contrast</p>
    <a style="display: inline-block; width: 20px; height: 20px;">tap</a>
    <h1>Title</h1>
    <h3>Skipped a level</h3>
    <input type="text">
    <pre>sk-ant-1234567890abcdef1234567890abcdef</pre>
  </body>
</html>
"""

findings = lint(html)
for f in findings:
    print(f.line, f.severity, f.rule_id, f.message)

Each finding is a dataclass:

Finding(
    rule_id="color-contrast",
    severity="error",
    message="Contrast ratio 1.61:1 is below WCAG AA minimum of 4.5:1.",
    line=4,
    snippet='<p style="color: #ccc; background-color: #fff">',
)

Rules

Rule id Severity Checks
color-contrast error Inline color vs background-color against WCAG 2.1 AA (4.5:1 normal, 3:1 large).
touch-target-size warning Interactive elements (a, button, input[type=button/submit]) below 24x24 CSS pixels.
heading-hierarchy warning First heading must be h1; no skipping levels (e.g. h1 -> h3).
form-label error input / select / textarea without an associated <label for> or aria-label.
leaked-secret error Provider-shaped API keys (OpenAI, Anthropic, GitHub, AWS, Slack, Stripe, Google AI) in any text content or attribute value.

API

  • lint(html_string) -> list[Finding] -- run the full ruleset.
  • Finding(rule_id, severity, message, line, snippet) -- result dataclass.
  • parse_color(value) -> RGBA | None, contrast_ratio(fg, bg) -> float, parse_css_size(value) -> float | None -- helpers exported for reuse.

API differences from the JS sibling

  • Stdlib-only: uses Python's html.parser instead of parse5 + css-tree. Selector matching for <style> blocks is therefore omitted; only inline style=... attributes contribute to contrast/size analysis.
  • Returns a flat list[Finding] instead of { issues, score, summary } -- matches the spec's lint(html_string) -> list[Finding] shape. Compute a score yourself if you need one.
  • Rule set is the spec's five families. The JS port has additional rules (responsive images, viewport meta, link rel-noopener) that aren't in scope here.

See the JS sibling's README for the broader rationale.

Metadata

Release files for designlint-py 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for designlint-py 0.1.0
File Size Uploaded Provenance Actions
designlint_py-0.1.0.tar.gz 14.2 kB Without provenance Details for designlint_py-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for designlint-py 0.1.0
File Interpreter ABI Platform Actions
designlint_py-0.1.0-py3-none-any.whl Python 3 none any Details for designlint_py-0.1.0-py3-none-any.whl

Total release size: 28.9 kB

Release files / designlint_py-0.1.0.tar.gz

Download URL designlint_py-0.1.0.tar.gz
Size 14.2 kB
Tags Source
SHA-256 checksum
How to use checksums
33f9f7833a0ed05c03fb9e61b04fbe4caf3bbf72826bd295334b3af4bf892190
BLAKE2b-256 checksum
How to use checksums
ae90f9157e03dc9545af0aedf40299ac213e4c1b10788edf70dc5ec6d33ba173
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release files / designlint_py-0.1.0-py3-none-any.whl

Download URL designlint_py-0.1.0-py3-none-any.whl
Size 14.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0fd0d8ad86cc5aac2068e3c6b7f0c49892a4cffde1fc4fc60e9193dc72aea2e4
BLAKE2b-256 checksum
How to use checksums
0a567f181a9cace16834641c63a1f5be89946d1951dd764e45a421dde9bd9c34
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Security for designlint-py 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page