{"id":268,"date":"2025-06-16T13:00:00","date_gmt":"2025-06-16T13:00:00","guid":{"rendered":"https:\/\/niceexcept.com\/?p=268"},"modified":"2025-06-23T09:49:53","modified_gmt":"2025-06-23T09:49:53","slug":"what-i-wish-someone-told-me-when-i-was-getting-into-aria","status":"publish","type":"post","link":"https:\/\/niceexcept.com\/index.php\/2025\/06\/16\/what-i-wish-someone-told-me-when-i-was-getting-into-aria\/","title":{"rendered":"What I Wish Someone Told Me When I Was Getting Into ARIA"},"content":{"rendered":"

What I Wish Someone Told Me When I Was Getting Into ARIA<\/title><\/p>\n<article>\n<header>\n<h1>What I Wish Someone Told Me When I Was Getting Into ARIA<\/h1>\n<address>Eric Bailey<\/address>\n<p> 2025-06-16T13:00:00+00:00<br \/>\n 2025-06-23T09:33:10+00:00<br \/>\n <\/header>\n<p>If you haven\u2019t encountered ARIA before, great! It\u2019s a chance to learn something new and exciting. If you have heard of ARIA before, this might help you better understand it or maybe even teach you something new!<\/p>\n<p>These are all things I wish someone had told me when I was getting started on my web accessibility journey. This post will:<\/p>\n<ul>\n<li>Provide a mindset for <strong>how to approach ARIA<\/strong> as a concept,<\/li>\n<li><strong>Debunk some common misconceptions<\/strong>, and<\/li>\n<li><strong>Provide some guiding thoughts<\/strong> to help you better understand and work with it.<\/li>\n<\/ul>\n<p>It is my hope that in doing so, this post will help make an oft-overlooked yet vital corner of web design and development easier to approach.<\/p>\n<h2 id=\"what-this-post-is-not\">What This Post Is Not<\/h2>\n<p>This <strong>is not<\/strong> a recipe book for how to use ARIA to build accessible websites and web apps. It is also not a guide for how to remediate an inaccessible experience. <strong>A lot of accessibility work is highly contextual<\/strong>. I do not know the specific needs of your project or organization, so trying to give advice here could easily do more harm than good.<\/p>\n<p>Instead, think of this post as a \u201cknow before you go\u201d guide. I\u2019m hoping to give you a good headspace to approach ARIA, as well as highlight things to watch out for when you undertake your journey. So, with that out of the way, let\u2019s dive in!<\/p>\n<div data-audience=\"non-subscriber\" data-remove=\"true\" class=\"feature-panel-container\">\n<aside class=\"feature-panel\">\n<div class=\"feature-panel-left-col\">\n<div class=\"feature-panel-description\">\n<p>Meet <strong><a data-instant href=\"\/printed-books\/image-optimization\/\">Image Optimization<\/a><\/strong>, Addy Osmani\u2019s new practical guide to optimizing and delivering <strong>high-quality images<\/strong> on the web. Everything in one single <strong>528-pages<\/strong> book.<\/p>\n<p><a data-instant href=\"https:\/\/www.smashingmagazine.com\/printed-books\/image-optimization\/\" class=\"btn btn--green btn--large\">Jump to table of contents \u21ac<\/a><\/div>\n<\/div>\n<div class=\"feature-panel-right-col\"><a data-instant href=\"https:\/\/www.smashingmagazine.com\/printed-books\/image-optimization\/\" class=\"feature-panel-image-link\"><\/p>\n<div class=\"feature-panel-image\">\n<img decoding=\"async\" loading=\"lazy\" class=\"feature-panel-image-img lazyload\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"Feature Panel\" width=\"480\" height=\"697\" data-src=\"https:\/\/archive.smashing.media\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/87fd0cfa-692e-459c-b2f3-15209a1f6aa7\/image-optimization-shop-cover-opt.png\"><\/p>\n<\/div>\n<p><\/a>\n<\/div>\n<\/aside>\n<\/div>\n<h2 id=\"so-what-is-aria\">So, What Is ARIA?<\/h2>\n<blockquote><p>ARIA is what you turn to if there is not a native HTML element or attribute that is better suited for the job of communicating interactivity, purpose, and state.<\/p><\/blockquote>\n<p>Think of it like a spice that you sprinkle into your markup to enhance things.<\/p>\n<p>Adding ARIA to your HTML markup is a way of providing additional information to a website or web app for <a href=\"https:\/\/webaim.org\/articles\/visual\/blind#screenreaders\">screen readers<\/a> and <a href=\"https:\/\/webaim.org\/articles\/motor\/assistive#voicerecognition\">voice control software<\/a>.<\/p>\n<ul>\n<li><strong>Interactivity<\/strong> means the content can be activated or manipulated. An example of this is navigating to a link\u2019s destination.<\/li>\n<li><strong>Purpose<\/strong> means what something is used for. An example of this is a text input used to collect someone\u2019s name.<\/li>\n<li><strong>State<\/strong> means the current status content has been placed in and controlled by <a href=\"https:\/\/www.w3.org\/TR\/wai-aria\/#introstates\">states, properties, and values<\/a>. An example of this is an accordion panel \u200b\u200bthat can either be expanded or collapsed.<\/li>\n<\/ul>\n<p>Here is an illustration to help communicate what I mean by this:<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/1-interactivity-purpose-state.png\"><\/p>\n<p> <img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"244\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"Three panels, showing a pressed-in mute button, its underlying HTML code, and three labels for \u201cInteractivity,\u201d \u201cPurpose,\u201d and \u201cState.\u201d The button element uses the \u201cInteractivity\u201d label. A declaration of aria-pressed equals true uses the \u201cState\u201d label. And finally, the button\u2019s string value of \u201cMute\u201d uses the \u201cPurpose\u201d label. The button\u2019s HTML also uses a visually hidden CSS class to hide the string, then a decorative SVG icon to show a speaker mute icon.\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/1-interactivity-purpose-state.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n (<a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/1-interactivity-purpose-state.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<ul>\n<li>The presence of <a href=\"https:\/\/html.spec.whatwg.org\/multipage\/form-elements.html#the-button-element\">HTML\u2019s <code>button<\/code> element<\/a> will instruct assistive technology to report it as a button, letting someone know that it can be activated to perform a predefined action.<\/li>\n<li>The presence of the text string \u201cMute\u201d will be reported by assistive technology to clue the person into what the button is used for.<\/li>\n<li>The presence of <a href=\"https:\/\/w3c.github.io\/aria\/#aria-pressed\"><code>aria-pressed="true"<\/code><\/a> means that someone or something has previously activated the button, and it is now in a \u201cpushed in\u201d state that sustains its action.<\/li>\n<\/ul>\n<p>This overall pattern will let people who use assistive technology know:<\/p>\n<ol>\n<li>If something is interactive,<\/li>\n<li>What kind of interactive behavior it performs, and<\/li>\n<li>Its <a href=\"https:\/\/w3c.github.io\/aria\/#host_general_attrs\">current state<\/a>.<\/li>\n<\/ol>\n<h2 id=\"aria-s-history\">ARIA\u2019s History<\/h2>\n<p>ARIA has been around for a long time, with <a href=\"https:\/\/www.w3.org\/TR\/2006\/WD-aria-role-20060926\/\">the first version published on September 26th, 2006<\/a>.<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/2-browser.png\"><\/p>\n<p> <img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"592\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"The Roles for Accessible Rich Internet Applications (WAI-ARIA Roles) specification, loaded in a copy of Internet Explorer 7.\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/2-browser.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n (<a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/2-browser.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<blockquote class=\"pull-quote\">\n<p>\n <a class=\"pull-quote__link\" aria-label=\"Share on Twitter\" href=\"https:\/\/twitter.com\/share?text=%0aARIA%20was%20created%20to%20provide%20a%20bridge%20between%20the%20limitations%20of%20HTML%20and%20the%20need%20for%20making%20interactive%20experiences%20understandable%20by%20assistive%20technology.%0a&url=https:\/\/smashingmagazine.com%2f2025%2f06%2fwhat-i-wish-someone-told-me-aria%2f\"><\/p>\n<p>ARIA was created to provide a bridge between the limitations of HTML and the need for making interactive experiences understandable by assistive technology.<\/p>\n<p> <\/a>\n <\/p>\n<div class=\"pull-quote__quotation\">\n<div class=\"pull-quote__bg\">\n <span class=\"pull-quote__symbol\">\u201c<\/span><\/div>\n<\/p><\/div>\n<\/blockquote>\n<p>The latest version of ARIA is <a href=\"https:\/\/www.w3.org\/TR\/wai-aria-1.2\/\">version 1.2<\/a>, published on June 6th, 2023. Version 1.3 is slated to be released relatively soon, and you can read more about it in <a href=\"https:\/\/www.craigabbott.co.uk\/blog\/a-look-at-the-new-wai-aria-1-3-draft\/\">this excellent article by Craig Abbott<\/a>.<\/p>\n<p>You may also see it referred to as WAI-ARIA, where WAI stands for \u201cWeb Accessibility Initiative.\u201d The <a href=\"https:\/\/www.w3.org\/WAI\/\">WAI<\/a> is part of the <a href=\"https:\/\/www.w3.org\/\">W3C<\/a>, the organization that sets standards for the web. That said, most accessibility practitioners I know call it \u201cARIA\u201d in written and verbal communication and leave out the \u201cWAI-\u201d part.<\/p>\n<h2 id=\"the-spirit-of-aria-reflects-the-era-in-which-it-was-created\">The Spirit Of ARIA Reflects The Era In Which It Was Created<\/h2>\n<p>The reason for this is simple: The web was a lot less mature in the past than it is now. The most popular operating system in 2006 was <a href=\"https:\/\/en.wikipedia.org\/wiki\/Windows_XP\">Windows XP<\/a>. The iPhone didn\u2019t exist yet; it was released a year later.<\/p>\n<p>From a very high level, <strong>ARIA is a snapshot of the operating system interaction paradigms of this time period<\/strong>. This is because ARIA recreates them.<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/3-wxpdefaultdesk.png\"><\/p>\n<p> <img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"600\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"Windows XP, showing an open Start menu, the famous Rolling Green Hills desktop wallpaper, and a tooltip popping up from the taskbar advising us to take a tour of Windows XP. Screenshot.\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/3-wxpdefaultdesk.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n Image source: <a href=\"https:\/\/the-microsoft-windows-xp.fandom.com\/wiki\/Windows_XP\">The Microsoft Windows XP Wiki<\/a>. (<a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/3-wxpdefaultdesk.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<h3 id=\"the-mindset\">The Mindset<\/h3>\n<p>Smartphones with features like <a href=\"https:\/\/jquerymobile.com\/\">tappable<\/a>, swipeable, and draggable surfaces were far less commonplace. Single Page Application \u201cweb app\u201d experiences were also rare, with <a href=\"https:\/\/en.wikipedia.org\/wiki\/Ajax_(programming)\">Ajax<\/a>-based approaches being the most popular. This means that we have to <strong>build the experiences of today using the technology of 2006<\/strong>. In a way, <strong>this is a good thing<\/strong>. It forces us to take new and novel experiences and interrogate them.<\/p>\n<p>Interactions that cannot be broken down into smaller, more focused pieces that map to ARIA patterns are most likely inaccessible. This is because they won\u2019t be able to be operated by assistive technology or function on older or less popular devices.<\/p>\n<p>I may be biased, but I also think these sorts of novel interactions that can\u2019t translate also serve as a warning that a general audience will find them to be <strong>confusing and, therefore, unusable<\/strong>. This belief is important to consider given that the internet serves:<\/p>\n<ul>\n<li>An unknown number of people,<\/li>\n<li>Using an unknown number of devices,<\/li>\n<li>Each with an unknown amount of personal customizations,<\/li>\n<li>Who have their own unique needs and circumstances and<\/li>\n<li>Have unknown motivational factors.<\/li>\n<\/ul>\n<h3 id=\"interaction-expectations\">Interaction Expectations<\/h3>\n<p>Contemporary expectations for keyboard-based interaction for web content — checkboxes, radios, modals, accordions, and so on — are sourced from Windows XP and its predecessor operating systems. These interaction models are carried forward as muscle memory for older people who use assistive technology. Younger people who rely on assistive technology also learn these de facto standards, thus continuing the cycle.<\/p>\n<p>What does this mean for you? Someone using a keyboard to interact with your website or web app <strong>will most likely<\/strong> <a href=\"https:\/\/github.blog\/engineering\/user-experience\/considerations-for-making-a-tree-view-component-accessible\/#start-with-windows\"><strong>try these Windows OS-based keyboard shortcuts first<\/strong><\/a>. This means things like pressing:<\/p>\n<ul>\n<li><kbd>Enter<\/kbd> to navigate to a link\u2019s destination,<\/li>\n<li><kbd>Space<\/kbd> to activate buttons,<\/li>\n<li><kbd>Home<\/kbd> and <kbd>End<\/kbd> to jump to the start or end of a list of items, and so on.<\/li>\n<\/ul>\n<h3 id=\"it-s-also-a-living-document\">It\u2019s Also A Living Document<\/h3>\n<p>This is not to say that ARIA has stagnated. It is constantly being worked on with new additions, removals, and clarifications. Remember, it is now at version 1.2, with <a href=\"https:\/\/www.w3.org\/TR\/wai-aria-1.3\/\">version 1.3 arriving soon<\/a>.<\/p>\n<p>In parallel, HTML as a language also reflects this evolution. Elements were originally created to support a document-oriented web and have been gradually evolving to <a href=\"https:\/\/open-ui.org\/\">support more dynamic, app-like experiences<\/a>. The great bit here is that this is all <a href=\"https:\/\/github.com\/w3c\/aria\/\">conducted in the open<\/a> and is something you can contribute to if you feel motivated to do so.<\/p>\n<div class=\"partners__lead-place\"><\/div>\n<h2 id=\"aria-has-rules-for-using-it\">ARIA Has Rules For Using It<\/h2>\n<p>There are <a href=\"https:\/\/www.w3.org\/TR\/using-aria\/#NOTES\">five rules included in ARIA\u2019s documentation<\/a> to help steer how you approach it:<\/p>\n<ol>\n<li><a href=\"https:\/\/www.w3.org\/TR\/using-aria\/#firstrule\">Use a native element whenever possible.<\/a><br \/>\nAn example would be using an anchor element (<code><a><\/code>) for a link rather than a <code>div<\/code> with a click handler and a <code>role<\/code> of <code>link<\/code>.<\/li>\n<li><a href=\"https:\/\/www.w3.org\/TR\/using-aria\/#secondrule\">Don\u2019t adjust a native element\u2019s semantics if at all possible.<\/a><br \/>\nAn example would be trying to use a heading element as a tab rather than wrapping the heading in a semantically neutral <code>div<\/code>.<\/li>\n<li><a href=\"https:\/\/www.w3.org\/TR\/using-aria\/#3rdrule\">Anything interactive has to be keyboard operable.<\/a><br \/>\nIf you can\u2019t use it with a keyboard, it isn\u2019t accessible. Full stop.<\/li>\n<li><a href=\"https:\/\/www.w3.org\/TR\/using-aria\/#4thrule\">Do not use <code>role="presentation"<\/code> or <code>aria-hidden="true"<\/code> on a focusable element.<\/a><br \/>\nThis makes something intended to be interactive unable to be used by assistive technology.<\/li>\n<li><a href=\"https:\/\/www.w3.org\/TR\/using-aria\/#fifthrule\">Interactive elements must be named.<\/a><br \/>\nAn example of this is using the text string \u201cPrint\u201d for a <code>button<\/code> element.<\/li>\n<\/ol>\n<p>Observing these five rules will do a lot to help you out. The following is more context to provide even more support.<\/p>\n<h2 id=\"aria-has-a-taxonomy\">ARIA Has A Taxonomy<\/h2>\n<p>There is a structured grammar to ARIA, and it is centered around roles, as well as states and properties.<\/p>\n<h3 id=\"roles\">Roles<\/h3>\n<p>A <a href=\"https:\/\/www.w3.org\/TR\/wai-aria\/#dfn-role\">Role<\/a> is what assistive technology reads and then announces. A lot of people refer to this in shorthand as <em>semantics<\/em>. <strong>HTML elements have implied roles<\/strong>, which is why an anchor element will be announced as a link by screen readers with no additional work.<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/4-roles.png\"><\/p>\n<p> <img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"198\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"Three panels, showing how an implied role gets announced by assistive technology. The first panel shows an anchor element with a string value of \u201cFrench fries.\u201d The anchor element has the label \u201cImplied link role.\u201d The second panel shows a standard blue link with an underline. The link reads, \u201cFrench fries.\u201d The third panel shows a speech balloon coming from a laptop. The speech balloon\u2019s contents read, \u201cFrench fries, link.\u201d A label points to the speech balloon and reads, \u201cImplied link role.\u201d\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/4-roles.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n (<a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/4-roles.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<p><strong>Implied roles are almost always better to use<\/strong> if the use case calls for them. Recall <a href=\"https:\/\/www.w3.org\/TR\/using-aria\/#firstrule\">the first rule of ARIA<\/a> here. This is usually what digital accessibility practitioners refer to when they say, \u201cJust use semantic HTML.\u201d<\/p>\n<p>There are many reasons for favoring implied roles. The main consideration is better guarantees of support across an unknown number of operating systems, browsers, and assistive technology combinations.<\/p>\n<p><a href=\"https:\/\/www.w3.org\/TR\/wai-aria\/#roles_categorization\">Roles have categories<\/a>, each with its own purpose. The <a href=\"https:\/\/www.w3.org\/TR\/wai-aria\/#abstract_roles\">Abstract role category<\/a> is notable in that it is an organizing <a href=\"https:\/\/en.wiktionary.org\/wiki\/supercategory\">supercategory<\/a> <strong>not intended to be used by authors<\/strong>:<\/p>\n<blockquote><p>Abstract roles are used for the ontology. Authors <strong>MUST NOT<\/strong> use abstract roles in content.<\/p><\/blockquote>\n<pre><code class=\"language-html\"><!-- This won't work, don't do it -->\n<h2 role=\"sectionhead\">\n Anatomy and physiology\n<\/h2>\n\n<!-- Do this instead -->\n<section aria-labeledby=\"anatomy-and-physiology\">\n <h2 id=\"anatomy-and-physiology\">\n Anatomy and physiology\n <\/h2>\n<\/section>\n<\/code><\/pre>\n<p>Additionally, in the same way, you can only declare ARIA on certain things, <strong>you can only declare some ARIA as children of other ARIA declarations<\/strong>. An example of this is the <a href=\"https:\/\/www.w3.org\/TR\/wai-aria\/#listitem\">the <code>listitem<\/code> role<\/a>, which requires <a href=\"https:\/\/www.w3.org\/TR\/wai-aria\/#list\">a role of <code>list<\/code><\/a> to be present on its parent element.<\/p>\n<p>So, what\u2019s the best way to determine if a role requires a parent declaration? The answer is to <a href=\"https:\/\/www.w3.org\/TR\/wai-aria\/#role_definitions\">review the official definition<\/a>.<\/p>\n<h3 id=\"states-and-properties\">States And Properties<\/h3>\n<p><a href=\"https:\/\/www.w3.org\/TR\/wai-aria\/#introstates\">States and properties<\/a> are the other two main parts of ARIA\u2018s overall taxonomy.<\/p>\n<p>Implicit roles are provided by semantic HTML, and explicit roles are provided by ARIA. Both describe <strong>what an element is<\/strong>. States <strong>describe that element\u2019s characteristics in a way that assistive technology can understand<\/strong>. This is done via property declarations and their companion values.<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/5-role-and-state.png\"><\/p>\n<p> <img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"344\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"A code example that shows how roles, states, and properties all work together. The first panel shows HTML code for a button element, which uses an ARIA declaration of aria disabled equals true. The button element is labeled as \u201cRole\u201d. The ARIA declaration, including both the property and value portions, is labeled \u201cState.\u201d\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/5-role-and-state.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n (<a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/5-role-and-state.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<p>ARIA states can change quickly or slowly, both as a result of human interaction as well as application state. When the state is changed as a result of human interaction, it is considered an \u201cunmanaged state.\u201d Here, a developer must supply the underlying JavaScript logic to control the interaction.<\/p>\n<p>When the state changes as a result of the application (e.g., operating system, web browser, and so on), this is considered \u201c<a href=\"https:\/\/www.w3.org\/TR\/wai-aria\/#dfn-managed-state\">managed state<\/a>.\u201d Here, the application automatically supplies the underlying logic.<\/p>\n<h2 id=\"how-to-declare-aria\">How To Declare ARIA<\/h2>\n<p>Think of ARIA as an extension of <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTML\/Attributes\">HTML attributes<\/a>, a suite of name\/value pairs. Some values are predefined, while others are author-supplied:<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/6-predefined-author-defined.png\"><\/p>\n<p> <img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"432\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"Two HTML declarations. One is a div element with an ARIA declaration of aria-live equals polite declared on it. The second is a button element with an ARIA declaration of aria-label equals save. The aria-live declaration is labeled \u201cPredefined value,\u201d and the aria-label declaration is labeled \u201cAuthor-supplied value.\u201d\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/6-predefined-author-defined.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n (<a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/6-predefined-author-defined.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<p>For the examples in the previous graphic, the <code>polite<\/code> value for <code>aria-live<\/code> is one of <a href=\"https:\/\/w3c.github.io\/aria\/#aria-live\">the three predefined values<\/a> (<code>off<\/code>, <code>polite<\/code>, and <code>assertive<\/code>). For <code>aria-label<\/code>, \u201cSave\u201d is a text string manually supplied by the author.<\/p>\n<p>You declare ARIA on HTML elements the same way you declare other attributes:<\/p>\n<pre><code class=\"language-html\"><!-- \n Applies an id value of \n \"carrot\" to the div\n-->\n<div id=\"carrot\"><\/div>\n\n<!-- \n Hides the content of this paragraph \n element from assistive technology \n-->\n<p aria-hidden=\"true\">\n Assistive technology can't read this\n<\/p>\n\n<!-- \n Provides an accessible name of \"Stop\", \n and also communicates that the button \n is currently pressed. A type property \n with a value of \"button\" prevents \n browser form submission.\n-->\n<button \n aria-label=\"Stop\"\n aria-pressed=\"true\"\n type=\"button\">\n <!-- SVG icon -->\n<\/button>\n<\/code><\/pre>\n<p>Other usage notes:<\/p>\n<ul>\n<li>You can place more than one ARIA declaration on an HTML element.<\/li>\n<li>The order of placement of ARIA when declared on an HTML element does not matter.<\/li>\n<li>There is no limit to how many ARIA declarations can be placed on an element. Be aware that <strong>the more you add, the more complexity you introduce<\/strong>, and more complexity means a larger chance <a href=\"https:\/\/www.a11yproject.com\/posts\/aria-has-perfect-support\/\">things may break or not function as expected<\/a>.<\/li>\n<li>You can declare ARIA on an HTML element and also have other non-ARIA declarations, such as <code>class<\/code> or <code>id<\/code>. The order of declarations does not matter here, either.<\/li>\n<\/ul>\n<p>It might also be helpful to know that boolean attributes are treated a little differently in ARIA when compared to HTML. <a href=\"https:\/\/hidde.blog\/\">Hidde de Vries<\/a> writes about this in his post, <a href=\"https:\/\/hidde.blog\/boolean-attributes-in-html-and-aria-whats-the-difference\/\">\u201cBoolean attributes in HTML and ARIA: what’s the difference?\u201d<\/a>.<\/p>\n<h2 id=\"not-a-whole-lot-of-aria-is-hardcoded\">Not A Whole Lot Of ARIA Is \u201cHardcoded\u201d<\/h2>\n<p>In this context, \u201chardcoding\u201d means directly writing a static attribute or value declaration into your component, view, or page.<\/p>\n<p>A lot of ARIA is designed to be applied or conditionally modified dynamically based on <a href=\"https:\/\/www.freecodecamp.org\/news\/stateful-vs-stateless-architectures-explained\/\">application state<\/a> or as a response to someone\u2019s action. An example of this is a show-and-hide disclosure pattern:<\/p>\n<ul>\n<li><a href=\"https:\/\/w3c.github.io\/aria\/#aria-expanded\">ARIA\u2019s <code>aria-expanded<\/code> attribute<\/a> is toggled from <code>false<\/code> to <code>true<\/code> to communicate if the disclosure is in an expanded or collapsed state.<\/li>\n<li><a href=\"https:\/\/html.spec.whatwg.org\/multipage\/interaction.html#the-hidden-attribute\">HTML\u2019s <code>hidden<\/code> attribute<\/a> is conditionally removed or added in tandem to show or hide the disclosure\u2019s full content area.<\/li>\n<\/ul>\n<div class=\"break-out\">\n<pre><code class=\"language-html\"><div class=\"disclosure-container\">\n <button \n aria-expanded=\"false\"\n class=\"disclosure-toggle\"\n type=\"button\">\n How we protect your personal information\n <\/button>\n <div \n hidden\n class=\"disclosure-content\">\n <ul>\n <li>Fast, accurate, thorough and non-stop protection from cyber attacks<\/li>\n <li>Patching practices that address vulnerabilities that attackers try to exploit<\/li>\n <li>Data loss prevention practices help to ensure data doesn't fall into the wrong hands<\/li>\n <li>Supply risk management practices help ensure our suppliers adhere to our expectations<\/li>\n <\/ul>\n <p>\n <a href=\"\/security\/\">Learn more about our security best practices<\/a>.\n <\/p>\n <\/div>\n<\/div>\n<\/code><\/pre>\n<\/div>\n<p>A common example of a hardcoded ARIA declaration you\u2019ll encounter on the web is <a href=\"https:\/\/www.smashingmagazine.com\/2021\/05\/accessible-svg-patterns-comparison\/\">making an SVG icon inside a button decorative<\/a>:<\/p>\n<pre><code class=\"language-html\"><button type=\"button>\n <svg aria-hidden=\"true\">\n <!-- SVG code -->\n <\/svg>\n Save\n<\/button>\n<\/code><\/pre>\n<p>Here, the string \u201cSave\u201d is what is required for someone to understand what the button will do when they activate it. The accompanying icon helps that understanding visually but is considered redundant and therefore <a href=\"https:\/\/www.w3.org\/WAI\/tutorials\/images\/decorative\/\">decorative<\/a>.<\/p>\n<h2 id=\"declaring-an-aria-role-on-something-that-already-uses-that-role-implicitly-does-not-make-it-extra-accessible\">Declaring An Aria Role On Something That Already Uses That Role Implicitly Does Not Make It \u201cExtra\u201d Accessible<\/h2>\n<p>An implied role is all you need if you\u2019re using semantic HTML. Explicitly declaring its role via ARIA does not confer any additional advantages.<\/p>\n<pre><code class=\"language-html\"><!-- \n You don't need to declare role=\"button\" here.\n Using the <button> element will make assistive \n technology announce it as a button. The \n role=\"button\" declaration is redundant.\n -->\n<button role=\"button\">\n Save\n<\/button>\n<\/code><\/pre>\n<p>You might occasionally run into these redundant declarations on <a href=\"https:\/\/www.w3.org\/WAI\/ARIA\/apg\/patterns\/landmarks\/examples\/HTML5.html\">HTML sectioning elements<\/a>, such as <code><main role="main"><\/code>, or <code><footer role="contentinfo"><\/code>. This isn\u2019t needed anymore, and you can just use the <code><main><\/code> or <code><footer><\/code> elements.<\/p>\n<p>The reason for this is historic. These declarations were done for support reasons, in that it was a stop-gap technique for assistive technology that needed to be updated to support these <a href=\"https:\/\/www.w3.org\/html\/logo\/\">new-at-the-time HTML elements<\/a>.<\/p>\n<p>Contemporary assistive technology does not need these redundant declarations. Think of it the same way that we don\u2019t have to use vendor prefixes for the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/border-radius\">CSS <code>border-radius<\/code> property<\/a> anymore.<\/p>\n<p><strong>Note<\/strong>: <em>There is an exception to this guidance. There are circumstances where certain complex and complicated markup patterns don\u2019t work as expected for assistive technology. In these cases, we want to hardcode the implicit role as explicit ARIA to ensure it works. This assistive technology support concern is <a href=\"#the-more-aria-you-add-to-something-the-greater-the-chance-something-will-behave-unexpectedly\">covered in more detail later in this post<\/a>.<\/em><\/p>\n<h2 id=\"you-don-t-need-to-say-what-a-control-is-that-is-what-roles-are-for\">You Don\u2019t Need To Say What A Control Is; That Is What Roles Are For<\/h2>\n<p>Both implicit and explicit roles are announced by screen readers. You don\u2019t need to include that part for things like the interactive element\u2019s text string or <a href=\"https:\/\/w3c.github.io\/aria\/#aria-label\">an <code>aria-label<\/code><\/a>.<\/p>\n<pre><code class=\"language-html\"><!-- Don't do this -->\n<button \n aria-label=\"Save button\"\n type=\"button\">\n <!-- Icon SVG -->\n<\/button>\n\n<!-- Do this instead -->\n<button \n aria-label=\"Save\"\n type=\"button\">\n <!-- Icon SVG -->\n<\/button>\n<\/code><\/pre>\n<p>Had we used the string value of \u201cSave button\u201d for our Save button, a screen reader would announce it along the lines of, \u201cSave button, button.\u201d That\u2019s <a href=\"https:\/\/theideaplace.net\/tooltip-should-not-start-an-accessible-name\/\">redundant<\/a> and confusing.<\/p>\n<div class=\"partners__lead-place\"><\/div>\n<h2 id=\"aria-roles-have-very-specific-meanings\">ARIA Roles Have Very Specific Meanings<\/h2>\n<p>We sometimes refer to website and web app navigation colloquially as menus, especially if it\u2019s an e-commerce-style <a href=\"https:\/\/www.nngroup.com\/articles\/mega-menus-work-well\/\">mega menu<\/a>.<\/p>\n<p>In ARIA, <a href=\"https:\/\/w3c.github.io\/aria\/#menu\">menus mean something very specific<\/a>. Don\u2019t think of global or in-page navigation or the like. Think of menus in this context as what appears when you click the Edit menu button on your application\u2019s menubar.<\/p>\n<figure class=\"\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/7-menu.png\"><\/p>\n<p> <img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"712\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"The edit menu option activated on Windows Notepad. It shows a list of menu options, with the option for \u201cGo to\u201d being in focus. Some options are disabled, as there is no content in the Notepad file, nor is there anything on the Windows Clipboard. The other menu options are Undo, Cut, Copy, Paste, Delete, Search with Bing, Find, Find Next, Find Previous, Replace, Select All, Time\/Date, and Font. Screenshot.\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/7-menu.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n Notepad, Windows 11. (<a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/7-menu.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<p>Using a role improperly because its name seems like an appropriate fit at first glance creates confusion for people who do not have the context of the visual UI. <strong>Their expectations will be set with the announcement of the role<\/strong>, then subverted when it does not act the way it is supposed to.<\/p>\n<p>Imagine if you click on a link, and instead of taking you to another webpage, it sends something completely unrelated to your printer instead. It\u2019s sort of like that.<\/p>\n<p>Declaring <code>role="menu"<\/code> is a common example of a misapplied role, but there are others. The best way to know what a role is used for? <a href=\"https:\/\/www.w3.org\/TR\/wai-aria\/#role_definitions\">Go straight to the source<\/a> and read up on it.<\/p>\n<h2 id=\"certain-roles-are-forbidden-from-having-accessible-names\">Certain Roles Are Forbidden From Having Accessible Names<\/h2>\n<p>These roles are <code>caption<\/code>, <code>code<\/code>, <code>deletion<\/code>, <code>emphasis<\/code>, <code>generic<\/code>, <code>insertion<\/code>, <code>paragraph<\/code>, <code>presentation<\/code>, <code>strong<\/code>, <code>subscript<\/code>, and <code>superscript<\/code>.<\/p>\n<p>This means you can try and provide an accessible name for one of these elements — say via <code>aria-label<\/code> — but it won\u2019t work because it\u2019s disallowed by <a href=\"https:\/\/www.w3.org\/TR\/wai-aria-1.2\/#namefromprohibited\">the rules of ARIA\u2019s grammar<\/a>.<\/p>\n<div class=\"break-out\">\n<pre><code class=\"language-html\"><!-- This won't work-->\n<strong aria-label=\"A 35% discount!\">\n $39.95\n<\/strong>\n\n<!-- Neither will this -->\n<code title=\"let JavaScript example\">\n let submitButton = document.querySelector('button[type=\"submit\"]');\n<\/code>\n<\/code><\/pre>\n<\/div>\n<p>For these examples, recall that the role is implicit, sourced from the declared HTML element.<\/p>\n<p>Note here that sometimes a browser will make an attempt regardless and overwrite the author-specified string value. This overriding is a confusing act for all involved, which led to the rule being established in the first place.<\/p>\n<h2 id=\"you-can-t-make-up-aria-and-expect-it-to-work\">You Can\u2019t Make Up ARIA And Expect It To Work<\/h2>\n<p>I\u2019ve witnessed some developers guess-adding CSS classes, such as <code>.background-red<\/code> or <code>.text-white<\/code>, to their markup and being rewarded if the design visually updates correctly.<\/p>\n<p>The reason this works is that someone previously added those classes to the project. With ARIA, the people who add the content we can use are the <a href=\"https:\/\/www.w3.org\/WAI\/about\/groups\/ariawg\/\">Accessible Rich Internet Applications Working Group<\/a>. This means each new version of ARIA has a predefined set of properties and values. Assistive technology is then updated to parse those attributes and values, <a href=\"https:\/\/ericwbailey.website\/published\/it-needs-to-map-back-to-a-role\/#edicts-still-need-to-be-carried-out\">although this isn\u2019t always a guarantee<\/a>.<\/p>\n<p>Declaring ARIA, which isn\u2019t part of that predefined set, means assistive technology won\u2019t know what it is and consequently won\u2019t announce it.<\/p>\n<pre><code class=\"language-html\"><!-- \n There is no \"selectpanel\" role in ARIA.\n Because of this, this code will be announced \n as a button and not as a select panel.\n-->\n<button \n role=\"selectpanel\"\n type=\"button\">\n Choose resources\n<\/button>\n<\/code><\/pre>\n<h2 id=\"aria-fails-silently\">ARIA Fails Silently<\/h2>\n<p>This speaks to the previous section, where ARIA won\u2019t understand words spoken to it that exist outside its limited vocabulary.<\/p>\n<p><strong>There are no console errors for malformed ARIA<\/strong>. There\u2019s also no alert dialog, beeping sound, or flashing light for your operating system, browser, or assistive technology. This fact is yet another reason why it is so important to <a href=\"https:\/\/webaim.org\/articles\/nvda\/\"><strong>test with actual assistive technology<\/strong><\/a>.<\/p>\n<p><a href=\"https:\/\/webaim.org\/articles\/screenreader_testing\/\">You don\u2019t have to be an expert<\/a> here, either. There is a good chance your code needs updating if you set something to announce as a specific <a href=\"https:\/\/www.w3.org\/TR\/wai-aria\/#introstates\">state<\/a> and assistive technology in its default configuration does not announce that state.<\/p>\n<h2 id=\"aria-only-exposes-the-presence-of-something-to-assistive-technology\">ARIA Only Exposes The Presence Of Something To Assistive Technology<\/h2>\n<p><strong>Applying ARIA to something does not automatically \u201cunlock\u201d capabilities<\/strong>. It <strong>only<\/strong> sends a hint to assistive technology about how the interactive content should behave.<\/p>\n<p>For assistive technology like screen readers, that hint could be for how to announce something. For assistive technology like <a href=\"https:\/\/www.afb.org\/node\/16207\/refreshable-braille-displays\">refreshable Braille displays<\/a>, it could be for how it raises and lowers its pins. For example, <strong>declaring <code>role="button"<\/code> on a <code>div<\/code> element does not automatically make it clickable<\/strong>. You will still need to:<\/p>\n<ul>\n<li>Target the <code>div<\/code> element in JavaScript,<\/li>\n<li>Tie it to a <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Element\/click_event\">click event<\/a>,<\/li>\n<li>Author the interactive logic that it performs when clicked, and then<\/li>\n<li>Accommodate <a href=\"https:\/\/adrianroselli.com\/2022\/04\/brief-note-on-buttons-enter-and-space.html\">all the other expected behaviors<\/a>.<\/li>\n<\/ul>\n<p>This all makes me wonder why you can\u2019t save yourself some work and use a <code>button<\/code> element in the first place, but that is a different story for a different day.<\/p>\n<p>Additionally, <strong>adjusting an element\u2019s role via ARIA does not modify the element\u2019s native functionality<\/strong>. For example, you can declare <code>role="image"<\/code> on a <code>div<\/code> element. However, attempting to declare the <code>alt<\/code> or <code>src<\/code> attributes on the <code>div<\/code> won\u2019t work. This is because <code>alt<\/code> and <code>src<\/code> are <a href=\"https:\/\/html.spec.whatwg.org\/multipage\/grouping-content.html#the-div-element\">not supported attributes for <code>div<\/code><\/a>.<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/8-image%20element-div.png\"><\/p>\n<p> <img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"289\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"Two panels, one labeled \u201cWill work\u201d and the other labeled, \u201cWon\u2019t work.\u201d The panel labeled \u201cWill work\u201d shows an image element with an alt and src attribute. The panel labeled \u201cWon\u2019t work\u201d shows a div with a role of image, as well as alt and src attributes. Both src attributes link to a file called cucumber.jpg, and both alt attributes use a string value of \u201cA small cucumber.\u201d\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/8-image%20element-div.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n (<a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/8-image%20element-div.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<h2 id=\"declaring-an-aria-role-on-something-will-override-its-semantics-but-not-its-behavior\">Declaring an ARIA Role On Something Will Override Its Semantics, But Not Its Behavior<\/h2>\n<p>This speaks to the previous section on <strong>ARIA only exposing something\u2019s presence<\/strong>. Don\u2019t forget that certain HTML elements have primary and secondary interactive capabilities built into them.<\/p>\n<p>For example, an anchor element\u2019s primary capability is navigating to whatever URL value is provided for its <code>href<\/code> attribute. Secondary capabilities for an anchor element include copying the URL value, opening it in a new tab or incognito window, and so on.<\/p>\n<figure class=\"\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/9-right-click.png\"><\/p>\n<p> <img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"720\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"A link whose string value is \u201cLink with a role set to button.\u201d Above it is text that reads, \u201cFor demonstration purposes only. Please don\u2019t do this.\u201d The link has a cursor placed over it, with an active right-click menu. The menu shows multiple actions you can take on the link, including opening it in a new tab or window, copying and saving the link address, searching the web for the link\u2019s string value, as well as options provided by user-installed browser extensions. These options are managing the link with the 1Password password manager and copying a link to the selected text. Cropped screenshot.\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/9-right-click.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n Chrome on macOS. Note the support for user-installed browser extensions. (<a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/9-right-click.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<p>These secondary capabilities are still preserved. However, it may not be apparent to someone that they can use them — or use them in the way that they\u2019d expect — depending on what is announced.<\/p>\n<p>The opposite is also true. When an element has no capabilities, having its role adjusted does not grant it any new abilities. Remember, <a href=\"#aria-only-exposes-the-presence-of-something-to-assistive-technology\"><strong>ARIA only announces<\/strong><\/a>. This is why that <code>div<\/code> with a <code>role<\/code> of <code>button<\/code> assigned to it won\u2019t do anything when clicked if no companion JavaScript logic is also present.<\/p>\n<figure class=\"\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/keyboard-support.png\"><\/p>\n<p> <img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"705\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"Two side-by-side graphics, each one consisting of three panels. The first panel on the left of the graphic shows the HTML code for a button element. The first panel for the right graphic shows HTML code for a div with a role of button. Both examples use a string value of \u201cFavorite\u201d and have a class of \u201cbutton-fav\u201d applied to them. The second panel for both left and right graphics shows an identical-looking button labeled \u201cFavorite\u201d, which has a golden-colored background. The third panel for the left graphic shows support for Enter and Space keypresses. The third panel for the right graphic shows no support for Enter and Space keypresses.\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/keyboard-support.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n (<a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/keyboard-support.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<h2 id=\"you-will-need-to-declare-aria-to-make-certain-interactions-accessible\">You Will Need To Declare ARIA To Make Certain Interactions Accessible<\/h2>\n<p>A lot of the previous content may make it seem like ARIA is something you should avoid using altogether. This isn\u2019t true. Know that this guidance is written to help steer you to <strong>situations where HTML does not offer the capability to describe an interaction<\/strong> out of the box. <strong>This space is where you want to use ARIA<\/strong>.<\/p>\n<p>Knowing how to identify this area requires spending some time learning what HTML elements there are, as well as what they are and are not used for. I quite like <a href=\"https:\/\/html5doctor.com\/\">HTML5 Doctor\u2019s Element Index<\/a> for upskilling on this.<\/p>\n<h2 id=\"certain-aria-states-require-certain-aria-roles-to-be-present\">Certain ARIA States Require Certain ARIA Roles To Be Present<\/h2>\n<p>This is analogous to how HTML has both <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTML\/Global_attributes\">global attributes<\/a> and attributes that can only be used on a per-element basis. For example, <a href=\"https:\/\/w3c.github.io\/aria\/#aria-describedby\"><code>aria-describedby<\/code> can be used on any HTML element<\/a> or role. However, <a href=\"https:\/\/w3c.github.io\/aria\/#aria-posinset\"><code>aria-posinset<\/code> can only be used with <code>article<\/code>, <code>comment<\/code>, <code>listitem<\/code>, <code>menuitem<\/code>, <code>option<\/code>, <code>radio<\/code>, <code>row<\/code>, and <code>tab<\/code> roles<\/a>. Remember here that these roles can be provided by either HTML or ARIA.<\/p>\n<p>Learning what states require which roles can be achieved by <a href=\"https:\/\/www.w3.org\/TR\/wai-aria\/#state_prop_def\">reading the official reference<\/a>. Check for the \u201cUsed in Roles\u201d portion of each entry\u2019s characteristics:<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/11-used-in-roles.png\"><\/p>\n<p> <img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"523\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\" A characteristics table for aria setsize. The table\u2019s two columns are labeled \u201cCharacteristic\u201d and \u201cValue.\u201d The second table row is highlighted, demonstrating where you look for what role supports what state. The First row\u2019s first cell has the text, \u201cUsed in roles.\u201d The first row\u2019s second cell has the text, \u201carticle, listitem, menuitem, option, radio, row, tab.\u201d The second row\u2019s first cell has the text, \u201cInherits into Roles.\u201d The second row\u2019s second cell has the text, \u201cmenuitemcheckbox, menuitemradio, treeitem.\u201d The third row\u2019s first cell has the text \u201cValue.\u201d Cropped screenshot.\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/11-used-in-roles.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n Characteristics for <code>aria-setsize<\/code>. (<a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/11-used-in-roles.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<p>Automated code scanners — like <a href=\"https:\/\/www.deque.com\/axe\/\">axe<\/a>, <a href=\"https:\/\/wave.webaim.org\/\">WAVE<\/a>, <a href=\"https:\/\/www.tpgi.com\/arc-platform\/arc-toolkit\/\">ARC Toolkit<\/a>, <a href=\"https:\/\/pa11y.org\/\">Pa11y<\/a>, <a href=\"https:\/\/github.com\/IBMa\/equal-access#equal-access\">equal-access<\/a>, and so on — can catch this sort of thing if they are written in error. I\u2019m a big fan of implementing these sorts of checks as part of a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Continuous_integration\">continuous integration<\/a> strategy, as it makes it a code quality concern shared across the whole team.<\/p>\n<h2 id=\"aria-is-more-than-web-browsers\">ARIA Is More Than Web Browsers<\/h2>\n<p>Speaking of technology that listens, it is helpful to know that the ARIA you declare <strong>instructs the browser to speak to the operating system<\/strong> the browser is installed on. Assistive technology then listens to <a href=\"https:\/\/www.w3.org\/TR\/wai-aria\/#dfn-accessibility-tree\">what the operating system reports<\/a>. It then communicates that to the person using the computer, tablet, smartphone, and so on.<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/12-flowchart-four-steps.png\"><\/p>\n<p> <img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"296\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"A flowchart with four steps. The first step is a webpage with a code icon floating above it. The second step is a computer, with an icon of an indented list floating above it. The third step is the symbol for accessibility, a Vitruvian man in a circle. Above this icon is a speech bubble. The fourth and final step is a person, with an icon of a lit lightbulb floating above it.\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/12-flowchart-four-steps.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n (<a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/12-flowchart-four-steps.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<p>A person can then instruct assistive technology to request the operating system to take action on the web content displayed in the browser.<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/13-flowchart-four-steps.png\"><\/p>\n<p> <img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"296\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"A flowchart with four steps. The first step is a person with an icon of a finger pressing a button floating above it. The second step is the symbol for accessibility, a Vitruvian man in a circle. Above this icon is a speech bubble. The third step is a computer, with an icon of a handshake floating above it. The fourth and final step is an updated webpage, with a clicking mouse cursor icon floating above it.\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/13-flowchart-four-steps.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n (<a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/13-flowchart-four-steps.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<p><strong>This interaction model is by design<\/strong>. It is done to make interaction from assistive technology indistinguishable from interaction performed without assistive technology.<\/p>\n<p>There are a few reasons for this approach. The most important one is <a href=\"https:\/\/css-tricks.com\/accessibility-events\/\">it helps <strong>preserve the privacy and autonomy<\/strong><\/a> of the <a href=\"https:\/\/accessaces.com\/what-disabled-people-have-to-give-up-in-the-name-of-accessibility\/\">people who rely on assistive technologies<\/a>.<\/p>\n<h2 id=\"just-because-it-exists-in-the-aria-spec-does-not-mean-assistive-technology-will-support-it\">Just Because It Exists In The ARIA Spec Does Not Mean Assistive Technology Will Support It<\/h2>\n<p>This support issue was touched on earlier and is a difficult fact to come to terms with.<\/p>\n<p>Contemporary developers enjoy the hard-fought, hard-won benefits of <a href=\"https:\/\/www.webstandards.org\/\">the web standards movement<\/a>. This means you can declare HTML and know that it will <a href=\"https:\/\/www.w3.org\/standards\/\">work with every major browser<\/a> out there. ARIA does not have this. <strong>Each assistive technology vendor has its own interpretation of the ARIA specification<\/strong>. Oftentimes, these interpretations are convergent. Sometimes, they\u2019re not.<\/p>\n<p>Assistive technology vendors also have support roadmaps for their products. Some assistive technology vendors:<\/p>\n<ul>\n<li>Will eventually add support,<\/li>\n<li>May never, and some<\/li>\n<li>Might do so in a way that contradicts how other vendors choose to implement things.<\/li>\n<\/ul>\n<p>There is also the operating system layer to contend with, which I\u2019ll cover in more detail in a little bit. Here, the mechanisms used to communicate with assistive technology are dusty, oft-neglected areas of software development.<\/p>\n<p>With these layers comes a scenario where <strong>the assistive technology can support the ARIA declared, but the operating system itself cannot communicate the ARIA\u2019s presence, or vice-versa<\/strong>. The reasons for this are varied but ultimately boil down to a historic lack of support, prioritization, and resources. However, I am <a href=\"https:\/\/aria-at.w3.org\/\">optimistic that this is changing<\/a>.<\/p>\n<p>Additionally, <strong>there is no equivalent to <a href=\"https:\/\/caniuse.com\/\">Caniuse<\/a>, <a href=\"https:\/\/web.dev\/baseline\">Baseline<\/a>, or <a href=\"https:\/\/webstatus.dev\/\">Web Platform Status<\/a> for assistive technology<\/strong>. The closest analog we have to support checking resources is <a href=\"https:\/\/a11ysupport.io\/\">a11ysupport.io<\/a>, but know that it is the painstaking work of a single individual. Its content may not be up-to-date, as the work is both Herculean in its scale and Sisyphean in its scope. Because of this, I must re-stress <a href=\"https:\/\/www.smashingmagazine.com\/2018\/09\/importance-manual-accessibility-testing\/\"><strong>the importance of manually testing with assistive technology<\/strong><\/a> to determine if the ARIA you use works as intended.<\/p>\n<p><strong>How To Determine ARIA Support<\/strong><\/p>\n<p>There are three main layers to determine if something is supported:<\/p>\n<ol>\n<li>Operating system and version.<\/li>\n<li>Assistive technology and version,<\/li>\n<li>Browser and browser version.<\/li>\n<\/ol>\n<h3 id=\"1-operating-system-and-version\">1. Operating System And Version<\/h3>\n<p>Each operating system (e.g., Windows, macOS, Linux) has its own way of <a href=\"https:\/\/alistapart.com\/article\/semantics-to-screen-readers\/\">communicating what content is present to assistive technology<\/a>. Each piece of assistive technology has to accommodate <strong>how<\/strong> to parse that communication.<\/p>\n<p>Some assistive technology is incompatible with certain operating systems. An example of this is not being able to use <a href=\"https:\/\/support.apple.com\/guide\/voiceover\/get-started-vo4be8816d70\/10\/mac\/15.0\">VoiceOver<\/a> with Windows, or <a href=\"https:\/\/www.freedomscientific.com\/products\/software\/jaws\/\">JAWS<\/a> with macOS. Furthermore, each version of each operating system has slight variations in what is reported and how. Sometimes, the operating system needs to be updated to \u201cteach\u201d it the updated AIRA vocabulary. Also, do not forget that things like <a href=\"https:\/\/github.com\/FreedomScientific\/standards-support\/issues\">bugs and regressions<\/a> can occur.<\/p>\n<h3 id=\"2-assistive-technology-and-version\">2. Assistive Technology And Version<\/h3>\n<p><strong>There is no \u201cone true way\u201d to make assistive technology<\/strong>. Each one is built to address different access needs and wants and is done so in an opinionated way — think how different web browsers have different features and UI.<\/p>\n<p>Each piece of assistive technology that consumes web content has its own way of communicating this information, and <strong>this is by design<\/strong>. It works with what the operating system reports, filtered through things like heuristics and preferences.<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/14-voice-control.png\"><\/p>\n<p> <img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"586\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"A three by three grid of nine buttons, with a title of \u201cSelect your order.\u201d Each button has a food-related emoji, with a tooltip showing the button\u2019s accessible name. The buttons are a hamburger with the title \u201c100% Angus Beef Burger\u201d, french fries with the title \u201cSpecial Smile Fries\u201d, a pizza slice with the title \u201cPepperoni Pizza\u201d, a hot dog with the title \u201cHot Dog With Mustard\u201d, a sandwich with a title of \u201cHam Sando\u201d, a taco with the title of \u201cTuesday Taco\u201d, a plate of spaghetti with the title of \u201cPasgetti\u201d, a waffle with the title of \u201cWaffles Sans Chicken\u201d, and some popcorn with the title of \u201cPoppin\u2019 Corn\u201d.\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/14-voice-control.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n The \u201cShow names\u201d command in <a href=\"https:\/\/support.apple.com\/en-us\/102225\">macOS Voice Control<\/a>, which displays the accessible names of these icon buttons. The accessible name has been supplied by <code>aria-label<\/code>. (<a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/14-voice-control.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<p>Like operating systems, assistive technology also has different versions with what each version is capable of supporting. They can also be susceptible to bugs and regressions.<\/p>\n<p>Another two factors worth pointing out here are <strong>upgrade hesitancy<\/strong> and <strong>lack of financial resources<\/strong>. Some people who rely on assistive technology are hesitant to upgrade it. This is based on a very understandable fear of breaking an important mechanism they use to interact with the world. This, in turn, translates to scenarios like holding off on updates until absolutely necessary, as well as disabling auto-updating functionality altogether.<\/p>\n<p>Lack of financial resources is sometimes referred to as <a href=\"https:\/\/stimpunks.org\/glossary\/crip-tax\/\">the disability or crip tax<\/a>. <a href=\"https:\/\/www.un.org\/development\/desa\/disabilities\/resources\/factsheet-on-persons-with-disabilities\/disability-and-employment.html\">Employment rates tend to be lower for disabled populations<\/a>, and with that comes less money to spend on acquiring new technology and updating it. This concern can and does apply to operating systems, browsers, and assistive technology.<\/p>\n<h3 id=\"3-browser-and-browser-version\">3. Browser And Browser Version<\/h3>\n<p>Some assistive technology works better with one browser compared to another. This is due to the underlying mechanics of <strong>how the browser reports its content to assistive technology<\/strong>. Using Firefox with NVDA is an example of this.<\/p>\n<p>Additionally, the support for this reporting sometimes only gets added for newer versions. Unfortunately, it also means support can sometimes accidentally regress, and people don\u2019t notice before releasing the browser update — again, this is due to a historic lack of resources and prioritization.<\/p>\n<h2 id=\"the-less-commonly-used-the-aria-you-declare-the-greater-the-chance-you-ll-need-to-test-it\">The Less Commonly-Used The ARIA You Declare, The Greater The Chance You\u2019ll Need To Test It<\/h2>\n<p>Common ARIA declarations you\u2019ll come across include, but are not limited to:<\/p>\n<ul>\n<li><code>aria-label<\/code>,<\/li>\n<li><code>aria-labelledby<\/code>,<\/li>\n<li><code>aria-describedby<\/code>,<\/li>\n<li><code>aria-hidden<\/code>,<\/li>\n<li><code>aria-live<\/code>.<\/li>\n<\/ul>\n<p>These are more common because they\u2019re more supported. They are more supported because many of these declarations have been around for a while. Recall <a href=\"#just-because-it-exists-in-the-aria-spec-does-not-mean-assistive-technology-will-support-it\">the previous section that discussed actual assistive technology support<\/a> compared to what the ARIA specification supplies.<\/p>\n<p>Newer, more esoteric ARIA, or historically deprioritized declarations, may not have that support yet or may never. An example of how complicated this can get is <a href=\"https:\/\/w3c.github.io\/aria\/#aria-controls\"><code>aria-controls<\/code><\/a>.<\/p>\n<p><code>aria-controls<\/code> is a part of ARIA that has been around for a while. <a href=\"https:\/\/www.freedomscientific.com\/products\/software\/jaws\/\">JAWS<\/a> had support for <code>aria-controls<\/code>, but then removed it after user feedback. Meanwhile, every other screen reader I\u2019m aware of never bothered to add support.<\/p>\n<p>What does that mean for us? Determining support, or lack thereof, is best accomplished by <strong>manual testing with assistive technology.<\/strong><\/p>\n<h2 id=\"the-more-aria-you-add-to-something-the-greater-the-chance-something-will-behave-unexpectedly\">The More ARIA You Add To Something, The Greater The Chance Something Will Behave Unexpectedly<\/h2>\n<p>This fact takes into consideration the complexities in preferences, different levels of support, bugs, regressions, and other concerns that come with ARIA\u2019s usage.<\/p>\n<p>Philosophically, it\u2019s a lot like adding more interactive complexity to your website or web app via JavaScript. The larger the surface area your code covers, <strong>the bigger the chance something unintended happens<\/strong>.<\/p>\n<p>Consider the amount of ARIA added to a component or discrete part of your experience. The more of it there is declared nested into <a href=\"https:\/\/dom.spec.whatwg.org\/\">the Document Object Model (DOM)<\/a>, the more it interacts with parent ARIA declarations. This is because assistive technology reads what the DOM exposes to help determine intent.<\/p>\n<p>A lot of contemporary development efforts are isolated, feature-based work that focuses on one small portion of the overall experience. Because of this, they may not take this holistic nesting situation into account. This is another reason why — you guessed it — manual testing is so important.<\/p>\n<p>Anecdotally, <a href=\"https:\/\/webaim.org\/projects\/million\/#aria\">WebAIM\u2019s annual Millions report<\/a> — an accessibility evaluation of the top 1,000,000 websites — touches on this phenomenon:<\/p>\n<blockquote><p><strong>Increased ARIA usage on pages was associated with higher detected errors. The more ARIA attributes that were present, the more detected accessibility errors could be expected.<\/strong> This does not necessarily mean that ARIA introduced these errors (these pages are more complex), but pages typically had significantly more errors when ARIA was present.<\/p><\/blockquote>\n<h2 id=\"assistive-technology-may-support-your-invalid-aria-declaration\">Assistive Technology May Support Your Invalid ARIA Declaration<\/h2>\n<p>There is a chance that ARIA, which is authored inaccurately, will actually function as intended with assistive technology. While <strong>I do not recommend betting on this fact to do your work<\/strong>, I do think it is worth mentioning when it comes to things like debugging.<\/p>\n<p>This is due to the wide range of familiarity there is with people who author ARIA.<\/p>\n<p>Some of the more mature assistive technology vendors try to accommodate the lower end of this familiarity. This is done in order to <strong>better enable the people who use their software to actually get what they need<\/strong>.<\/p>\n<p>There isn\u2019t an exhaustive list of what accommodations each piece of assistive technology has. Think of it like <a href=\"https:\/\/quandyfactory.com\/blog\/39\/the_virtue_of_forgiving_html_parsers\">the forgiving nature of a browser\u2019s HTML parser<\/a>, where <strong>the ultimate goal is to render content for humans<\/strong>.<\/p>\n<h2 id=\"aria-label-is-tricky\"><code>aria-label<\/code> Is Tricky<\/h2>\n<p><a href=\"https:\/\/w3c.github.io\/aria\/#aria-label\"><code>aria-label<\/code><\/a> is one of the most common ARIA declarations you\u2019ll run across. It\u2019s also one of the most misused.<\/p>\n<p><a href=\"https:\/\/benmyers.dev\/blog\/dont-use-aria-label-on-static-text-elements\/\"><code>aria-label<\/code> can\u2019t be applied to non-interactive HTML elements<\/a>, but oftentimes is. It <a href=\"https:\/\/adrianroselli.com\/2019\/11\/aria-label-does-not-translate.html\">can\u2019t always be translated<\/a> and is oftentimes <a href=\"https:\/\/ericwbailey.website\/published\/what-they-dont-tell-you-when-you-translate-your-app\/#you%E2%80%99ll-need-to-translate-%2F-localize-more-than-you-think-you-will\">overlooked for localization efforts<\/a>. Additionally, it can make things frustrating to operate for people who use voice control software, where the visible label differs from what the underlying code uses.<\/p>\n<p>Another problem is when it overrides an interactive element\u2019s pre-existing accessible name. For example:<\/p>\n<pre><code class=\"language-html\"><!-- Don't do this -->\n<a \n aria-label=\"Our services\"\n href=\"\/services\/\">\n Services\n<\/a>\n<\/code><\/pre>\n<p>This is a violation of <a href=\"https:\/\/www.w3.org\/WAI\/WCAG21\/Understanding\/label-in-name.html\">WCAG Success Criterion 2.5.3: Label in Name<\/a>, pure and simple. I have also seen it used as a way to provide a <a href=\"https:\/\/adrianroselli.com\/2019\/10\/stop-giving-control-hints-to-screen-readers.html\">control hint<\/a>. This is also a WCAG failure, in addition to being an antipattern:<\/p>\n<div class=\"break-out\">\n<pre><code class=\"language-html\"><!-- Also don't do this -->\n<a \n aria-label=\"Click this link to learn more about our unique and valuable services\"\n href=\"\/services\/\">\n Services\n<\/a>\n<\/code><\/pre>\n<\/div>\n<p>These factors — along with other considerations — are why I consider <a href=\"https:\/\/ericwbailey.website\/published\/aria-label-is-a-code-smell\/\"><code>aria-label<\/code> a code smell<\/a>.<\/p>\n<h2 id=\"aria-live-is-even-trickier\"><code>aria-live<\/code> Is Even Trickier<\/h2>\n<p>Live region announcements are <a href=\"https:\/\/w3c.github.io\/aria\/#aria-live\">powered by <code>aria-live<\/code><\/a> and are an important part of communicating updates to an experience to people who use screen readers.<\/p>\n<p>Believe me when I say that getting <code>aria-live<\/code> to work properly is tricky, even under the best of scenarios. I won\u2019t belabor the specifics here. Instead, I\u2019ll point you to <a href=\"https:\/\/tetralogical.com\/blog\/2024\/05\/01\/why-are-my-live-regions-not-working\/\">\u201cWhy are my live regions not working?\u201d<\/a>, a fantastic and comprehensive article published by TetraLogical.<\/p>\n<h2 id=\"the-aria-authoring-practices-guide-can-lead-you-astray\">The ARIA Authoring Practices Guide Can Lead You Astray<\/h2>\n<p>Also referred to as the APG, the <a href=\"https:\/\/www.w3.org\/WAI\/ARIA\/apg\/\">ARIA Authoring Practices Guide<\/a> should be treated with a decent amount of caution.<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/15-apg-caution.png\"><\/p>\n<p> <img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"463\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"A screenshot of the ARIA Authoring Practices Guide homepage, with a yellow caution tape placed across it.\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/15-apg-caution.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n (<a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/15-apg-caution.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<h3 id=\"the-downsides\">The Downsides<\/h3>\n<p>The guide was originally authored to help demonstrate ARIA\u2019s capabilities. As a result, <strong>its code examples near-exclusively, overwhelmingly, and disproportionately favor ARIA<\/strong>.<\/p>\n<p>Unfortunately, the APG\u2019s latest redesign also makes it far more approachable-looking than its surrounding W3C documentation. This is coupled with <a href=\"https:\/\/www.w3.org\/WAI\/ARIA\/apg\/patterns\/\">demonstrating UI patterns<\/a> in a way that signals it\u2019s a self-serve resource whose code can be used out of the box.<\/p>\n<p>These factors create a scenario where people assume everything can be used as presented. This is <strong>not true<\/strong>.<\/p>\n<p>Recall that just because ARIA is listed in the spec <a href=\"#just-because-it-exists-in-the-aria-spec-does-not-mean-assistive-technology-will-support-it\">does not necessarily guarantee it is supported<\/a>. Adrian Roselli writes about this in detail in his post, <a href=\"https:\/\/adrianroselli.com\/2023\/04\/no-apgs-support-charts-are-not-can-i-use-for-aria.html\">\u201cNo, APG\u2019s Support Charts Are Not \u2018Can I Use\u2019 for ARIA\u201d<\/a>.<\/p>\n<p>Also, remember <a href=\"https:\/\/www.w3.org\/TR\/using-aria\/#firstrule\">the first rule of ARIA<\/a> and know that <a href=\"#aria-has-rules-for-using-it\">an ARIA-first approach is counter to the specification\u2019s core philosophy of use<\/a>.<\/p>\n<p>In my experience, this has led to developers assuming they can copy-paste code examples or reference how it\u2019s structured in their own efforts, and everything will just work. This leads to mass frustration:<\/p>\n<ul>\n<li>Digital accessibility practitioners have to explain that \u201cdoing the right thing\u201d isn\u2019t going to work as intended.<\/li>\n<li>Developers then have to revisit their work to update it.<\/li>\n<li>Most importantly, people who rely on assistive technology risk not being able to use something.<\/li>\n<\/ul>\n<p>This is to say nothing about things like timelines and resourcing, working relationships, reputation, and brand perception.<\/p>\n<h3 id=\"the-upside\">The Upside<\/h3>\n<p>The APG\u2019s main strength is <strong>highlighting what keyboard keypresses people will expect to work<\/strong> on each pattern.<\/p>\n<p>Consider <a href=\"https:\/\/www.w3.org\/WAI\/ARIA\/apg\/patterns\/listbox\/#keyboardinteraction\">the listbox pattern<\/a>. It details keypresses you may expect (arrow keys, <kbd>Space<\/kbd>, and <kbd>Enter<\/kbd>), as well as less-common ones (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Typeahead\">typeahead<\/a> selection and making multiple selections). Here, we need to <a href=\"#the-spirit-of-aria-reflects-the-era-in-which-it-was-created\">remember that ARIA is based on the Windows XP era<\/a>. The keyboard-based interaction the APG suggests is built from the muscle memory established from the UI patterns used on this operating system.<\/p>\n<p>While your tree view component may look visually different from the one on your operating system, <a href=\"https:\/\/github.blog\/engineering\/user-experience\/considerations-for-making-a-tree-view-component-accessible\/#start-with-windows\">people will expect it to be keyboard operable in the same way<\/a>. Honoring this expectation will go a long way to <strong>ensuring your experiences are not only accessible but also intuitive and efficient to use<\/strong>.<\/p>\n<p>Another strength of the APG is giving <a href=\"https:\/\/www.w3.org\/WAI\/ARIA\/apg\/patterns\/\">standardized, centralized names to UI patterns<\/a>. Is it a dropdown? A listbox? A combobox? A select menu? <a href=\"https:\/\/adrianroselli.com\/2020\/03\/stop-using-drop-down.html\">Something else<\/a>?<\/p>\n<p>When it comes to digital accessibility, these terms all have specific meanings, as well as expectations that come with them. Having a common vocabulary when discussing how an experience should work goes a long way to <strong>ensuring everyone will be on the same page<\/strong> when it comes time to make and maintain things.<\/p>\n<h2 id=\"macos-voiceover-can-also-lead-you-astray\">macOS VoiceOver Can Also Lead You Astray<\/h2>\n<p><a href=\"https:\/\/support.apple.com\/guide\/voiceover\/welcome\/mac\">VoiceOver on macOS<\/a> has been <a href=\"https:\/\/www.applevis.com\/forum\/macos-mac-apps\/state-screen-readers-macos\">experiencing a lot of problems<\/a> over the last few years. If I could wager a guess as to why this is, as an outsider, it is that Apple\u2019s priorities are <a href=\"https:\/\/www.apple.com\/visionos\/visionos-2\/\">focused elsewhere<\/a>.<\/p>\n<p>The bulk of web development efforts are conducted on macOS. This means that well-intentioned developers will reach for VoiceOver, as it comes bundled with macOS and is therefore more convenient. However, macOS VoiceOver usage has a drastic minority share for desktops and laptops. It is under 10% of usage, with Windows-based JAWS and NVDA occupying a combined 78.2% majority share:<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/webaim.org\/projects\/screenreadersurvey10\/#primary\"><\/p>\n<p> <img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"526\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"A pie chart. The legend of the pie chart reads, \u201cJAWS, 40.5%\u201d, \u201cNVDA, 37.7%\u201d, \u201cVoiceOver, 9.7%\u201d, \u201cSuperNova, 3.7%\u201d, \u201cZoomText, 207%\u201d, \u201cOrca, 2.4%\u201d, \u201cNarrator, 0.7%\u201d, and \u201cOther, 2.7%.\u201d Cropped screenshot.\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/16-webaim-pie-chart.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n Image source: <a href=\"https:\/\/webaim.org\/projects\/screenreadersurvey10\/#primary\">WebAIM Screen Reader User Survey #10<\/a>. (<a href=\"https:\/\/files.smashing.media\/articles\/what-i-wish-someone-told-me-aria\/16-webaim-pie-chart.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<h3 id=\"the-problem\">The Problem<\/h3>\n<p>The sad, sorry truth of the matter is that macOS VoiceOver, in its current state, has a lot of problems. It should only be used to confirm that it can operate the experience the way Windows-based screen readers can.<\/p>\n<p>This means testing on Windows with NVDA or JAWS will <strong>create an experience that is far more accurate to what most people who use screen readers on a laptop or desktop will experience<\/strong>.<\/p>\n<h3 id=\"dealing-with-the-problem\">Dealing With The Problem<\/h3>\n<p>Because of this situation, I heavily encourage a workflow that involves:<\/p>\n<ol>\n<li>Creating an experience\u2019s underlying markup,<\/li>\n<li>Testing it with NVDA or JAWS to set up baseline expectations,<\/li>\n<li>Testing it with macOS VoiceOver to identify what doesn\u2019t work as expected.<\/li>\n<\/ol>\n<p>Most of the time, I find myself having to <a href=\"#declaring-an-aria-role-on-something-that-already-uses-that-role-implicitly-does-not-make-it-extra-accessible\">declare redundant ARIA on the semantic HTML I write<\/a> in order to address missed expected announcements for macOS VoiceOver.<\/p>\n<p><strong>macOS VoiceOver testing is still important to do<\/strong>, as it is not the fault of the person who uses macOS VoiceOver to get what they need, and we should ensure they can still have access.<\/p>\n<p>You can use apps like <a href=\"https:\/\/www.virtualbox.org\/\">VirtualBox<\/a> and <a href=\"https:\/\/www.microsoft.com\/en-us\/evalcenter\/evaluate-windows-11-enterprise\">Windows evaluation Virtual Machines<\/a> to use Windows in your macOS development environment. Services like <a href=\"https:\/\/assistivlabs.com\/\">AssistivLabs<\/a> also make on-demand, preconfigured testing easy.<\/p>\n<p><strong>What About iOS VoiceOver?<\/strong><\/p>\n<p>Despite sharing the same name, <a href=\"https:\/\/support.apple.com\/guide\/iphone\/turn-on-and-practice-voiceover-iph3e2e415f\/ios\">VoiceOver on iOS<\/a> is a completely different animal. As software, it is separate from its desktop equivalent and also enjoys <a href=\"https:\/\/webaim.org\/projects\/screenreadersurvey10\/#mobileplatforms\">a whopping 70.6% usage share<\/a>.<\/p>\n<p>With this knowledge, know that it\u2019s also important to <strong>test the ARIA you write on mobile<\/strong> to make sure it works as intended.<\/p>\n<h2 id=\"you-can-style-aria\">You Can Style ARIA<\/h2>\n<p>ARIA attributes can be targeted via CSS the way other HTML attributes can. Consider this HTML markup for the main navigation portion of a small e-commerce site:<\/p>\n<pre><code class=\"language-html\"><nav aria-label=\"Main\">\n <ul>\n <li>\n <a href=\"\/home\/\">Home<\/a>\n <a href=\"\/products\/\">Products<\/a>\n <a aria-current=\"true\" href=\"\/about-us\/\">About Us<\/a>\n <a href=\"\/contact\/\">Contact<\/a>\n <\/li>\n <\/ul>\n<\/nav>\n<\/code><\/pre>\n<p>The presence of <code>aria-current="true"<\/code> on the \u201cAbout Us\u201d link will tell assistive technology to <a href=\"https:\/\/tink.uk\/using-the-aria-current-attribute\/\">announce that it is the current part of the site someone is on<\/a> if they are navigating through the main site navigation.<\/p>\n<p>We can also tie that indicator of being the current part of the site into something that is shown visually. Here\u2019s how you can target the attribute in CSS:<\/p>\n<pre><code class=\"language-css\">nav[aria-label=\"Main\"] [aria-current=\"true\"] {\n border-bottom: 2px solid #ffffff;\n}\n<\/code><\/pre>\n<p>This is <strong>an incredibly powerful way to<\/strong> <a href=\"https:\/\/css-tricks.com\/user-facing-state\/\"><strong>tie application state to user-facing state<\/strong><\/a>. Combine it with modern CSS like <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/:has\"><code>:has()<\/code><\/a> and <a href=\"https:\/\/developer.chrome.com\/docs\/web-platform\/view-transitions\">view transitions<\/a> and you have the ability to create robust, sophisticated UI with less reliance on JavaScript.<\/p>\n<h2 id=\"you-can-also-use-aria-when-writing-ui-tests\">You Can Also Use ARIA When Writing UI Tests<\/h2>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Software_testing\">Tests<\/a> are great. They help guarantee that the code you work on will continue to do what you intended it to do.<\/p>\n<p>A lot of web UI-based testing will use the presence of classes (e.g., <code>.is-expanded<\/code>) or data attributes (ex, <code>data-expanded<\/code>) to verify a UI\u2019s existence, position and states. These types of selectors also have a far greater likelihood to be changed as time goes on when compared to semantic code and ARIA declarations.<\/p>\n<p>This is something my coworker Cam McHenry touches on in his great post, <a href=\"https:\/\/camchenry.com\/blog\/how-i-write-accessible-playwright-tests\">\u201cHow I write accessible Playwright tests\u201d<\/a>. Consider this piece of <a href=\"https:\/\/playwright.dev\/\">Playwright<\/a> code, which checks for the presence of a button that toggles open an edit menu:<\/p>\n<div class=\"break-out\">\n<pre><code class=\"language-javascript\">\/\/ Selects an element with a role of `button` \n\/\/ that has an accessible name of \"Edit\"\nconst editMenuButton = await page.getByRole('button', { name: \"Edit\" });\n\n\/\/ Requires the edit button to have a property \n\/\/ of `aria-haspopup` with a value of `true`\nexpect(editMenuButton).toHaveAttribute('aria-haspopup', 'true');\n<\/code><\/pre>\n<\/div>\n<p>The test selects UI based on outcome rather than appearance. That\u2019s <strong>a far more reliable way to target things in the long-term<\/strong>.<\/p>\n<p>This all helps to create a virtuous feedback cycle. It enshrines semantic HTML and ARIA\u2019s presence in your front-end UI code, which helps to guarantee accessible experiences don\u2019t regress. Combining this with styling, you have a <strong>powerful, self-contained system for building robust, accessible experiences<\/strong>.<\/p>\n<h2 id=\"aria-is-ultimately-about-caring-about-people\">ARIA Is Ultimately About Caring About People<\/h2>\n<p>Web accessibility can be about enabling important things like scheduling medical appointments. It is also about fun things like chatting with your friends. It\u2019s also used for every web experience that lives in between.<\/p>\n<p>Using semantic HTML — supplemented with a judicious application of ARIA — helps you enable these experiences. To sum things up, ARIA:<\/p>\n<ul>\n<li>Has been around for a long time, and its spirit reflects the era in which it was first created;<\/li>\n<li>Has a governing taxonomy, vocabulary, and rules for use and is declared in the same way HTML attributes are;<\/li>\n<li>Is mostly used for dynamically updating things, controlled via JavaScript;<\/li>\n<li>Has highly specific use cases in mind for each of its roles;<\/li>\n<li>Fails silently if mis-authored;<\/li>\n<li>Only exposes the presence of something to assistive technology and does not confer interactivity;<\/li>\n<li>Requires input from the web browser, but also the operating system, in order for assistive technology to use it;<\/li>\n<li>Has a range of actual support, complicated by the more of it you use;<\/li>\n<li>Has some things to watch out for, namely <code>aria-label<\/code>, the ARIA Authoring Practices Guide, and macOS VoiceOver support;<\/li>\n<li>Can also be used for things like visual styling and writing resilient tests;<\/li>\n<li>Is best evaluated by using actual assistive technology.<\/li>\n<\/ul>\n<p>Viewed one way, ARIA is arcane, full of misconceptions, and fraught with potential missteps. Viewed another, ARIA is a beautiful and elegant way to programmatically communicate the interactivity and state of a user interface.<\/p>\n<p>I choose the second view. At the end of the day, using ARIA helps to <strong>ensure that disabled people can use a web experience the same way everyone else can<\/strong>.<\/p>\n<p><em>Thank you to <a href=\"https:\/\/adrianroselli.com\/\">Adrian Roselli<\/a> and <a href=\"https:\/\/janmaarten.com\/\">Jan Maarten<\/a> for their feedback.<\/em><\/p>\n<h3 id=\"further-reading\">Further Reading<\/h3>\n<ul>\n<li>\u201c<a href=\"https:\/\/www.lullabot.com\/articles\/what-heck-aria-beginners-guide-aria-accessibility\">What the Heck is ARIA? A Beginner\u2019s Guide to ARIA for Accessibility<\/a>,\u201d Kat Shaw<\/li>\n<li>\u201c<a href=\"https:\/\/www.smashingmagazine.com\/2015\/03\/web-accessibility-with-accessibility-api\/\">Accessibility APIs: A Key To Web Accessibility<\/a>,\u201d L\u00e9onie Watson & Chaals McCathie Nevile<\/li>\n<li>\u201c<a href=\"https:\/\/alistapart.com\/article\/semantics-to-screen-readers\/\">Semantics to Screen Readers<\/a>,\u201d Melanie Richards<\/li>\n<li>\u201c<a href=\"https:\/\/www.tpgi.com\/what-aria-does-not-do\/\">What ARIA does not do<\/a>,\u201d Steve Faulkner<\/li>\n<li>\u201c<a href=\"https:\/\/html5accessibility.com\/stuff\/2024\/07\/15\/what-aria-still-does-not-do\/\">What ARIA still does not do<\/a>,\u201d stevef<\/li>\n<li>\u201c<a href=\"https:\/\/www.deque.com\/blog\/apg-support-tables-why-they-matter\/\">APG support tables — why they matter<\/a>,\u201d Michael Fairchild<\/li>\n<li>\u201c<a href=\"https:\/\/adrianroselli.com\/2023\/02\/aria-vs-html.html\">ARIA vs HTML<\/a>,\u201d Adrian Roselli<\/li>\n<\/ul>\n<div class=\"signature\">\n <img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"Smashing Editorial\" width=\"35\" height=\"46\" loading=\"lazy\" class=\"lazyload\" data-src=\"https:\/\/www.smashingmagazine.com\/images\/logo\/logo--red.png\"><br \/>\n <span>(gg, yk)<\/span>\n<\/div>\n<\/article>\n","protected":false},"excerpt":{"rendered":"<p>What I Wish Someone Told Me When I Was Getting Into ARIA What I Wish Someone Told Me When I Was Getting Into ARIA Eric Bailey 2025-06-16T13:00:00+00:00 2025-06-23T09:33:10+00:00 If you haven\u2019t encountered ARIA before, great! It\u2019s a chance to learn something new and exciting. If you have heard of ARIA before, this might help you…<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[],"class_list":["post-268","post","type-post","status-publish","format-standard","hentry","category-accessibility"],"_links":{"self":[{"href":"https:\/\/niceexcept.com\/index.php\/wp-json\/wp\/v2\/posts\/268","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/niceexcept.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/niceexcept.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/niceexcept.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/niceexcept.com\/index.php\/wp-json\/wp\/v2\/comments?post=268"}],"version-history":[{"count":1,"href":"https:\/\/niceexcept.com\/index.php\/wp-json\/wp\/v2\/posts\/268\/revisions"}],"predecessor-version":[{"id":269,"href":"https:\/\/niceexcept.com\/index.php\/wp-json\/wp\/v2\/posts\/268\/revisions\/269"}],"wp:attachment":[{"href":"https:\/\/niceexcept.com\/index.php\/wp-json\/wp\/v2\/media?parent=268"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/niceexcept.com\/index.php\/wp-json\/wp\/v2\/categories?post=268"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/niceexcept.com\/index.php\/wp-json\/wp\/v2\/tags?post=268"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}