role attribute" — SC 4.1.2From generic "42 violations" to specific "8 of 14 widgets don't conform — 6 auto-fixable." See what static scanners miss and what SmartQCompliance delivers.
aria-haspopup, aria-expanded, and keyboard support"Every morning, your GRC team gets a one-page executive brief written by AI — not a 200-row spreadsheet. Here's what the Widget Compliance section looks like:
The site contains 14 interactive widgets. 6 conform to W3C ARIA Authoring Practices.
Of the 8 non-conforming widgets:
That's the kind of analysis that makes a procurement officer say "fix it" and a general counsel say "now."
Each use case shows exactly what static scanners find vs. what DeepScan finds — and the complete fix we generate from W3C reference implementations.
role attribute" — SC 4.1.2aria-expanded, aria-controls, and aria-activedescendant — screen reader users cannot tell when search results appear, which result is highlighted, or navigate results with arrow keys. W3C APG Combobox pattern requires all three.<input role="combobox"> — adds the role, widget still brokenaria-expanded (toggles on open/close), aria-controls (points to results listbox), aria-activedescendant (tracks highlighted result), keyboard handler (Arrow Down opens, Arrow keys navigate, Enter selects, Escape closes) — generated from W3C combobox reference implementationaria-expanded toggles to true, presses Arrow Down, verifies aria-activedescendant updates, presses Escape, verifies aria-expanded returns to falsearia-haspopup, aria-expanded, and keyboard handler — screen reader users cannot discover the dropdown exists, cannot tell when it opens, and cannot navigate menu items with arrow keys. W3C APG Menu Button pattern requires aria-haspopup='menu', aria-expanded, and Arrow/Escape keyboard support.<button aria-label="Products"> — adds the name, dropdown still invisible to screen readersaria-haspopup="menu", aria-expanded (toggles), aria-controls (points to menu), menu container with role="menu", items with role="menuitem", keyboard handler (Enter/Space/Down Arrow opens, Arrow keys navigate, Escape closes, Home/End for first/last) — from W3C Menu Button referencearia-expanded becomes true and focus moves into menu, presses Arrow Down, verifies focus moves to next menuitem, presses Escape, verifies menu closes and focus returns to buttonaria-labelledby" — SC 4.1.2aria-modal='true' — background page content is still announced by screen readers, mixing with dialog content. Focus is not trapped within dialog — Tab key moves focus behind the dialog. Escape key does not close the dialog. W3C APG Dialog (Modal) pattern requires aria-modal, focus trapping, and Escape to close.<div role="dialog" aria-labelledby="title"> — adds label, background still interferes, focus still escapesaria-modal="true", aria-labelledby pointing to visible heading, focus trap (Tab wraps within dialog), Escape closes and returns focus to trigger button, aria-describedby for instructions — from W3C Dialog Modal referencetabpanel role" — SC 1.3.1aria-selected on tabs, aria-controls linking tabs to panels, and aria-labelledby on panels. Arrow keys do not navigate between tabs. Screen reader users cannot determine which tab is active or access panel content. W3C APG Tabs pattern requires roving tabindex, aria-selected, and bidirectional linking.<div role="tabpanel"> — adds panel role, tabs still don't communicate selection or support keyboardrole="tablist" container, each tab with role="tab", aria-selected (true on active, false on others), aria-controls pointing to its panel, each panel with role="tabpanel" and aria-labelledby pointing back to its tab, Arrow Left/Right to navigate tabs, Home/End for first/last — from W3C Tabs referencearia-selected changes to the next tab, verifies the corresponding tabpanel becomes visible and previous one hides<div> with click handler — missing role='switch' and aria-checked. Screen reader announces nothing. Keyboard users cannot activate it (no Space/Enter handler). W3C APG Switch pattern requires role='switch', aria-checked (true/false), and Space key to toggle.<div role="checkbox"> — wrong role (switch, not checkbox), still no keyboard handlerrole="switch", aria-checked (toggles true/false), accessible label via aria-labelledby, Space and Enter key handlers, visual state synchronized with aria-checked — from W3C Switch referencearia-checked toggles from false to true, presses Space again, verifies it returns to falserole='spinbutton', aria-valuemin, aria-valuemax, and aria-valuenow. Arrow keys do not adjust the value. Screen reader users cannot determine the current quantity or the allowed range. W3C APG Spin Button pattern requires value properties and Arrow key support.<button aria-label="Increase quantity"> — labels one button, the widget is still not a spinbuttonrole="spinbutton", aria-valuenow (current qty), aria-valuemin="1", aria-valuemax (stock limit), aria-label, Up/Down Arrow keys to increment/decrement, Home/End for min/max — from W3C Spin Button referencearia-valuenow increments, presses Arrow Down, verifies it decrements, presses Home, verifies it goes to aria-valueminaria-expanded and aria-controls — screen reader users cannot tell which sections are open or closed, and cannot discover that headers are expandable. W3C APG Accordion pattern requires aria-expanded on each header button and aria-controls pointing to the content region.aria-expanded (toggles true/false), aria-controls pointing to content panel, optional role="region" on panels with aria-labelledby back to header — from W3C Accordion referencearia-expanded changes from false to true, verifies content panel becomes visible, activates again, verifies it collapsesaria-expanded, calendar grid missing role='grid', day cells missing role='gridcell', selected date not marked with aria-selected. Keyboard users cannot navigate the calendar with Arrow keys. W3C APG Combobox Date Picker pattern requires combobox properties on input, grid pattern on calendar, and full arrow key navigation.<input aria-label="Select date"> — labels the input, calendar grid still inaccessiblearia-expanded on input, aria-controls pointing to grid dialog, grid with role="grid", rows with role="row", cells with role="gridcell", selected date with aria-selected="true", Arrow keys navigate between days, Page Up/Down for months, Enter selects — from W3C Combobox Date Picker referencearia-expanded toggles, presses Arrow Right, verifies focus moves to next day, presses Enter, verifies date is selected and aria-selected is setrole='radiogroup' on container and role='radio' on each star. No aria-checked state. Arrow keys do not navigate between options. Screen reader users cannot determine current selection or change it. W3C APG Radio Group pattern requires radiogroup, radio, aria-checked, and Arrow key navigation with roving tabindex.<img alt="3 out of 5 stars"> — makes the image readable but the interactive rating is still brokenrole="radiogroup" and aria-label="Rating", each star with role="radio" and aria-checked (true on selected, false on others), aria-label="1 star" through "5 stars", Arrow keys to navigate and select, roving tabindex — from W3C Radio Group referencearia-checked moves to next star and previous star becomes uncheckedaria-label on region" — SC 1.3.1aria-roledescription='carousel', slide container missing aria-live region, no pause button for auto-rotation. When slides auto-advance, screen reader users are not notified. Users with vestibular disorders cannot pause the animation. W3C APG Carousel pattern requires aria-roledescription, aria-label, live region or tab pattern for slides, and a visible pause control.<div role="region" aria-label="Featured products"> — labels the container, auto-rotation still inaccessiblearia-roledescription="carousel", aria-label, tab interface or live region for slides, visible pause/play button, aria-live="off" when paused, respects prefers-reduced-motion — from W3C Carousel referencearia-live changes or rotation stops, verifies prefers-reduced-motion is respectedrole='alert' or aria-live region — screen reader users are never notified when items are added to cart. They must navigate to the cart icon to discover the count changed. W3C APG Alert pattern requires role='alert' (implicit aria-live='assertive') on the container so content is announced immediately.role="alert", content injected dynamically, not present at page load, announced immediately by screen reader without focus change — from W3C Alert referencearia-multiselectable — users cannot multi-select filters. Options missing aria-selected — screen reader cannot announce which filters are active. Arrow keys do not navigate options. W3C APG Listbox pattern requires listbox, option roles, aria-selected, and Shift+Click/Space for multi-select.<ul role="list"> — wrong role entirely (list, not listbox)role="listbox", aria-multiselectable="true", aria-label="Filter by size", each option with role="option" and aria-selected, Arrow keys navigate, Space toggles selection, Shift+Space for range select — from W3C Listbox referencearia-selected toggles to truearia-label" — SC 2.4.8aria-current='page' on the current page link — screen reader users cannot distinguish the current location from other breadcrumb links. W3C APG Breadcrumb pattern requires aria-current='page' on the link representing the current page.<nav aria-label="Breadcrumb"> — labels the nav, current page still not identified<nav aria-label="Breadcrumb">, ordered list of links, current page link with aria-current="page" — from W3C Breadcrumb referencearia-current="page" on the last (current) linkrole='slider', aria-valuemin, aria-valuemax, aria-valuenow, and aria-valuetext. Keyboard users cannot adjust the value — Arrow keys do nothing. Screen reader users cannot determine the current price range. W3C APG Slider Multi-Thumb pattern requires two slider elements with independent value ranges and Arrow key controls.tabindex="0" — makes it focusable but Arrow keys still do nothingrole="slider", aria-valuemin="0", aria-valuemax="500", aria-valuenow (current value), aria-valuetext="$150" (human-readable), aria-label="Minimum price" / "Maximum price", Arrow keys adjust value, Home/End for min/max — from W3C Multi-Thumb Slider referencearia-valuenow increments, checks aria-valuetext updates to readable price formataria-pressed — screen reader users cannot determine whether dark mode is on or off. W3C APG Button pattern requires aria-pressed (true/false) for toggle buttons. The label must NOT change when state changes.<button aria-label="Dark Mode"> — adds name, pressed state still unknownaria-pressed (toggles true/false on activation), consistent label that doesn't change, Enter/Space to toggle — from W3C Button referencearia-pressed changes from false to true, activates again, verifies it returns to false, confirms label text does not changearia-expanded and aria-controls — screen reader users cannot tell whether content is shown or hidden, and cannot discover the relationship between the button and the content it controls. W3C APG Disclosure pattern requires aria-expanded on the trigger and aria-controls pointing to the content.<a href="#" aria-label="Read more about product"> — adds description, still no expanded state<button aria-expanded="false" aria-controls="details-panel">Read More</button>, content panel with matching ID, aria-expanded toggles on activation — from W3C Disclosure referencearia-expanded changes to true, verifies content panel becomes visible in AX treearia-sort on column headers — screen reader users cannot determine sort direction (ascending, descending, none). Column headers missing role='columnheader'. W3C APG Table pattern requires aria-sort with values ascending, descending, or none on sortable headers.<table><caption>Product Comparison</caption> — adds caption, sort state still invisiblerole="table" (or native <table>), column headers with role="columnheader", sortable headers with aria-sort="ascending" / "descending" / "none", aria-sort updates on click — from W3C Table referencearia-sort changes from none to ascending, activates again, verifies it changes to descendingrole='tree' on container, items missing role='treeitem', expandable folders missing aria-expanded. No aria-level on nested items. Arrow keys don't navigate the tree. W3C APG Tree View pattern requires tree, treeitem, aria-expanded on branch nodes, aria-level or DOM nesting, and full arrow key navigation.<ul role="list"> — wrong role, no tree behaviorrole="tree", items with role="treeitem", folders with aria-expanded, level tracking via aria-level or DOM nesting, Arrow Right to expand, Arrow Left to collapse/go to parent, Arrow Up/Down to navigate — from W3C Tree View referencearia-expanded becomes true, presses Arrow Down, verifies focus moves to first child treeitemrole='toolbar' and aria-label. Individual buttons missing aria-pressed for toggle state (Bold on/off). Arrow keys do not navigate between buttons — every button is a separate Tab stop. W3C APG Toolbar pattern requires role='toolbar', aria-label, and Left/Right Arrow key navigation with roving tabindex.aria-label to each button icon — labels present but 15 Tab stops for 15 buttons, toggle state unknownrole="toolbar", aria-label="Formatting", Arrow keys navigate between buttons (single Tab stop for the group), toggle buttons with aria-pressed (Bold/Italic/Underline) — from W3C Toolbar referencearia-pressed togglesaria-labelledby" — SC 4.1.2role='dialog' but should use role='alertdialog' — this is an urgent action requiring user response. Missing aria-describedby pointing to the warning message. W3C APG Alert Dialog pattern requires alertdialog role, aria-modal, aria-labelledby for title, aria-describedby for the warning text, and focus on the least destructive action.<div role="dialog" aria-labelledby="title"> — wrong role for urgent message, no descriptionrole="alertdialog", aria-modal="true", aria-labelledby pointing to "Delete Item?" heading, aria-describedby pointing to "This action cannot be undone" message, initial focus on "Cancel" (least destructive) — from W3C Alert Dialog referencerole="alertdialog", verifies aria-describedby content is announced, verifies initial focus is on Cancel (not Delete)role='meter', aria-valuemin, aria-valuemax, aria-valuenow, and aria-label. Screen reader users cannot determine how much storage is used or the total capacity. W3C APG Meter pattern requires all value properties and a descriptive label.<div aria-label="Storage usage"> — labels the container, no value informationrole="meter", aria-valuemin="0", aria-valuemax="5", aria-valuenow="3.2", aria-valuetext="3.2 GB of 5 GB used (64%)", aria-label="Storage usage" — from W3C Meter referencearia-valuenow is present and within aria-valuemin/aria-valuemax range, verifies aria-valuetext provides human-readable descriptionrole='feed', articles missing role='article' with aria-setsize and aria-posinset. No aria-busy during loading. Screen reader users cannot navigate between posts (Page Down to next article) and don't know how many posts are loaded. W3C APG Feed pattern requires feed, article, set size tracking, and busy state during load.role="feed", aria-label, articles with role="article", aria-posinset (position), aria-setsize (total or -1 for unknown), aria-busy="true" during loading — from W3C Feed referencearia-busy during load, verifies new articles get correct aria-posinset, verifies aria-setsize updatesaria-colcount/aria-rowcount for virtual scrolling. Cells missing aria-colindex/aria-rowindex. Arrow keys don't navigate between cells — every cell is a separate Tab stop. W3C APG Grid pattern requires grid, row, gridcell roles, index properties, and full four-directional arrow key navigation.<th> headers — fixes header association but grid is still a table with 200+ Tab stopsrole="grid", rows with role="row", cells with role="gridcell", column headers with role="columnheader", aria-colcount/aria-rowcount for total dimensions, aria-colindex/aria-rowindex on cells, single Tab stop for the entire grid, Arrow keys navigate between cells — from W3C Grid reference<nav> elements but only 1 has aria-label — screen reader users see '3 navigation landmarks' but can't distinguish them (main nav vs footer nav vs sidebar nav). W3C APG Landmarks pattern requires unique aria-label on repeated landmark roles so users can distinguish between them.role="navigation" — already has it via <nav>, but duplicates are still indistinguishablearia-label: <nav aria-label="Main">, <nav aria-label="Footer">, <nav aria-label="Categories">. Same for repeated <aside>, <section>, <form> elements — from W3C Landmarks referencearia-label, reports which landmarks are indistinguishable