[{"data":1,"prerenderedAt":984},["ShallowReactive",2],{"site-header-nav":3,"page-\u002Fcore-accessibility-principles-for-modern-frameworks\u002Fsemantic-html-vs-aria-in-component-trees\u002F":156,"content-navigation":910},[4,66,70],{"title":5,"path":6,"stem":7,"children":8},"Core Accessibility Principles For Modern Frameworks","\u002Fcore-accessibility-principles-for-modern-frameworks","core-accessibility-principles-for-modern-frameworks",[9,12,18,24,36,48,60],{"title":10,"path":6,"stem":11},"Core Accessibility Principles for Modern Frameworks","core-accessibility-principles-for-modern-frameworks\u002Findex",{"title":13,"path":14,"stem":15,"children":16},"Accessible Color Contrast & Theming","\u002Fcore-accessibility-principles-for-modern-frameworks\u002Faccessible-color-contrast-theming","core-accessibility-principles-for-modern-frameworks\u002Faccessible-color-contrast-theming\u002Findex",[17],{"title":13,"path":14,"stem":15},{"title":19,"path":20,"stem":21,"children":22},"Accessible Form Validation & Error States in Modern Frameworks","\u002Fcore-accessibility-principles-for-modern-frameworks\u002Faccessible-form-validation-error-states","core-accessibility-principles-for-modern-frameworks\u002Faccessible-form-validation-error-states\u002Findex",[23],{"title":19,"path":20,"stem":21},{"title":25,"path":26,"stem":27,"children":28},"Focus Management Strategies for SPAs","\u002Fcore-accessibility-principles-for-modern-frameworks\u002Ffocus-management-strategies-for-spas","core-accessibility-principles-for-modern-frameworks\u002Ffocus-management-strategies-for-spas\u002Findex",[29,30],{"title":25,"path":26,"stem":27},{"title":31,"path":32,"stem":33,"children":34},"Handling Focus Restoration After Dynamic Route Changes","\u002Fcore-accessibility-principles-for-modern-frameworks\u002Ffocus-management-strategies-for-spas\u002Fhandling-focus-restoration-after-dynamic-route-changes","core-accessibility-principles-for-modern-frameworks\u002Ffocus-management-strategies-for-spas\u002Fhandling-focus-restoration-after-dynamic-route-changes\u002Findex",[35],{"title":31,"path":32,"stem":33},{"title":37,"path":38,"stem":39,"children":40},"Keyboard Navigation Patterns for Modals","\u002Fcore-accessibility-principles-for-modern-frameworks\u002Fkeyboard-navigation-patterns-for-modals","core-accessibility-principles-for-modern-frameworks\u002Fkeyboard-navigation-patterns-for-modals\u002Findex",[41,42],{"title":37,"path":38,"stem":39},{"title":43,"path":44,"stem":45,"children":46},"Building Accessible Dropdowns Without External UI Kits","\u002Fcore-accessibility-principles-for-modern-frameworks\u002Fkeyboard-navigation-patterns-for-modals\u002Fbuilding-accessible-dropdowns-without-external-ui-kits","core-accessibility-principles-for-modern-frameworks\u002Fkeyboard-navigation-patterns-for-modals\u002Fbuilding-accessible-dropdowns-without-external-ui-kits\u002Findex",[47],{"title":43,"path":44,"stem":45},{"title":49,"path":50,"stem":51,"children":52},"Screen Reader Compatibility Testing for Modern Frameworks","\u002Fcore-accessibility-principles-for-modern-frameworks\u002Fscreen-reader-compatibility-testing","core-accessibility-principles-for-modern-frameworks\u002Fscreen-reader-compatibility-testing\u002Findex",[53,54],{"title":49,"path":50,"stem":51},{"title":55,"path":56,"stem":57,"children":58},"Testing ARIA Live Regions with Jest and Testing Library","\u002Fcore-accessibility-principles-for-modern-frameworks\u002Fscreen-reader-compatibility-testing\u002Ftesting-aria-live-regions-with-jest-and-testing-library","core-accessibility-principles-for-modern-frameworks\u002Fscreen-reader-compatibility-testing\u002Ftesting-aria-live-regions-with-jest-and-testing-library\u002Findex",[59],{"title":55,"path":56,"stem":57},{"title":61,"path":62,"stem":63,"children":64},"Semantic HTML vs ARIA in Component Trees","\u002Fcore-accessibility-principles-for-modern-frameworks\u002Fsemantic-html-vs-aria-in-component-trees","core-accessibility-principles-for-modern-frameworks\u002Fsemantic-html-vs-aria-in-component-trees\u002Findex",[65],{"title":61,"path":62,"stem":63},{"title":67,"path":68,"stem":69},"Modern Framework Accessibility","\u002F","index",{"title":71,"path":72,"stem":73,"children":74},"React Nextjs Accessibility Patterns","\u002Freact-nextjs-accessibility-patterns","react-nextjs-accessibility-patterns",[75,78,90,102,108,126,144],{"title":76,"path":72,"stem":77},"React & Next.js Accessibility Patterns","react-nextjs-accessibility-patterns\u002Findex",{"title":79,"path":80,"stem":81,"children":82},"Accessible Component Libraries in React","\u002Freact-nextjs-accessibility-patterns\u002Faccessible-component-libraries-in-react","react-nextjs-accessibility-patterns\u002Faccessible-component-libraries-in-react\u002Findex",[83,84],{"title":79,"path":80,"stem":81},{"title":85,"path":86,"stem":87,"children":88},"Building Accessible Tabs in React Without Radix UI","\u002Freact-nextjs-accessibility-patterns\u002Faccessible-component-libraries-in-react\u002Fbuilding-accessible-tabs-in-react-without-radix-ui","react-nextjs-accessibility-patterns\u002Faccessible-component-libraries-in-react\u002Fbuilding-accessible-tabs-in-react-without-radix-ui\u002Findex",[89],{"title":85,"path":86,"stem":87},{"title":91,"path":92,"stem":93,"children":94},"Dynamic Content & State Announcements in React & Next.js","\u002Freact-nextjs-accessibility-patterns\u002Fdynamic-content-state-announcements","react-nextjs-accessibility-patterns\u002Fdynamic-content-state-announcements\u002Findex",[95,96],{"title":91,"path":92,"stem":93},{"title":97,"path":98,"stem":99,"children":100},"Implementing React Context for Global Accessibility Preferences","\u002Freact-nextjs-accessibility-patterns\u002Fdynamic-content-state-announcements\u002Freact-context-for-global-accessibility-preferences","react-nextjs-accessibility-patterns\u002Fdynamic-content-state-announcements\u002Freact-context-for-global-accessibility-preferences\u002Findex",[101],{"title":97,"path":98,"stem":99},{"title":103,"path":104,"stem":105,"children":106},"Form Handling with React Hook Form & Accessibility","\u002Freact-nextjs-accessibility-patterns\u002Fform-handling-with-react-hook-form-a11y","react-nextjs-accessibility-patterns\u002Fform-handling-with-react-hook-form-a11y\u002Findex",[107],{"title":103,"path":104,"stem":105},{"title":109,"path":110,"stem":111,"children":112},"Next.js App Router & A11y: Implementation Guide for Modern Frameworks","\u002Freact-nextjs-accessibility-patterns\u002Fnextjs-app-router-a11y","react-nextjs-accessibility-patterns\u002Fnextjs-app-router-a11y\u002Findex",[113,114,120],{"title":109,"path":110,"stem":111},{"title":115,"path":116,"stem":117,"children":118},"Implementing Skip Links in Next.js App Router: A Step-by-Step Guide","\u002Freact-nextjs-accessibility-patterns\u002Fnextjs-app-router-a11y\u002Fimplementing-skip-links-in-nextjs-app-router","react-nextjs-accessibility-patterns\u002Fnextjs-app-router-a11y\u002Fimplementing-skip-links-in-nextjs-app-router\u002Findex",[119],{"title":115,"path":116,"stem":117},{"title":121,"path":122,"stem":123,"children":124},"Next.js Dynamic Imports and Keyboard Navigation: A Complete A11y Implementation Guide","\u002Freact-nextjs-accessibility-patterns\u002Fnextjs-app-router-a11y\u002Fnextjs-dynamic-imports-and-keyboard-navigation","react-nextjs-accessibility-patterns\u002Fnextjs-app-router-a11y\u002Fnextjs-dynamic-imports-and-keyboard-navigation\u002Findex",[125],{"title":121,"path":122,"stem":123},{"title":127,"path":128,"stem":129,"children":130},"React Hooks for Accessibility: Implementation Patterns & State Management","\u002Freact-nextjs-accessibility-patterns\u002Freact-hooks-for-accessibility","react-nextjs-accessibility-patterns\u002Freact-hooks-for-accessibility\u002Findex",[131,132,138],{"title":127,"path":128,"stem":129},{"title":133,"path":134,"stem":135,"children":136},"Fixing Focus Trap Issues in React Portals","\u002Freact-nextjs-accessibility-patterns\u002Freact-hooks-for-accessibility\u002Ffixing-focus-trap-issues-in-react-portals","react-nextjs-accessibility-patterns\u002Freact-hooks-for-accessibility\u002Ffixing-focus-trap-issues-in-react-portals\u002Findex",[137],{"title":133,"path":134,"stem":135},{"title":139,"path":140,"stem":141,"children":142},"Making React useEffect Accessible for Screen Readers","\u002Freact-nextjs-accessibility-patterns\u002Freact-hooks-for-accessibility\u002Fmaking-react-useeffect-accessible-for-screen-readers","react-nextjs-accessibility-patterns\u002Freact-hooks-for-accessibility\u002Fmaking-react-useeffect-accessible-for-screen-readers\u002Findex",[143],{"title":139,"path":140,"stem":141},{"title":145,"path":146,"stem":147,"children":148},"Server Components & Client-Side Interactivity","\u002Freact-nextjs-accessibility-patterns\u002Fserver-components-client-side-interactivity","react-nextjs-accessibility-patterns\u002Fserver-components-client-side-interactivity\u002Findex",[149,150],{"title":145,"path":146,"stem":147},{"title":151,"path":152,"stem":153,"children":154},"Handling Accessible Modals in Next.js 14 Server Components","\u002Freact-nextjs-accessibility-patterns\u002Fserver-components-client-side-interactivity\u002Fhandling-accessible-modals-in-nextjs-14-server-components","react-nextjs-accessibility-patterns\u002Fserver-components-client-side-interactivity\u002Fhandling-accessible-modals-in-nextjs-14-server-components\u002Findex",[155],{"title":151,"path":152,"stem":153},{"id":157,"title":61,"body":158,"date":903,"description":904,"extension":905,"image":903,"meta":906,"modifiedAt":903,"navigation":334,"noindex":907,"path":62,"publishedAt":903,"seo":908,"stem":63,"updatedAt":903,"__hash__":909},"content\u002Fcore-accessibility-principles-for-modern-frameworks\u002Fsemantic-html-vs-aria-in-component-trees\u002Findex.md",{"type":159,"value":160,"toc":894},"minimark",[161,165,187,192,235,238,482,496,500,510,532,665,675,679,686,693,759,770,774,785,799,820,824,859,863,869,875,890],[162,163,61],"h1",{"id":164},"semantic-html-vs-aria-in-component-trees",[166,167,168,169,176,177,182,183,186],"p",{},"In modern frontend architectures, the tension between native semantic markup and programmatic ARIA attributes dictates baseline accessibility compliance. This guide addresses ",[170,171,175],"a",{"href":172,"rel":173},"https:\u002F\u002Fwww.w3.org\u002FWAI\u002FWCAG21\u002FUnderstanding\u002Finfo-and-relationships.html",[174],"nofollow","WCAG 1.3.1 Info and Relationships"," and ",[170,178,181],{"href":179,"rel":180},"https:\u002F\u002Fwww.w3.org\u002FWAI\u002FWCAG21\u002FUnderstanding\u002Fname-role-value.html",[174],"4.1.2 Name, Role, Value",", establishing why native elements must remain the foundation of any accessible component tree. As outlined in our foundational guide on ",[170,184,10],{"href":185},"\u002Fcore-accessibility-principles-for-modern-frameworks\u002F",", the first rule of ARIA is unequivocal: use native HTML elements whenever possible. Framework virtual DOMs, hydration cycles, and reactive state management introduce unique failure modes that can silently strip or duplicate accessibility semantics if not explicitly managed.",[188,189,191],"h2",{"id":190},"the-first-rule-of-aria-in-framework-rendering","The First Rule of ARIA in Framework Rendering",[166,193,194,195,199,200,203,204,207,208,211,212,215,216,176,219,222,223,226,227,230,231,234],{},"Framework rendering engines reconcile the virtual DOM against the actual DOM, which can inadvertently strip or duplicate ARIA states if not explicitly bound. Native elements like ",[196,197,198],"code",{},"\u003Cbutton>",", ",[196,201,202],{},"\u003Cnav>",", and ",[196,205,206],{},"\u003Carticle>"," ship with implicit roles, keyboard event listeners, and focus management that ARIA cannot replicate without extensive JavaScript overhead. Relying on ",[196,209,210],{},"\u003Cdiv role=\"button\">"," bypasses these native contracts, forcing developers to manually implement ",[196,213,214],{},"onKeyDown"," handlers for ",[196,217,218],{},"Enter",[196,220,221],{},"Space",", manage ",[196,224,225],{},"tabindex",", and handle ",[196,228,229],{},"aria-pressed"," or ",[196,232,233],{},"aria-disabled"," states reactively.",[166,236,237],{},"During hydration, server-rendered markup is patched with client-side JavaScript. If ARIA attributes are conditionally applied or computed post-mount, screen readers may announce stale or missing roles until reconciliation completes. Always bind accessibility states to the initial render payload to prevent hydration mismatches.",[239,240,245],"pre",{"className":241,"code":242,"language":243,"meta":244,"style":244},"language-jsx shiki shiki-themes github-light github-dark","\u002F\u002F React: Correct - Leverages native semantics & built-in keyboard handling\n\u003Cbutton\n onClick={handleSubmit}\n aria-disabled={isSubmitting}\n disabled={isSubmitting} \u002F\u002F Native disabled prevents focus\u002Fclicks\n>\n Submit\n\u003C\u002Fbutton>\n\n\u002F\u002F React: Incorrect - ARIA override requires manual keyboard & focus management\n\u003Cdiv\n role=\"button\"\n tabIndex={0}\n onClick={handleSubmit}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') handleSubmit();\n }}\n aria-disabled={isSubmitting}\n>\n Submit\n\u003C\u002Fdiv>\n","jsx","",[196,246,247,256,267,281,292,306,312,318,329,336,342,350,362,380,389,413,447,453,462,467,472],{"__ignoreMap":244},[248,249,252],"span",{"class":250,"line":251},"line",1,[248,253,255],{"class":254},"sJ8bj","\u002F\u002F React: Correct - Leverages native semantics & built-in keyboard handling\n",[248,257,259,263],{"class":250,"line":258},2,[248,260,262],{"class":261},"sVt8B","\u003C",[248,264,266],{"class":265},"s9eBZ","button\n",[248,268,270,274,278],{"class":250,"line":269},3,[248,271,273],{"class":272},"sScJk"," onClick",[248,275,277],{"class":276},"szBVR","=",[248,279,280],{"class":261},"{handleSubmit}\n",[248,282,284,287,289],{"class":250,"line":283},4,[248,285,286],{"class":272}," aria-disabled",[248,288,277],{"class":276},[248,290,291],{"class":261},"{isSubmitting}\n",[248,293,295,298,300,303],{"class":250,"line":294},5,[248,296,297],{"class":272}," disabled",[248,299,277],{"class":276},[248,301,302],{"class":261},"{isSubmitting} ",[248,304,305],{"class":254},"\u002F\u002F Native disabled prevents focus\u002Fclicks\n",[248,307,309],{"class":250,"line":308},6,[248,310,311],{"class":261},">\n",[248,313,315],{"class":250,"line":314},7,[248,316,317],{"class":261}," Submit\n",[248,319,321,324,327],{"class":250,"line":320},8,[248,322,323],{"class":261},"\u003C\u002F",[248,325,326],{"class":265},"button",[248,328,311],{"class":261},[248,330,332],{"class":250,"line":331},9,[248,333,335],{"emptyLinePlaceholder":334},true,"\n",[248,337,339],{"class":250,"line":338},10,[248,340,341],{"class":254},"\u002F\u002F React: Incorrect - ARIA override requires manual keyboard & focus management\n",[248,343,345,347],{"class":250,"line":344},11,[248,346,262],{"class":261},[248,348,349],{"class":265},"div\n",[248,351,353,356,358],{"class":250,"line":352},12,[248,354,355],{"class":272}," role",[248,357,277],{"class":276},[248,359,361],{"class":360},"sZZnC","\"button\"\n",[248,363,365,368,370,373,377],{"class":250,"line":364},13,[248,366,367],{"class":272}," tabIndex",[248,369,277],{"class":276},[248,371,372],{"class":261},"{",[248,374,376],{"class":375},"sj4cs","0",[248,378,379],{"class":261},"}\n",[248,381,383,385,387],{"class":250,"line":382},14,[248,384,273],{"class":272},[248,386,277],{"class":276},[248,388,280],{"class":261},[248,390,392,395,397,400,404,407,410],{"class":250,"line":391},15,[248,393,394],{"class":272}," onKeyDown",[248,396,277],{"class":276},[248,398,399],{"class":261},"{(",[248,401,403],{"class":402},"s4XuR","e",[248,405,406],{"class":261},") ",[248,408,409],{"class":276},"=>",[248,411,412],{"class":261}," {\n",[248,414,416,419,422,425,428,431,434,436,439,441,444],{"class":250,"line":415},16,[248,417,418],{"class":276}," if",[248,420,421],{"class":261}," (e.key ",[248,423,424],{"class":276},"===",[248,426,427],{"class":360}," 'Enter'",[248,429,430],{"class":276}," ||",[248,432,433],{"class":261}," e.key ",[248,435,424],{"class":276},[248,437,438],{"class":360}," ' '",[248,440,406],{"class":261},[248,442,443],{"class":272},"handleSubmit",[248,445,446],{"class":261},"();\n",[248,448,450],{"class":250,"line":449},17,[248,451,452],{"class":261}," }}\n",[248,454,456,458,460],{"class":250,"line":455},18,[248,457,286],{"class":272},[248,459,277],{"class":276},[248,461,291],{"class":261},[248,463,465],{"class":250,"line":464},19,[248,466,311],{"class":261},[248,468,470],{"class":250,"line":469},20,[248,471,317],{"class":261},[248,473,475,477,480],{"class":250,"line":474},21,[248,476,323],{"class":261},[248,478,479],{"class":265},"div",[248,481,311],{"class":261},[483,484,485],"blockquote",{},[166,486,487,491,492,495],{},[488,489,490],"strong",{},"Testing Hook:"," Use browser DevTools to inspect the raw DOM output before React hydration completes. Verify that semantic elements are not replaced by framework-generated wrappers that strip implicit roles or delay ",[196,493,494],{},"aria-*"," attribute application.",[188,497,499],{"id":498},"component-composition-role-delegation","Component Composition & Role Delegation",[166,501,502,503,230,506,509],{},"Component composition in design systems frequently introduces deeply nested wrapper elements for styling, layout, or state isolation. Each wrapper risks introducing an implicit role that conflicts with the intended accessibility tree. To prevent role collisions, layout primitives should explicitly declare ",[196,504,505],{},"role=\"presentation\"",[196,507,508],{},"role=\"none\""," to signal assistive technologies that the element is purely structural.",[166,511,512,513,516,517,520,521,524,525,230,528,531],{},"When rendering via framework portals (e.g., React ",[196,514,515],{},"createPortal",", Vue ",[196,518,519],{},"\u003CTeleport>",", or Angular ",[196,522,523],{},"ng-template","), ensure the accessibility tree is not fragmented by moving interactive elements outside their logical DOM hierarchy. Portals detach nodes from the visual tree but leave them in the accessibility tree; if a modal or dropdown is teleported to the document root, its ",[196,526,527],{},"aria-owns",[196,529,530],{},"aria-controls"," relationships must be explicitly maintained to preserve logical reading order. For complex component trees, avoid prop-drilling accessibility flags; instead, leverage framework-native context APIs to propagate state without polluting component props.",[239,533,537],{"className":534,"code":535,"language":536,"meta":244,"style":244},"language-vue shiki shiki-themes github-light github-dark","\u003C!-- Vue: Role Delegation in Card Components -->\n\u003Ctemplate>\n \u003C!-- Wrapper explicitly stripped of semantic meaning -->\n \u003Cdiv class=\"card-wrapper\" role=\"presentation\">\n \u003Carticle class=\"card-content\" :aria-labelledby=\"titleId\">\n \u003Ch3 :id=\"titleId\">{{ title }}\u003C\u002Fh3>\n \u003Cslot \u002F>\n \u003C\u002Farticle>\n \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n","vue",[196,538,539,544,553,558,582,606,627,640,649,657],{"__ignoreMap":244},[248,540,541],{"class":250,"line":251},[248,542,543],{"class":254},"\u003C!-- Vue: Role Delegation in Card Components -->\n",[248,545,546,548,551],{"class":250,"line":258},[248,547,262],{"class":261},[248,549,550],{"class":265},"template",[248,552,311],{"class":261},[248,554,555],{"class":250,"line":269},[248,556,557],{"class":254}," \u003C!-- Wrapper explicitly stripped of semantic meaning -->\n",[248,559,560,563,565,568,570,573,575,577,580],{"class":250,"line":283},[248,561,562],{"class":261}," \u003C",[248,564,479],{"class":265},[248,566,567],{"class":272}," class",[248,569,277],{"class":261},[248,571,572],{"class":360},"\"card-wrapper\"",[248,574,355],{"class":272},[248,576,277],{"class":261},[248,578,579],{"class":360},"\"presentation\"",[248,581,311],{"class":261},[248,583,584,586,589,591,593,596,599,601,604],{"class":250,"line":294},[248,585,562],{"class":261},[248,587,588],{"class":265},"article",[248,590,567],{"class":272},[248,592,277],{"class":261},[248,594,595],{"class":360},"\"card-content\"",[248,597,598],{"class":272}," :aria-labelledby",[248,600,277],{"class":261},[248,602,603],{"class":360},"\"titleId\"",[248,605,311],{"class":261},[248,607,608,610,613,616,618,620,623,625],{"class":250,"line":308},[248,609,562],{"class":261},[248,611,612],{"class":265},"h3",[248,614,615],{"class":272}," :id",[248,617,277],{"class":261},[248,619,603],{"class":360},[248,621,622],{"class":261},">{{ title }}\u003C\u002F",[248,624,612],{"class":265},[248,626,311],{"class":261},[248,628,629,631,634,638],{"class":250,"line":314},[248,630,562],{"class":261},[248,632,633],{"class":265},"slot",[248,635,637],{"class":636},"s7hpK"," \u002F",[248,639,311],{"class":261},[248,641,642,645,647],{"class":250,"line":320},[248,643,644],{"class":261}," \u003C\u002F",[248,646,588],{"class":265},[248,648,311],{"class":261},[248,650,651,653,655],{"class":250,"line":331},[248,652,644],{"class":261},[248,654,479],{"class":265},[248,656,311],{"class":261},[248,658,659,661,663],{"class":250,"line":338},[248,660,323],{"class":261},[248,662,550],{"class":265},[248,664,311],{"class":261},[483,666,667],{},[166,668,669,671,672,674],{},[488,670,490],{}," Run the component through an accessibility tree inspector (e.g., Chrome DevTools Accessibility pane or axe DevTools). Ensure parent wrapper roles are correctly suppressed and that the computed role of the interactive element matches the expected semantic target. Verify portal-rendered elements maintain correct ",[196,673,527],{}," relationships.",[188,676,678],{"id":677},"state-synchronization-live-regions","State Synchronization & Live Regions",[166,680,681,682,685],{},"Dynamic interfaces require precise synchronization between framework reactivity and screen reader announcements. When state updates trigger UI changes, ",[196,683,684],{},"aria-live"," regions must be carefully managed to prevent announcement spam or silent failures. Frameworks that batch updates or debounce rapid state changes can inadvertently delay or drop live region notifications. Always map reactive state directly to ARIA attributes using computed properties or derived stores, and ensure conditional rendering does not destroy the live region DOM node, which would break the accessibility tree reference.",[166,687,688,689,692],{},"For seamless user flows during heavy DOM mutations, pair live regions with the strategies detailed in ",[170,690,25],{"href":691},"\u002Fcore-accessibility-principles-for-modern-frameworks\u002Ffocus-management-strategies-for-spas\u002F",". When state changes rapidly, implement a debounce or throttle mechanism before updating the live region payload to allow screen readers to process the announcement queue without interruption.",[239,694,698],{"className":695,"code":696,"language":697,"meta":244,"style":244},"language-svelte shiki shiki-themes github-light github-dark","\u003C!-- Svelte: Reactive Live Region Binding -->\n\u003Cscript>\n let statusMessage = $state('');\n \u002F\u002F Framework reactivity automatically syncs to DOM attributes\n\u003C\u002Fscript>\n\n\u003C!-- Live region persists in DOM regardless of conditional content -->\n\u003Cdiv aria-live=\"polite\" aria-atomic=\"true\">\n {#if statusMessage}\n \u003Cp>{statusMessage}\u003C\u002Fp>\n {\u002Fif}\n\u003C\u002Fdiv>\n","svelte",[196,699,700,705,710,715,720,725,729,734,739,744,749,754],{"__ignoreMap":244},[248,701,702],{"class":250,"line":251},[248,703,704],{},"\u003C!-- Svelte: Reactive Live Region Binding -->\n",[248,706,707],{"class":250,"line":258},[248,708,709],{},"\u003Cscript>\n",[248,711,712],{"class":250,"line":269},[248,713,714],{}," let statusMessage = $state('');\n",[248,716,717],{"class":250,"line":283},[248,718,719],{}," \u002F\u002F Framework reactivity automatically syncs to DOM attributes\n",[248,721,722],{"class":250,"line":294},[248,723,724],{},"\u003C\u002Fscript>\n",[248,726,727],{"class":250,"line":308},[248,728,335],{"emptyLinePlaceholder":334},[248,730,731],{"class":250,"line":314},[248,732,733],{},"\u003C!-- Live region persists in DOM regardless of conditional content -->\n",[248,735,736],{"class":250,"line":320},[248,737,738],{},"\u003Cdiv aria-live=\"polite\" aria-atomic=\"true\">\n",[248,740,741],{"class":250,"line":331},[248,742,743],{}," {#if statusMessage}\n",[248,745,746],{"class":250,"line":338},[248,747,748],{}," \u003Cp>{statusMessage}\u003C\u002Fp>\n",[248,750,751],{"class":250,"line":344},[248,752,753],{}," {\u002Fif}\n",[248,755,756],{"class":250,"line":352},[248,757,758],{},"\u003C\u002Fdiv>\n",[483,760,761],{},[166,762,763,765,766,769],{},[488,764,490],{}," Test with VoiceOver (macOS\u002FiOS) and NVDA (Windows) during rapid state transitions. Verify announcement timing, ensure ",[196,767,768],{},"aria-atomic=\"true\""," reads the complete updated string, and confirm that conditional rendering does not detach the live region from the DOM.",[188,771,773],{"id":772},"visual-semantics-styling-boundaries","Visual Semantics & Styling Boundaries",[166,775,776,777,780,781,784],{},"Structural semantics and visual presentation must remain decoupled. While visual perception is governed by contrast and typography standards (see ",[170,778,13],{"href":779},"\u002Fcore-accessibility-principles-for-modern-frameworks\u002Faccessible-color-contrast-theming\u002F","), programmatic meaning relies entirely on the accessibility tree. Aggressive CSS resets, ",[196,782,783],{},"appearance: none",", or utility-first styling often strip native element behaviors, including default focus rings and implicit roles. When overriding native styles, you must explicitly restore keyboard focus indicators and ensure ARIA attributes reflect the actual component state.",[166,786,787,788,791,792,794,795,798],{},"Additionally, never use ",[196,789,790],{},"aria-label"," to replace visible, accessible text. ",[196,793,790],{}," should only supplement or clarify existing content. If an element requires a visual label, render it in the DOM and use ",[196,796,797],{},"aria-labelledby"," to establish the relationship. This prevents discrepancies between what sighted users see and what assistive technologies announce.",[483,800,801],{},[166,802,803,805,806,230,809,811,812,815,816,819],{},[488,804,490],{}," Validate that CSS-in-JS or utility frameworks do not inject inline styles that override ",[196,807,808],{},"role",[196,810,494],{}," attributes in the computed accessibility tree. Verify that ",[196,813,814],{},"@media (prefers-reduced-motion)"," is paired with ARIA announcements for motion-sensitive users, and that ",[196,817,818],{},"outline: none"," is never applied without a visible focus fallback.",[612,821,823],{"id":822},"common-pitfalls-in-framework-component-trees","Common Pitfalls in Framework Component Trees",[825,826,827,837,843,849,852],"ul",{},[828,829,830,831,833,834,836],"li",{},"Overusing ",[196,832,210],{}," instead of native ",[196,835,198],{}," elements, bypassing implicit keyboard contracts.",[828,838,839,840,842],{},"Duplicating ",[196,841,797],{}," across nested interactive elements, causing screen readers to announce conflicting labels.",[828,844,845,846,848],{},"Ignoring framework-specific event normalization (e.g., missing ",[196,847,214],{}," handlers for custom roles in React\u002FVue).",[828,850,851],{},"Hardcoding ARIA states in static markup instead of binding them to reactive component data.",[828,853,854,855,858],{},"Applying ",[196,856,857],{},"aria-hidden=\"true\""," to focusable elements, trapping keyboard navigation in hidden DOM nodes.",[612,860,862],{"id":861},"frequently-asked-questions","Frequently Asked Questions",[166,864,865,868],{},[488,866,867],{},"When should I use ARIA instead of semantic HTML in a component tree?","\nOnly when native HTML elements cannot represent the required UI pattern or state. Examples include custom select dropdowns, complex data grids, or tab panels where native equivalents lack sufficient cross-browser support or styling flexibility.",[166,870,871,874],{},[488,872,873],{},"How do framework virtual DOMs affect ARIA state synchronization?","\nVirtual DOM diffing can cause ARIA attributes to be removed, duplicated, or applied out of order if not explicitly bound to reactive state. Always use framework-native binding syntax to ensure the DOM reflects the current accessibility state.",[166,876,877,880,881,199,884,886,887,889],{},[488,878,879],{},"Can CSS frameworks break semantic accessibility?","\nYes. Utility-first CSS or CSS-in-JS libraries often apply ",[196,882,883],{},"display: block",[196,885,783],{},", or ",[196,888,818],{}," to native elements, stripping built-in accessibility behaviors. Always pair visual resets with explicit ARIA roles and keyboard event handlers when necessary.",[891,892,893],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s7hpK, html code.shiki .s7hpK{--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":244,"searchDepth":258,"depth":258,"links":895},[896,897,898,899],{"id":190,"depth":258,"text":191},{"id":498,"depth":258,"text":499},{"id":677,"depth":258,"text":678},{"id":772,"depth":258,"text":773,"children":900},[901,902],{"id":822,"depth":269,"text":823},{"id":861,"depth":269,"text":862},null,"Learn when to rely on semantic HTML versus ARIA in component trees to preserve accessibility APIs, reduce bugs, and ship maintainable UI.","md",{},false,{"title":61,"description":904},"iTJKxop1N6CtDKOporXqcuL2XBLL2tjH5yfRiGbs5g8",[911,941,942],{"title":5,"path":6,"stem":7,"children":912},[913,914,917,920,926,932,938],{"title":10,"path":6,"stem":11},{"title":13,"path":14,"stem":15,"children":915},[916],{"title":13,"path":14,"stem":15},{"title":19,"path":20,"stem":21,"children":918},[919],{"title":19,"path":20,"stem":21},{"title":25,"path":26,"stem":27,"children":921},[922,923],{"title":25,"path":26,"stem":27},{"title":31,"path":32,"stem":33,"children":924},[925],{"title":31,"path":32,"stem":33},{"title":37,"path":38,"stem":39,"children":927},[928,929],{"title":37,"path":38,"stem":39},{"title":43,"path":44,"stem":45,"children":930},[931],{"title":43,"path":44,"stem":45},{"title":49,"path":50,"stem":51,"children":933},[934,935],{"title":49,"path":50,"stem":51},{"title":55,"path":56,"stem":57,"children":936},[937],{"title":55,"path":56,"stem":57},{"title":61,"path":62,"stem":63,"children":939},[940],{"title":61,"path":62,"stem":63},{"title":67,"path":68,"stem":69},{"title":71,"path":72,"stem":73,"children":943},[944,945,951,957,960,969,978],{"title":76,"path":72,"stem":77},{"title":79,"path":80,"stem":81,"children":946},[947,948],{"title":79,"path":80,"stem":81},{"title":85,"path":86,"stem":87,"children":949},[950],{"title":85,"path":86,"stem":87},{"title":91,"path":92,"stem":93,"children":952},[953,954],{"title":91,"path":92,"stem":93},{"title":97,"path":98,"stem":99,"children":955},[956],{"title":97,"path":98,"stem":99},{"title":103,"path":104,"stem":105,"children":958},[959],{"title":103,"path":104,"stem":105},{"title":109,"path":110,"stem":111,"children":961},[962,963,966],{"title":109,"path":110,"stem":111},{"title":115,"path":116,"stem":117,"children":964},[965],{"title":115,"path":116,"stem":117},{"title":121,"path":122,"stem":123,"children":967},[968],{"title":121,"path":122,"stem":123},{"title":127,"path":128,"stem":129,"children":970},[971,972,975],{"title":127,"path":128,"stem":129},{"title":133,"path":134,"stem":135,"children":973},[974],{"title":133,"path":134,"stem":135},{"title":139,"path":140,"stem":141,"children":976},[977],{"title":139,"path":140,"stem":141},{"title":145,"path":146,"stem":147,"children":979},[980,981],{"title":145,"path":146,"stem":147},{"title":151,"path":152,"stem":153,"children":982},[983],{"title":151,"path":152,"stem":153},1778094796116]