Skip to content
SCRAWL

Website Accessibility Checker: Static HTML Checks

Static HTML accessibility checks on one URL. Alt text, labels, headings, lang, title, IDs, and ARIA rules. Raw HTML only, no JS. Not a full WCAG audit.

  • Open the tool
  • Enter your URL or data
  • Review your results
  • Browser-based — no install
  • Instant results

Paste one URL for static HTML accessibility checks: alt text, link and button names, form labels, headings, lang, title, duplicate ids, and basic ARIA rules. Raw HTML only — not a WCAG audit; pair with Image Alt Checker or Heading Visualizer for deeper views.

By Faisal YUpdated

Step-by-step guide
Website Accessibility Checker — Static HTML

Shipping a template change on Friday and hoping accessibility “just works” is how empty links and missing lang attributes reach production. Automated checks will not replace a skilled audit, but they will catch a predictable set of HTML mistakes in minutes — if you know what they measure and what they ignore. The Accessibility Checker on Scrawl fetches one URL , parses the raw HTML (up to 1.5MB), and runs a fixed rule set: image alt , link and button names, form labels, heading structure, document lang and <title> , duplicate id values, and a small set of ARIA misuse patterns. JavaScript is not executed. Results are grouped by check with error, warning, and info severities — not a percentage score or WCAG certificate. ! Three-step flow from SSRF-safe fetch through capped static checks to issues by severity Why static HTML checks are worth running first Manual accessibility testing is slow. Fully manual testing of every component state is unrealistic before each deploy. Static linters trade depth for speed: they flag markup patterns that break baseline access — unnamed controls, missing document language, images without alt — before you spend time in VoiceOver or NVDA. That matters for three practical reasons: Usability and compliance context — Unlabeled form fields and icon-only links with no accessible name block people who rely on screen readers or voice control from completing tasks. Fixing those patterns in HTML is a practical baseline before deeper testing. Crawl and parsing — Search engines and assistive technologies both lean on HTML semantics. A missing <title> or duplicate id breaking a label[for] association hurts humans and creates brittle DOM hooks for scripts. Template QA — CMS swaps, header/footer refactors, and design-system rollouts repeat the same mistakes site-wide. One URL through a linter on a staging host catches class-level…

Read the full guide

What this checker does

The Accessibility Checker fetches **one URL** and runs a fixed battery of **static HTML rules** on the initial response. It does not render JavaScript, simulate keyboard focus, measure color contrast, or score WCAG conformance. Results are grouped by check type with **error**, **warning**, and **info** severities, plus a per-check pass/found table.

Checks include:

- **Images** — `img` elements without an `alt` attribute (decorative `alt=""`, `role="presentation"`, and `aria-hidden` images are skipped); `input type="image"` without alt - **Links** — `a[href]` with no accessible name (visible text, `aria-label`, `aria-labelledby`, `title`, or child image with non-empty alt) - **Buttons** — `button`, `[role=button]`, and `input[type=button|submit|reset]` with no accessible name - **Form controls** — `input` (except hidden/submit/button/reset/image), `select`, and `textarea` without a label association (`label[for]`, wrapping `label`, `aria-label`, or valid `aria-labelledby`); `title`-only names are flagged as warnings - **Headings** — missing `h1`, multiple `h1`, skipped levels (for example `h2` then `h4`), empty heading elements - **Document** — missing or empty `lang` on `<html>`, malformed `lang` values, missing or empty `<title>` - **IDs** — duplicate `id` attribute values (each duplicate id reported once with count) - **ARIA** — invalid `role` values, `aria-hidden="true"` on focusable elements, `aria-labelledby` / `aria-describedby` pointing at missing ids, `role=button|link` on non-focusable elements without `tabindex`, redundant roles on native elements (info) - **Optional** — `iframe` without `title`, positive `tabindex`, viewport meta that blocks zoom (`user-scalable=no` or `maximum-scale` below 2)

Export CSV if you need a spreadsheet paper trail. HTML is capped at 1.5MB; issue lists cap at 200 total and 25 per check.

How to read results

Start with **errors** — they are the patterns most likely to block basic access (missing names, missing document language, duplicate ids used by labels). **Warnings** often mean “fix soon” (heading level skips, title-only labels, zoom lock). **Info** rows are educational (multiple `h1`, redundant ARIA roles).

Each row shows a short **snippet** of the element (tag and key attributes only). Snippets are plain text, not live HTML from the page.

How to fix common findings

**Missing alt** — Add a concise description, or `alt=""` if the image is decorative.

```html <!-- Before --> <img src="/chart.png">

<!-- After --> <img src="/chart.png" alt="Q3 revenue up 12% year over year"> ```

**Unlabeled input** — Tie a `label` to the control id or use `aria-label`.

```html <label for="email">Email</label> <input id="email" type="email" name="email"> ```

**Empty link** — Ensure visible text or an accessible name.

```html <a href="/pricing">View pricing</a> ```

**Skipped heading levels** — Nest headings without jumping levels when possible.

What this tool cannot do

- **No color contrast** — contrast needs computed styles and is out of scope - **No keyboard or focus order testing** — tab order, focus traps, and modals need manual or specialized tools - **No JavaScript rendering** — client-only widgets, SPA routes, and dynamically injected labels are invisible to this fetch - **No screen reader testing** — accessible name heuristics are not a substitute for NVDA, VoiceOver, or JAWS - **No WCAG certification** — automated rules catch a fraction of issues; a clean result here does not mean “WCAG compliant”

Treat this as a **first pass** before manual QA and before a full accessibility audit.

How this differs from other Scrawl tools

- **[Image Alt Checker](/tools/image-alt-checker)** — image-by-image alt listing only. Use it when you need every `src` in a table; use this tool for a broader static pass on one page. - **[Heading Visualizer](/tools/heading-visualizer)** — visual H1–H6 outline and two-URL comparison. Use it for structure review; this tool only reports heading-related issues alongside other checks. - **[H1/H2 Extractor](/tools/h1-h2-extractor)** — bulk heading text across up to 100 URLs with no a11y rules. - **[Link Extractor](/tools/link-extractor)** and **[Internal Link Analyzer](/tools/internal-link-analyzer)** — full link inventories and anchor text; this tool only flags links with no accessible name. - **[SEO Readiness Checker](/tools/seo-readiness-checker)** — general SEO signals, not accessibility-only.

Frequently Asked Questions

What does the Accessibility Checker test?

It runs static rules on raw HTML: image alt text, link and button names, form labels, heading structure, html lang and title, duplicate ids, basic ARIA misuse, and a few optional checks like iframe titles and viewport zoom lock.

Does it check color contrast or keyboard access?

No. Contrast needs computed styles; keyboard and focus behavior need manual testing or dedicated tools. This checker only inspects the initial HTML string.

Does it execute JavaScript?

No. Only the first HTML response from the server is parsed. Content that appears only after client-side rendering is out of scope.

Is this a WCAG audit or compliance certificate?

No. It is a quick automated linter. WCAG conformance requires manual testing and often professional audit scope beyond static HTML rules.

How is this different from the Image Alt Checker or Heading Visualizer?

Image Alt Checker lists every image and alt on a page. Heading Visualizer shows a visual outline. This tool runs many check types on one URL and reports issues in one list.

What are the limits?

One URL per run, HTML capped at 1.5MB, up to 200 issues total and 25 per check type, with rate limits on fetch. Private and localhost URLs are blocked.