3.4: Static vs. Dynamic WAI-ARIA
- Page ID
- 15593
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)
( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\id}{\mathrm{id}}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\kernel}{\mathrm{null}\,}\)
\( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\)
\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\)
\( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)Even if you don’t use JavaScript, there is a good amount you can do with static WAI-ARIA to improve the accessibility of a website or web application. You may have already gathered from the discussion of states and properties that some WAI-ARIA can be written right into the HTML of a web page (e.g., properties and landmarks). Others need to be dynamically updated based on user input or context (e.g., states and some properties).
Some of the static WAI-ARIA attributes you are likely to use are listed below, with their descriptions from W3C.
Global Static Properties
- aria-describedby: Identifies the element (or elements) that describes the object.
- aria-labelledby: Identifies the element (or elements) that labels the current element.
- aria-label: Defines a string value that labels the current element.
- aria-controls: Identifies the element (or elements) whose contents or presence are controlled by the current element.
- aria-owns: Identifies an element (or elements) in order to define a visual, functional, or contextual parent/child relationship between DOM elements where the DOM hierarchy cannot be used to represent the relationship.
- aria-details: Identifies the element that provides a detailed, extended description for the object.
Below is an example of some of these attributes in action. Though this example would need some scripting to handle the submenu opening and closing, and dynamically updating aria-expanded
to false when the submenu is closed, and update the active element referenced in aria-activedescendant
, you can get an idea of the semantics that are being applied to make the nested list announce itself as a menu. Watch or listen to the screen reader output in the video that follows the code box below to understand how the WAI-ARIA attributes are read. Examine the code in the code box to understand what WAI-ARIA is being used to produce that output.
How Does the Above Markup Work?
- Navigating with the Tab key, focus first goes to the
"menu_container"
div, which is made keyboard focusable with thetabindex="0"
attribute. - There the screen reader reads the content of the “chooser” div, identified by
aria-details
, describing what the menu is used for. This div is hidden from view but available to screen readers. This div could be made visible to make it available for everyone. - Next, the “offerings” UL receives focus, also made focusable with
tabindex="0"
. - There, the screen reader reads the content of the “navhowto” div, identified by
aria-describedby
, explaining how to navigate the menu. This div is hidden from view for most users. - Next, using the Arrow keys as instructed by the “navhowto” div, the ‘Home’
menuitem
takes focus, announcing “menubar expanded with submenu, Home, menu”. Probably a little more verbose in this case than it needs to be, but that’s how ChromeVox handles menu items. - Using the Down Arrow key, focus is moved to the “Courses” menu item, announcing “Courses, menu expanded with submenu.” The
aria-haspopup
attribute is what causes a screen reader to announce a submenu.aria-expanded="true"
causes the screen reader to announce that the menu is expanded. - Using the Down Arrow, focus moves into the submenu, announcing “Menu with two items, Economics, menuitem 1 of two.” The submenu is announced as a menu of its own, identified by adding
role="menu"
to the UL containing the two submenu items. - Finally, using the Down Arrow, the screen reader announces “Computer Science, menuitem two of two.”
Here’s a video that shows how ChromeVox would read out the menu described above:
Video: Example Menu with WAI-ARIA (0:33)
Most of the WAI-ARIA elements described in the above series of steps can be used statically by typing the attributes right into the HTML. The aria-activedescendant
would typically be dynamically updated with script as the menuitems are selected. The aria-expanded
would also be updated dynamically switching between true and false when the submenu is toggled opened or closed.
Here are some more static WAI-ARIA attributes, which we’ll look at in a little more detail later as you complete the activities.
Widget Static Attributes
- aria-haspopup: Indicates the availability and type of interactive popup element, such as menu or dialog, that can be triggered by an element.
- aria-modal: Indicates whether an element is modal when displayed
- aria-readonly: Indicates that the element is not editable but is otherwise operable.
- aria-required: Indicates that user input is required on the element before a form may be submitted.
Live Static Regions
- aria-live: Indicates that an element will be updated and describes the types of updates the user agents, assistive technologies, and user can expect from the live region.
- aria-atomic: Indicates whether assistive technologies will present all, or only parts of, the changed region based on the change notifications defined by the aria-relevant attribute.
- aria-relevant: Indicates what notifications the user agent will trigger when the accessibility tree within a live region is modified.