4.8: Live Regions
- Page ID
- 15607
\( \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}\)Live regions are used to present changes in web content that occur after a web page has loaded. Typical uses include presenting news feeds, feedback and error messages, or live chat output to screen readers, which would otherwise not know about this content changing or being added to a web page already rendered. Live regions can also be used to announce feedback and error messages when a page loads, so screen reader users do not need to search through a web page to find feedback. It reads automatically when a page finishes loading.
Types of Live Regions
A typical live region can be created by adding aria-live="polite"
to any element in which content is updated after a web page has loaded. The “polite” value indicates the priority of the content being updated. In this case, a screen reader will wait for a break in its audio output before announcing the change that occurred. You may also use aria-live="assertive"
to interrupt whatever the screen reader is reading, and instead read the changed content before continuing. Typically, “assertive” should be avoided. Only use it in cases where critical information is being updated, such as an error message or critical feedback.
Normally, aria-live
would not be used to present feedback or error messages, though it is possible. Instead role="alert"
, introduced earlier, would be used. Using role="alert"
creates an assertive live region that interrupts a screen reader to present its content. They can be used within rendered content to present messages without reloading the page, or they can be used after a page loads, to present the message before any of the other content on the page is read.
In addition to the commonly used role="alert"
, there are other less commonly used roles that also act as live regions. These are:
- role=”log”
- role=”marquee”
- role=”timer”
- role=”status”
Here is the full list of live region attributes:
- aria-live: polite, assertive, off
- aria-relevant: additions, removals, text, all
- aria-atomic: true, false
- aria-busy: true, false
- role=”alert”
- role=”log”
- role=”marquee”
- role=”timer”
- role=”status”
Care When Using Live Regions
There are a few cases where using a live region (aria-live
) to read changing content can create a barrier. Take, for instance, a carousel that presents a series of panels that rotate at a particular frequency. It can be helpful to set up a carousel as a live region, so as each panel slides into view, a screen reader reads the content. However, this behaviour could present a barrier, interfering with the screen reader when it is focused elsewhere, reading other content on the page. If a live region is used with a carousel, it should only be active when the carousel has focus. While typically a live region is created as a static WAI-ARIA attribute, in this case, it should be dynamically added on focus and dynamically removed on blur.
For carousels, it is also important to consider the rate at which panels rotate, ensuring that screen readers have enough time to read the content of the panel before rotating on to the next. This timing can be difficult to predict. It depends on the amount of content on each panel, which can vary significantly, and the rate at which users have their reading rate set on their screen reader. One solution to this issue may be to make the carousel manually rotate when it has focus so users can proceed to the next panel only when they are ready.
Another case where live regions can be problematic is with timers. Timers counting by seconds can essentially render the rest of the content on a page unusable for a screen reader user. As the screen reader announces every second, it interrupts the reading of the other content on a page. Timers that increment each minute, for instance, would not have this problem.
Other places where live regions may be problematic are with very active news or Twitter feeds. Though live regions can be useful for this type of updating content, if there is a constant stream of updates or updates occur frequently, screen reader users may have difficulty comprehending other page content with the frequent interruptions.
Try This: To experience the aggravation of a constantly updating live region, open ChromeVox and give focus to the timer below. In this case, the timer is in an iframe, so you can simply set focus outside the iframe to stop it from reading. If the timer were embedded in the content of the page itself, you would not have this option, and the rest of the page would become unusable with a screen reader. The only option would be to leave the page.