Saltar al contenido principal

Accesibilidad web

Información sobre accesibilidad web

Contexto

#

Flutter admite la accesibilidad web al traducir su árbol de Semántica interno a una estructura DOM de HTML accesible que los lectores de pantalla puedan entender. Dado que Flutter renderiza su UI en un único lienzo (canvas), necesita una capa especial para exponer el significado y la estructura de la UI a los navegadores web.

Accesibilidad web de activación opcional (Opt-in)

#

Botón invisible

#

Por razones de rendimiento, la accesibilidad web de Flutter no está activada de forma predeterminada. Para activar la accesibilidad, el usuario debe presionar un botón invisible con aria-label="Enable accessibility". Después de presionar el botón, el árbol DOM reflejará toda la información de accesibilidad para los widgets.

Activar el modo de accesibilidad mediante código

#

Un enfoque alternativo es activar el modo de accesibilidad agregando el siguiente código al ejecutar una app.

dart
import 'package:flutter/semantics.dart';

void main() {
  runApp(const MyApp());
  if (kIsWeb) {
    SemanticsBinding.instance.ensureSemantics();
  }
}

Mejorando la accesibilidad con roles semánticos

#

¿Qué son los roles semánticos?

#

Los roles semánticos definen el propósito de un elemento de la UI, ayudando a los lectores de pantalla y otras herramientas de asistencia a interpretar y presentar tu aplicación de manera efectiva a los usuarios. Por ejemplo, un rol puede indicar si un widget es un botón, un enlace, un encabezado, un deslizador (slider) o parte de una tabla.

Aunque los Widgets estándar de Flutter a menudo proporcionan esta semántica automáticamente, un componente personalizado sin un rol claramente definido puede ser incomprensible para un usuario de lector de pantalla.

Al asignar los roles adecuados, te aseguras de que:

  • Los lectores de pantalla puedan anunciar el tipo y el propósito de los elementos correctamente.
  • Los usuarios puedan navegar por tu aplicación de manera más efectiva utilizando tecnologías de asistencia.
  • Tu aplicación cumpla con los estándares de accesibilidad web, mejorando la usabilidad.

Uso de SemanticsRole en Flutter para la web

#

Flutter proporciona el Widget Semantics con el enum SemanticsRole para permitir a los desarrolladores asignar roles específicos a sus Widgets. Cuando tu app web de Flutter se renderiza, estos roles específicos de Flutter se traducen en sus correspondientes roles ARIA en la estructura HTML de la página web.

1. Semántica automática desde Widgets estándar

Muchos Widgets estándar de Flutter, como TabBar, MenuAnchor y Table, incluyen automáticamente información semántica junto con sus roles. Siempre que sea posible, prefiere usar estos Widgets estándar, ya que gestionan muchos aspectos de la accesibilidad listos para usar (out-of-the-box).

2. Agregar o reemplazar roles explícitamente

Para componentes personalizados o cuando la semántica predeterminada no sea suficiente, utiliza el Widget Semantics para definir el rol:

Aquí tienes un ejemplo de cómo podrías definir explícitamente una lista y sus elementos:

dart
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.'),
            ),
          ),
        ],
      ),
    );
  }
}