La accesibilidad de tu app ya no es opcional en la UE
Desde el 28 de junio de 2025, el European Accessibility Act (EAA) obliga a que buena parte de los productos y servicios digitales que se venden en la Unión Europea sean accesibles. En España la norma que lo traspone es la Ley 11/2023, de 8 de mayo, desarrollada por el Real Decreto 193/2023. No es una recomendación de diseño ni una buena práctica: es una obligación legal con autoridad supervisora propia —la UTAC, creada por el Real Decreto 143/2026— y con sanciones detrás.
Para una app móvil, "ser accesible" tiene una definición técnica concreta: cumplir el estándar EN 301 549, que remite a las WCAG 2.1 nivel AA y añade requisitos específicos para software nativo. La buena noticia, si construyes con Flutter, es que el framework trae APIs de accesibilidad de primera clase. La mala es que activarlas bien exige criterio, y la mayoría de apps que auditamos suspenden en lo básico: contrastes insuficientes, controles sin etiqueta y layouts que se rompen al subir el tamaño de fuente.
Esta guía explica qué exige la ley, cómo se implementa en Flutter y cómo se prueba de verdad —más allá de "pasar el scanner".
Qué es el EAA y a quién obliga (en España, ya)
El EAA es la Directiva (UE) 2019/882. En España se aplica a través de la Ley 11/2023 y el RD 193/2023, con obligaciones plenamente en vigor desde el 28 de junio de 2025. Afecta, entre otros, a:
- Comercio electrónico (cualquier app que venda productos o servicios).
- Servicios bancarios y financieros para consumidores.
- Transporte de pasajeros (billetes, información de viaje, apps de movilidad).
- Comunicaciones electrónicas.
- Libros electrónicos y software de lectura.
Dos matices que suelen pasarse por alto:
- No hace falta estar domiciliado en la UE. Si tu app se ofrece a usuarios de la UE, aplica, estés donde estés. Es el mismo patrón extraterritorial que ya conoces del RGPD.
- La exención de microempresa es estrecha. Las empresas de servicios con menos de 10 personas y menos de 2 M€ de facturación anual quedan exentas. Pero la exención no cubre a los fabricantes de producto, y el umbral se cruza rápido. No construyas tu estrategia de cumplimiento sobre una exención que perderás en cuanto crezcas.
Sobre los servicios que ya estaban en el mercado antes del 28 de junio de 2025 puede haber periodos transitorios (hasta cinco años según cómo lo desarrolle cada Estado), pero cualquier producto o servicio nuevo debe cumplir desde el primer día. En la práctica: si vas a lanzar o rehacer una app en 2026, cumples ahora.
El estándar que importa: EN 301 549, no "WCAG a secas"
Aquí es donde se equivoca casi todo el mundo. Las WCAG están pensadas para contenido web. Una app móvil nativa —y una app Flutter compila a nativo— se rige por EN 301 549, que incorpora WCAG 2.1 AA como base pero añade cláusulas para software no web y hardware. Traducido a lo que de verdad tienes que hacer en una app:
| Requisito (EN 301 549 / WCAG 2.1 AA) | Qué significa en tu app |
|---|---|
| Contraste de texto mínimo 4.5:1 (3:1 para texto grande) | Revisa cada color de texto sobre su fondo real, incluidos estados y modo oscuro |
| Todo control tiene nombre, rol y estado | Botones, switches y campos deben anunciarse al lector de pantalla, no solo verse |
| Objetivo táctil suficiente | Mínimo recomendado 48x48 dp por elemento interactivo |
| Redimensionado de texto | La UI debe seguir siendo usable al subir el tamaño de fuente del sistema |
| Uso sin depender solo del color | El color no puede ser el único indicador (error, selección, estado) |
| Orden de foco y navegación lógicos | La lectura con lector de pantalla debe seguir un orden coherente |
Cómo se implementa en Flutter
Flutter expone toda esta capa a través del árbol de Semantics, que se traduce a TalkBack (Android) y VoiceOver (iOS). Los widgets de Material y Cupertino ya aportan semántica por defecto; tu trabajo es rellenar los huecos y no romperla.
// Etiqueta explícita para un control cuyo propósito no es evidente por el texto
Semantics(
label: 'Buscar vuelos',
button: true,
child: IconButton(
icon: const Icon(Icons.search),
onPressed: _buscar,
),
)
// Marcar una cabecera para que el lector de pantalla permita saltar entre secciones
Semantics(
header: true,
child: Text('Resultados', style: textTheme.headlineSmall),
)
// Objetivo táctil garantizado y respeto del escalado de texto del sistema
ConstrainedBox(
constraints: const BoxConstraints(
minWidth: kMinInteractiveDimension, // 48.0
minHeight: kMinInteractiveDimension,
),
child: Text(
'Continuar',
// No fijes fontSize en px absolutos ignorando MediaQuery.textScaler:
// deja que el texto escale y prueba el layout a 200 %.
style: textTheme.labelLarge,
),
)
Los puntos donde más falla la gente:
- Iconos sin etiqueta. Un
IconButtoncon solo un icono se anuncia como "botón" sin más. AñadetooltipoSemantics(label:). - Imágenes decorativas que ensucian. Envuélvelas en
ExcludeSemanticspara que el lector no las lea. - Grupos que se leen a trozos. Usa
MergeSemanticspara que una tarjeta (avatar + nombre + estado) se anuncie como una sola unidad. - Texto que no escala. Evita
fontSizeclavados y contenedores de altura fija con texto dentro: revienta a escalas grandes.
Cuándo NO tocar Semantics: no añadas etiquetas manuales a widgets de Material que ya las traen —duplicarás anuncios y empeorarás la experiencia—. La accesibilidad se mide por cómo suena en el lector de pantalla, no por cuántos Semantics metes.
Cómo se prueba (y por qué "pasa el scanner" no basta)
Hay tres niveles, y el automático es solo el primero.
1. Tests automáticos en CI. Flutter trae matchers para las guías de accesibilidad. Fállalos en el pipeline:
testWidgets('cumple guías de accesibilidad', (tester) async {
final handle = tester.ensureSemantics();
await tester.pumpWidget(const MiApp());
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
await expectLater(tester, meetsGuideline(iOSTapTargetGuideline));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
await expectLater(tester, meetsGuideline(textContrastGuideline));
handle.dispose();
});
2. Inspección con DevTools. El semantics inspector de Flutter DevTools te deja ver el árbol de accesibilidad tal y como lo recibe el sistema operativo: nombres, roles y estados de cada nodo.
3. Prueba manual con lector de pantalla. Este es el juez real y el que ningún test automático sustituye. Navega tu app entera con TalkBack y con VoiceOver, solo con gestos, sin mirar la pantalla. Si no puedes completar el flujo principal, no cumples —aunque el scanner esté en verde—. Los tests automáticos detectan quizá el 30-40 % de los problemas reales; el resto sale con una persona y un lector de pantalla.
Para una obligación legal como el EAA, además conviene una auditoría formal contra EN 301 549 y guardar la documentación: la norma no solo exige cumplir, exige documentar y mantener el cumplimiento.
Qué hacer esta semana
Si tienes una app en la UE en cualquiera de los sectores afectados, este es el mínimo accionable:
- Pasa los matchers de accesibilidad en tu suite de tests y mételos en CI para que no haya regresiones.
- Audita contrastes de color en modo claro y oscuro, incluidos estados deshabilitado y error.
- Recorre el flujo crítico (alta, compra, pago) entero con TalkBack y VoiceOver.
- Sube el tamaño de fuente del sistema al máximo y busca textos cortados y botones que desaparecen.
- Documenta el resultado contra EN 301 549. Lo que no está documentado, ante una inspección, no existe.
En resumen
La accesibilidad dejó de ser un "nice to have" para convertirse en un requisito legal con sanciones en toda la UE. Es, además, deuda técnica de las caras: barata si se diseña desde el principio, lenta y costosa si se parchea al final sobre una app entera. Flutter te da las herramientas —Semantics, matchers de contraste y objetivo táctil, integración nativa con TalkBack y VoiceOver—; lo que marca la diferencia es el criterio para usarlas y el hábito de probar con un lector de pantalla de verdad.
Si necesitas auditar una app existente contra EN 301 549 o construir una nueva accesible desde el diseño, en Dribba llevamos la accesibilidad como parte del estándar de calidad, no como un extra. También puedes reforzar tu equipo con perfiles senior de Flutter vía staff augmentation. Y si te interesa el marco regulatorio europeo aplicado a producto, tenemos más análisis como el del AI Act.




