Web Accessibility
Background
#Flutter supports web accessibility by translating its internal Semantics tree into an accessible HTML DOM structure that screen readers can understand. Since Flutter renders its UI on a single canvas, it needs a special layer to expose the UI's meaning and structure to web browsers.
Opt-in web accessibility
#Invisible button
#For performance reasons, Flutter's web accessibility is not on by default. To turn on accessibility, the user needs to press an invisible button with aria-label="Enable accessibility"
. After pressing the button, the DOM tree will reflect all accessibility information for the widgets.
Turn on accessibility mode in code
#An alternative approach is to turn on accessibility mode by adding the following code when running an app.
import 'package:flutter/semantics.dart';
void main() {
runApp(const MyApp());
if (kIsWeb) {
SemanticsBinding.instance.ensureSemantics();
}
}
Enhancing Accessibility with Semantic Roles
#What are Semantic Roles?
#Semantic roles define the purpose of a UI element, helping screen readers and other assistive tools interpret and present your application effectively to users. For example, a role can indicate if a widget is a button, a link, to users. For example, a role can indicate whether a widget is a button, a link, a heading, a slider, or part of a table.
While Flutter's standard widgets often provide these semantics automatically, a custom component without a clearly defined role can be incomprehensible to a screen reader user.
By assigning appropriate roles, you ensure that:
- Screen readers can announce the type and purpose of elements correctly.
- Users can navigate your application more effectively using assistive technologies.
- Your application adheres to web accessibility standards, improving usability.
Using SemanticsRole
in Flutter for web
#Flutter provides the Semantics
widget with the SemanticsRole
enum to allow developers to assign specific roles to their widgets. When your Flutter web app is rendered, these Flutter-specific roles are translated into corresponding ARIA roles in the web page's HTML structure.
1. Automatic Semantics from Standard Widgets
Many standard Flutter widgets, like TabBar
, MenuAnchor
, and Table
, automatically include semantic information along with their roles. Whenever possible, prefer using these standard widgets as they handle many accessibility aspects out-of-the-box.
2. Explicitly adding or overriding roles
For custom components or when the default semantics aren't sufficient, use the Semantics
widget to define the role:
Here's an example of how you might explicitly define a list and its items:
import 'package:flutter/material.dart';
import 'package:flutter/semantics.dart';
class MyCustomListWidget extends StatelessWidget {
const MyCustomListWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// This example shows how to explicitly assign list and listitem roles
// when building a custom list structure.
return Semantics(
role: SemanticsRole.list,
explicitChildNodes: true,
child: Column(
children: <Widget>[
Semantics(
role: SemanticsRole.listItem,
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Text('Content of the first custom list item.'),
),
),
Semantics(
role: SemanticsRole.listItem,
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Text('Content of the second custom list item.'),
),
),
],
),
);
}
}
Unless stated otherwise, the documentation on this site reflects the latest stable version of Flutter. Page last updated on 2025-10-09. View source or report an issue.