Mergify Digital

Free tool · Download

Accessibility Content QA

A local, offline checker for static HTML. Give it an HTML file — or paste HTML into its local browser UI — and it returns a deterministic 0–100 score, a pass/fail gate, and a list of findings as JSON. It runs entirely on your machine: no uploads, no network calls, nothing leaves your computer. That makes it safe for client staging pages you cannot send to an online scanner.

Free download — unzip and run. Needs Python 3.12 or newer; standard library only, nothing to install.

What it checks

  • Missing language — an <html> element with no non-empty lang attribute (high severity).
  • Images without alt text — an <img> with no alt attribute at all (high), and empty alt text on images not marked decorative (low).
  • Unlabeled form controls — checked properly: a wrapping label, a matching label for, aria-label, aria-labelledby, or a title all count (high).
  • Title and meta — a missing or empty document <title> (medium) and a missing meta description (low).
  • Heading structure — first heading not an H1, level jumps like H2 → H4, and empty headings (medium).
  • Link text — links with no text (medium) and generic text like “click here” or “read more” (low).

Scoring is deterministic: the same HTML always produces the same score. It starts at 100; each finding subtracts a fixed penalty (high 18, medium 10, low 4). The gate passes only at a score of 80 or more and zero high-severity findings.

Real output

Sample run — a page with planted mistakesGate: fail
{
  "score": 14,
  "pass": false,
  "summary": {
    "issues": 8,
    "by_severity": { "high": 3, "medium": 2, "low": 3 },
    "images": 2, "links": 1, "form_controls": 1
  },
  "issues": [
    { "code": "html_lang_missing", "severity": "high",
      "message": "The html element is missing a non-empty lang attribute." },
    { "code": "image_alt_missing", "severity": "high",
      "message": "Image is missing an alt attribute." },
    { "code": "form_control_unlabeled", "severity": "high",
      "message": "Form control has no label, aria-label, aria-labelledby, or title." }
  ]
}
Trimmed for display — the full report listed all 8 findings. This is a real run of the downloadable tool against a small sample page, produced for this page. Fix the findings and re-run: the corrected version of that same sample scores 100, gate pass, zero findings.

Two ways to run it

  • Command line — python app.py page.html --pretty prints the JSON report. Exit code 0 means the gate passed, 2 means it failed, so it drops straight into a pre-publish checklist or a CI step.
  • Local WebUI — python webui_private_v11.py --port 8797, then open http://127.0.0.1:8797/ on the same machine and paste HTML (up to 1 MiB). It binds to loopback only and rejects non-local requests.

The honest limits

This tool checks a defined subset of static-HTML issues only. It does not check color contrast, keyboard navigation or focus order, ARIA validity beyond the label handling above, or anything JavaScript renders after load — and it never fetches or crawls a live URL. It is not a WCAG certification tool and does not certify any page or site. Its job is the fast, private, repeatable pre-publish gate in front of a full audit. The full scope note is in the guide.

From the same factory: when the pages you check carry product images for print-on-demand, PrintReady DPI preps those images — 4500×5400 canvas, 300 DPI, transparency cleaned — so uploads stop getting rejected. PrintReady DPI →

More free tools: TextClean Transformer cleans pasted text right in your browser, and AudioMaster LUFS masters audio to streaming loudness targets. All three are also in the free tools section on the home page.