a11yShiny: Accessibility for R Shiny Apps

janderkran1 pts0 comments

a11yShiny: Accessibility for R Shiny Apps – a11yShiny

The State of Accessibility in Web Apps

In 2016, the European Union adopted the Directive on the accessibility of websites and mobile applications targeted at public sector organizations. Its goal is to make websites and apps more inclusive for people with disabilities. Unfortunately, many websites remain inaccessible.

R Shiny and Accessibility

As an R Shiny developer, accessibility has not been my top priority. I develop a prototype with focus on the features with most business value. But often enough, when you work in the public sector or when your Shiny Dashboard is used by more people, accessibility becomes more important. The first thing I thought about was making colors in my plot colorblind-friendly and making sure contrasts are high. But digging deeper into the Web Content Accessibility Guidelines (WCAG 2.2) I learned about screen-readers, responsive layouts, tab focus, ARIA labels and so. I realized that ‘A11y’ is a short form for accessibility and that accessibility is not a simple function parameter you can switch on but that it requires an immense amount of work on R, HTML and CSS code… But wait, shouldn’t this be simpler?

Simplify Accessibility?

Yes, with the a11yShiny package which is now on CRAN. The a11yShiny package is a first shot at making accessibility in R Shiny as simple as a function call. It thereby follows the BITV-2.0, the German implementation of the European directive. The README describes in detail which of the BITV-2.0 criteria are fulfilled when using the a11yShiny wrapper functions.

Installation

You can install the latest version from CRAN directly and then call the library.

install.packages("a11yShiny")

library(a11yShiny)

a11y_ shiny replacements for responsive layout, ARIA labels and tab focus

Instead of calling the usual shiny fluidPage, fluidRow, column and different Input functions (selectInput, radioButtons, etc.) you use the a11y_ wrapper functions.

a11y_fluidPage, a11y_fluidRow and a11y_column ensure responsive layouts . This is for when users want to increase the size of zoom and font without messing up the layout.

Code<br>library(shiny)

a11yShiny::a11y_fluidPage(<br>lang = "en-US",<br>title = "Demo",<br>tags$hr(),<br>a11yShiny::a11y_fluidRow(<br>a11yShiny::a11y_column(4,<br># this aria label you can see with your browser's developer tools<br>aria_label = "More accessible inputs",<br>offset = 8,<br># Contrast mode button for all widgets<br>a11yShiny::a11y_highContrastButton())<br>),<br>tags$hr(),<br>a11yShiny::a11y_fluidRow(<br>a11yShiny::a11y_column(<br>4,<br>shiny::radioButtons("radio_choice", "I am not accessible:",<br>choices = list("Choice 1" = 1, "Choice 2" = 2, "Choice 3" = 3),<br>selected = 1<br>),<br>a11yShiny::a11y_column(<br>4,<br>offset = 4,<br>a11yShiny::a11y_radioButtons("radio_choice_acc",<br>"I am accessible (hover me):",<br>choices = list("Choice 1" = 1, "Choice 2" = 2, "Choice 3" = 3),<br>selected = 1<br>),<br>tags$hr(),<br>a11yShiny::a11y_fluidRow(<br>a11yShiny::a11y_column(<br>6,<br>div(<br>id = "search-row",<br>style = "display: flex; align-items: center; gap: 12px;",<br>textInput("searchbox", label = NULL, placeholder = "Enter your question:", width = "100%"),<br>actionButton(<br>"do_search",<br>label = NULL,<br>icon = icon("search")<br>),<br>#Composite Inputs for text and button<br>a11yShiny::a11y_column(<br>6,<br>div(<br>a11y_textButtonGroup(<br>textId = "text-acc",<br>buttonId = "btn-acc",<br>label = "Enter your question (accessible):",<br>value = "",<br>placeholder = NULL,<br>button_label = NULL,<br>button_icon = icon("search"),<br>button_aria_label = "Search",<br>controls = NULL,<br>layout = c("inline", "stack"),<br># aria label describing the grouped input widgets<br>text_describedby = "Enter your question and send it with click on search button",<br>text_heading_level = NULL

Contrast Mode

I am not accessible:

Choice 1

Choice 2

Choice 3

I am accessible (hover me):

Choice 1

Choice 2

Choice 3

Enter your question (accessible):

All a11y functions allow you to add Accessible Rich Internet Applications Label. ARIA labels are HTML attributes which make visual elements that lack visible text (e.g., icons, buttons without a label) understandable for users with visual impairments through a screen reader. And if you do not add a label description, an error message reminds you to do so ;)

Often enough, you have several input widgets that belong together. E.g. a chat textInput and a send actionButton. a11yShiny allows you to group inputs thematically by applying additional ARIA labels.

Comparison of the HTML structure of standard R Shiny and a11yShiny grouped input widgets: highlighting the aria-label and aria-describedby attributes in the a11yShiny widget.

Another nice feature that comes with the a11y_ functions is the tab focus , making keyboard navigation easier by highlighting the current selection with a bold black frame.

Last but not least, there is a high-contrast button, which applies high contrasts to your input widgets.

Tables and Plots

And what is with all the different output plots and tables?

a11y_renderDataTable makes your DT...

a11yshiny accessibility choice shiny label aria

Related Articles