Custom Rules & Heuristics
A11yEngine pairs standard axe-core 4.10.0 compliance checks with 43 proprietary local heuristic rules to audit interactive controls, media accessibility, focus safety, WAVE parity, and secure PII compliance.
custom-focus-trap-and-returnModal Dialog Focus Trap & Return
Simulates modal dismissal via Escape key and verifies if keyboard focus is properly trapped inside active dialogs and returned to trigger elements upon close.
<div role="dialog"><button onclick="closeModal()">Close</button></div><div role="dialog" aria-modal="true" aria-labelledby="modal-title"><h2 id="modal-title">Terms</h2><button onclick="closeModal()" ref={closeBtnRef}>Close</button></div>custom-widget-contractARIA Accordion / Widget State Contract
Validates aria-expanded toggle state transitions and verifies that aria-controls points to existing DOM target elements.
<button onclick="toggle()">Accordion</button><button aria-expanded="true" aria-controls="panel-1" onclick="toggle()">Accordion</button>
<div id="panel-1">Content</div>custom-live-region-chatterExcessive Live Region Announcement Chatter
Monitors dynamic DOM mutations to prevent excessive or rapid aria-live updates from overwhelming screen readers.
<div aria-live="assertive">Position updating every 50ms...</div><div aria-live="polite" aria-atomic="true">Status: Processing complete.</div>custom-spa-route-focusSPA Navigation Focus Reset Loss
Detects client-side SPA route transitions in React, Next.js, and Vue, verifying keyboard focus resets to the main heading or container.
router.push('/dashboard'); // Focus remains stuck on previous page linkrouter.push('/dashboard'); document.querySelector('h1')?.focus();custom-focus-outline-resetInvisible Keyboard Focus Indicator
Flags elements that override the browser default focus indicator (using outline:none, outline:0, or focus:outline-none) without declaring a visible fallback ring.
<button class="bg-[#111111] text-white focus:outline-none">Complete Purchase</button><button class="bg-[#111111] text-white focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">Complete Purchase</button>custom-tabindex-improperHardcoded Positive Tabindex
Detects element declarations with positive tabindex attributes (tabindex > 0). Hardcoding positive tabindex values disrupts natural top-down tabbing flow.
<a href="/pricing" tabindex="3">Pricing</a><a href="/pricing">Pricing</a>custom-keyboard-nav-missingUnreachable Clickable Custom Control
Catches non-interactive elements (like <div> or <span>) that have click listeners but lack tabindex attributes or keyboard event handlers.
<div onclick="submitOrder()" role="button">Buy Now</div><div onclick="submitOrder()" role="button" tabindex="0" onkeydown="if(event.key==='Enter'||event.key===' '){submitOrder();}">Buy Now</div>custom-aria-icon-missingIcon-Only Control Lacks Description
Flags links and buttons containing only SVG or vector glyphs with no textual label or aria-label attributes.
<button><svg class="w-4 h-4"></svg></button><button aria-label="Delete item permanently"><svg class="w-4 h-4"></svg></button>custom-accessible-name-mismatchVisible Label Mismatch in ARIA Name
Identifies custom controls where the visible text string is not included inside the aria-label attribute for speech recognition users.
<button aria-label="Submit credit details">Pay Now</button><button aria-label="Pay Now and submit credit details">Pay Now</button>custom-motion-preference-checkAnimation Lacks Reduced Motion Query
Identifies CSS animations lacking @media (prefers-reduced-motion) wrappers for vestibular motion sensitivity.
.animated-hero { animation: spin 2s infinite; }@media (prefers-reduced-motion: no-preference) { .animated-hero { animation: spin 2s infinite; } }custom-autoplay-mediaAutoplay Sound / Video Block
Flags audio or video elements configured to autoplay sound. Autoplay audio overrides screen reader voices.
<video src="/assets/intro.mp4" autoplay></video><video src="/assets/intro.mp4" controls></video>custom-video-captions-missingVideo Component Lacks Subtitles/Captions
Flags video player elements that do not contain a child <track kind="captions"> or <track kind="subtitles"> node.
<video controls src="/assets/intro.mp4"></video><video controls src="/assets/intro.mp4"><track default kind="captions" srclang="en" src="/captions_en.vtt"></video>custom-vague-link-textVague Descriptive Link Labels
Flags links labeled with generic terms like "click here", "read more", or "learn more".
<a href="/docs/api">Click Here</a> to view docs.<a href="/docs/api">View the API Documentation</a>.custom-skip-link-missingMissing "Skip to Main Content" Bypass
Flags pages with navigation headers or sidebars that lack a hidden skip bypass link as the first focusable child.
<body><nav><!-- menu --></nav><main id="main-content"><body><a href="#main-content" class="sr-only focus:not-sr-only">Skip to Main Content</a><nav></nav><main id="main-content">custom-skip-link-advisorySkip Link Target Visibility Advisory
Verifies existing skip link targets resolve to valid focusable DOM elements on the page.
<a href="#non-existent">Skip</a><a href="#main-content">Skip to Main Content</a>custom-theme-persistenceDark/Light Theme Toggle State
Audits theme switcher controls for proper aria-pressed state attributes and theme contrast.
<button onclick="toggleTheme()">Theme</button><button aria-pressed="true" aria-label="Toggle dark theme" onclick="toggleTheme()">Theme</button>custom-pdf-accessibilityScanned or Untagged PDF Document Link
Scans page PDF link destinations via Web Worker to detect scanned image-only PDFs lacking text layers.
<a href="/scanned-contract.pdf">Download Agreement</a><a href="/accessible-contract.pdf">Download Accessible PDF Agreement (Text-Searchable)</a>custom-governance-statementAccessibility Statement Missing in Footer
Audits global page footer for presence of an explicit link to an Accessibility Statement page.
<footer><a href="/privacy">Privacy</a></footer><footer><a href="/privacy">Privacy</a> <a href="/accessibility">Accessibility Statement</a></footer>custom-decorative-image-altDecorative Image Has Non-Empty Alt Text
Flags decorative images (role="presentation" or aria-hidden="true") that still contain a non-empty alt attribute.
<img role="presentation" alt="Company Banner" src="banner.png" /><img role="presentation" alt="" src="banner.png" />custom-audio-description-missingVideo Lacks Audio Description Track
Flags video elements missing <track kind="descriptions"> for blind visual narration.
<video src="tutorial.mp4" controls></video><video src="tutorial.mp4" controls><track kind="descriptions" src="desc_en.vtt"></video>custom-audio-transcript-missingAudio Content Missing Text Transcript
Flags <audio> elements with no nearby text transcript link or aria-describedby reference.
<audio src="podcast.mp3" controls></audio><audio src="podcast.mp3" controls></audio><a href="/transcripts/podcast-1.html">Read Transcript</a>custom-color-alone-requiredRequired Field Indicated by Color Alone
Flags required form fields that rely on red color styling alone without a visible asterisk (*), text label, or aria-required attribute.
<label class="text-red-500">Email <input type="email" required /></label><label>Email <span class="text-red-500">*</span> <input type="email" required aria-required="true" /></label>custom-images-of-textImage Appears to Contain Styled Text
Flags images whose alt text is a full sentence (>30 chars), indicating text baked into images instead of HTML.
<img alt="Special Offer 50% Off Everything Today Only Click Now" src="banner.png" /><div class="bg-indigo-600 text-white p-6 font-bold text-2xl">Special Offer 50% Off Everything</div>custom-title-attribute-advisoryTitle Attribute Advisory on Controls
Flags usage of native title tooltips on interactive elements which are inaccessible on touch devices.
<button title="Deletes item from cart">Remove</button><button aria-describedby="tooltip-1">Remove</button><div id="tooltip-1" role="tooltip">Deletes item</div>custom-sensory-characteristicsInstruction Relies on Shape or Position Alone
Audits page text for instructions that rely on visual shape, color, or location parameters alone (e.g. instructing users to select controls by color or position).
<p>Click the green round button on the right to complete checkout.</p><p>Select the "Complete Checkout" button to finish your order.</p>custom-page-title-missingPage Title Missing
Flags pages missing a top-level <title> element.
<head></head><head><title>Checkout - MyStore Official</title></head>custom-page-title-genericPage Title Generic
Flags pages with default titles like "Home", "Untitled Page", or "Document".
<title>Home</title><title>Dashboard - A11yEngine Platform</title>custom-page-title-duplicate-h1Page Title Duplicates H1 String
Flags page titles that are identical copies of the main H1 heading without brand name context.
<title>Contact Us</title><title>Contact Us | A11yEngine Platform</title>custom-touch-target-sizeTouch Target Too Small (<24×24px)
Flags interactive controls with bounding dimensions under 24×24 CSS px (WCAG 2.2 target size requirement).
<button style="width:14px; height:14px;">x</button><button style="min-width:24px; min-height:24px; padding:6px;">x</button>custom-auto-updating-marqueeAuto-Scrolling Marquee Without Pause
Flags <marquee> elements or dynamic auto-scrolling containers lacking pause controls.
<marquee>Breaking News Flash</marquee><div class="carousel" data-pause="true"><button aria-label="Pause marquee">Pause</button></div>custom-meta-refreshMeta Refresh Redirect Present
Flags <meta http-equiv="refresh"> elements that cause unannounced page reloads.
<meta http-equiv="refresh" content="5;url=/login">// Perform server-side or user-initiated navigation insteadcustom-carousel-no-pauseCarousel Slider Lacks Pause Control
Flags auto-rotating hero sliders lacking explicit pause/stop toggle buttons.
<div class="slider-auto">...</div><div class="slider"><button aria-label="Pause slider">Pause</button></div>custom-flashing-contentFlashing Animation Exceeds 3 Flashes/sec
Flags CSS animations with durations under 333ms, which can trigger seizures in photosensitive users.
<div style="animation: flash 100ms infinite;">Notice</div><div style="animation: pulse 2s ease-in-out infinite;">Notice</div>custom-drag-drop-no-keyboard-altDrag-and-Drop Has No Keyboard Alternative
Flags draggable="true" elements lacking keyboard reordering controls ("Move Up / Move Down").
<div draggable="true">Item 1</div><div draggable="true">Item 1 <button aria-label="Move item up">▲</button></div>custom-focus-indicator-qualityFocus Indicator Contrast Advisory
Audits focus ring contrast against adjacent background colors.
button:focus { outline: 1px solid #eee; }button:focus { outline: 2px solid #4f46e5; }custom-language-of-partsForeign Language Content Missing lang Attribute
Flags foreign-language text snippets on English pages missing explicit lang="..." attributes.
<p>S'il vous plaît revoir ce document</p><p lang="fr">S'il vous plaît revoir ce document</p>custom-auto-context-changeSelect Input Triggers Automatic Context Change
Flags <select> elements with onchange handlers that automatically submit forms on option pick.
<select onchange="this.form.submit()"><option>1</option></select><form><select><option>1</option></select><button type="submit">Go</button></form>custom-form-error-color-onlyForm Error Indicated by Color Alone
Flags form fields with red border error styling that lack text descriptions or aria-describedby references.
<input class="border-red-500" /><input class="border-red-500" aria-describedby="err-1" aria-invalid="true" /><span id="err-1" class="text-red-600 text-xs">Enter valid email.</span>custom-empty-buttonEmpty Button Lacks Accessible Name (WAVE Parity)
Flags <button> elements with no inner text, aria-label, title, or image alt text.
<button></button><button aria-label="Close dialog">✕</button>custom-broken-aria-referenceBroken ARIA ID Reference (WAVE Parity)
Flags aria-labelledby, aria-describedby, or aria-controls pointing to non-existent DOM element IDs.
<input aria-describedby="missing-id" /><input aria-describedby="help-text" /><span id="help-text">Enter 8+ chars.</span>custom-skipped-heading-levelNon-Sequential Skipped Heading Level (WAVE Parity)
Flags heading structures that skip levels non-sequentially (e.g. H1 directly to H3).
<h1>Main Title</h1>
<h3>Sub Header</h3><h1>Main Title</h1>
<h2>Sub Header</h2>custom-redundant-linkAdjacent Redundant Links (WAVE Parity)
Flags adjacent links pointing to the exact same href destination.
<a href="/about"><img src="thumb.jpg" alt="" /></a> <a href="/about">About Us</a><a href="/about"><img src="thumb.jpg" alt="" /> About Us</a>custom-noscript-elementNoscript Element Present (WAVE Parity)
Flags <noscript> tags whose content is hidden from JavaScript-enabled screen readers.
<noscript>Enable JS to view this site.</noscript><div role="alert">JavaScript is recommended.</div>