Photo by Daniel Ali on Unsplash

When we talk about accessibility and accessible apps, we mean building applications that are “responsive” regardless of any user specific needs.

In this context, “responsive” means that our app is suitable for all users, regardless they have a visual, a hearing impairment or even a physical handicap. In the end, it’s all about developing inclusive mobile apps.

Why should we care about accessibility…?

There are several good reasons to build accessible apps, ranging from personal values to financial motivations. Examples would be:

Still not convinced…? Check the following infography:

Accessibility statistics

How do we implement accessible apps…?
P.O.U.R. principles to the rescue!

Luckily for us, the accessibility topic has been discussed for several years, specially when applying it into the digital world.

As a result, we do not have to reinvent the wheel: most of the practices already stablished in the web are valid for mobile applications.

All these accessibility directives & guidelines are bundled into the P.O.U.R. principles, standing for:

  • (P)erceivable. The data displayed in our app should be presented in a way that our users can “get it” easily.
    Example: adding a text description to an image, so the users with visual impairment know the contents depicted by the image.
  • (O)perable. Users must be able to perform specific actions while using our app and also navigate from one screen to another.
    Example: adding support for different kind of inputs or even voice commands.
  • (U)nderstandable. We should assist our users with tips and clear directions so they can perform a task with no hassle.
    Example: form with hints and proper error messages.
  • (R)obust. Building compatible solutions based on industry standards, so we guarantee those will continue working in the future.

Accessibility with P.O.U.R.

Accessibility API in Flutter

If you’re reading this, you probably heard the “Everything is a widget” Flutter motto. So… how do we make our Flutter apps accessible? As you’ve probably guessed, by adding more widgets!

Flutter API includes specific widgets for accessibility, such as:

For instance, we can wrap a widget with “Semantics” and manage its alternative text description:

@override
  Widget build(BuildContext context) {
    return Semantics(
      value: "Welcome to the accessible counter app in Flutter",
      child: MaterialApp(
        title: 'Accessibility Demo',
        ...
        home: const MyHomePage(),
      ),
    );
  }

Moreover, most common widgets include default accessibility properties. The “Text” widget, for instance, contains the “semanticsLabel” property:

Text(
   "Some title",
   semanticsLabel: "Some accessibility description",
)

In terms of accessibility, the previous snippet would be equivalent to:

Semantics(
   value: "Some accessibility description",
   child: Text("Some title")
)

By using these semantics widgets, we can add text alternatives or provide assistance to users easily, complying with some of the accessibility guidelines. Cross-platform accessibility out-of- the-box! Well, not there yet, but certainly is a good start ­čÖé

The semantics tree

You probably know all about the widget tree, so you may be wondering… does it handle semantics too? Not exactly…

Turns out that there is another tree in the Flutter forest… framework: meet the semantics tree!

The semantics tree basically stores the accessibility data of our app. Every time we wrap a component with a “Semantics” widget or we use some of the semantics properties, we add a new node to the semantics tree, containing the description of the original widget. Eventually this information is retrieved by screen readers and other accessibility tools so the contents of our app reaches all audiences.

Take into account that Flutter favours composition, and we build our UI by nesting widgets. Sometimes we may have code like:

Padding(
   ...   
   child: Center(
      child: Container(
         margin: EdgeInsets.all(8.0),
         child: Text(
            "Some text", 
            semanticsLabel: "Some text description"
         )     
      )
   )
)   

In this example, we’re displaying some fancy text with styling, using a group of widgets to set its alignment, paddings and margins. But the only important widget in terms of accessibility is the “Text” widget.

That’s why these 4 widgets in the widget tree will have only 1 node in the semantics tree. So the binding between the widget and the semantics tree is not a 1-to-1 relationship. This means that several nodes in the widget tree may map to a single semantics node.

Relationship between widget and semantics tree

Coming up next…

In the next article, we will see different ways of implementing accessibility in a sample Flutter app. So write you next time!

References

https://docs.flutter.dev/development/accessibility-and-localization/accessibility

Source code

https://github.com/begomez/Flutter-Accessibility

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: