Front-end et handicap visuel: une contradiction?

L'Ă©quipe de dĂ©veloppement de l'application CFF Inclusive montre, Ă  l'aide d'exemples pratiques, comment les obstacles Ă  l'accessibilitĂ© d'une application peuvent ĂȘtre surmontĂ©s ou Ă©vitĂ©s d'emblĂ©e. Les personnes intĂ©ressĂ©es peuvent tout de suite afficher l'exemple de code correspondant pour les frameworks "Flutter" et "swiftUI".

Trois recommandations pratiques du team chargĂ© du dĂ©veloppement de l’appli « Inclusive CFF » pour un front-end inclusif.

En dĂ©cembre 2020, les CFF lançaient l’appli Inclusive CFF, qui avait initialement pour vocation de numĂ©riser les informations clientĂšle visuelles dans les gares et les trains du trafic grandes lignes des CFF afin de les diffuser sur le smartphone personnel des client·e·s. Elle a ainsi rendu lisibles et audibles les informations de voyage essentielles pour les personnes souffrant d’un handicap visuel. Depuis, l’appli Inclusive CFF s’est enrichie de nouvelles fonctionnalitĂ©s: un localisateur de bouton de porte a Ă©tĂ© installĂ©, les informations clientĂšle affichĂ©es aux arrĂȘts de tram et de bus y ont Ă©tĂ© intĂ©grĂ©es et les annonces diffusĂ©es en gare y sont retranscrites sous forme de texte. C’est pourquoi l’appli, de plus en plus utilisĂ©e par les personnes malentendantes Ă©galement, est devenue aujourd’hui un assistant de voyage pour l’ensemble des voyageurs et voyageuses en situation de handicap.L’appli Inclusive CFF a Ă©tĂ© rĂ©compensĂ©e Ă  plusieurs reprises. Elle a remportĂ© le Prix de la Canne Blanche 2020 remis par l’UCBA ainsi que le Participants Award dĂ©cernĂ© lors des UIC International Sustainable Railway Awards 2022. CFF Inclusive est aussi la toute premiĂšre application Ă  avoir Ă©tĂ© certifiĂ©e en 2022 par la fondation «AccĂšs pour tous».

Mais quels sont les critĂšres Ă  prendre en compte dans le front-end en vue de rendre une application facile d’utilisation pour les personnes souffrant d’un handicap visuel? L’exercice est Ă  la fois passionnant et exigeant. Le team en charge du dĂ©veloppement d’Inclusive CFF a beaucoup appris ces quatre derniĂšres annĂ©es: de la part des utilisateur·trice·s tests ayant une dĂ©ficience visuelle mais Ă©galement de leurs propres tests rĂ©alisĂ©s avec diffĂ©rentes fonctions d’assistance. Ses trois principales recommandations sont prĂ©sentĂ©es ci-dessous et illustrĂ©es par des exemples tirĂ©s du code:

Recommandation n° 1 : prendre en charge l’agrandissement des contenus.

Il est facile d’éviter les textes tronquĂ©s.

De nombreux utilisateurs et utilisatrices en situation de handicap visuel utilisent l’option d’agrandissement du texte proposĂ©e par le systĂšme d’exploitation. Il est par consĂ©quent important que l’appli puisse prendre en charge les diffĂ©rentes tailles de contenu.

Lors de tests rĂ©alisĂ©s avec une application prĂ©sentant des textes agrandis, il arrive rĂ©guliĂšrement que certains contenus soient tronquĂ©s. Dans la plupart des cas, il suffit d’autoriser l’application Ă  afficher des textes de plusieurs lignes pour remĂ©dier Ă  ce problĂšme.

SwiftUI

Text("...")
    .fixedSize(horizontal: false, vertical: true)

Flutter

// Flutter
Text(‘
’), // it usually just works ¯\_(ツ)_/¯
// but use Expanded for Text in a Row
Row(
    children: <Widget>[
        Expanded(
            child: Text(‘
’),
        ),
    ],
)

Mais cette possibilitĂ© n’est parfois pas souhaitable, notamment pour les boutons. Il est dĂšs lors judicieux, d’une part, de choisir des libellĂ©s aussi courts que possible et, d’autre part, de limiter – Ă  titre de compromis – la taille maximale des caractĂšres pour certains textes et de laisser au systĂšme d’exploitation le soin de l’affichage. Toutefois, pour les personnes Ă  l’acuitĂ© visuelle rĂ©duite, une limitation de la taille des caractĂšres n’est pas idĂ©ale dans la mesure oĂč le texte pourrait s’afficher dans une police de caractĂšres trop petite pour elles. Il est donc recommandĂ©, dans la mesure du possible, de raccourcir les libellĂ©s, de disposer diffĂ©remment les boutons dans le design ou d’autoriser les contenus de plusieurs lignes.

SwiftUI

Text(“
”)
    .minimumScaleFactor(0.1)

Flutter

AutoSizeText(    // Use this awesome plugin
    '...',
    maxLines: 1,
    minFontSize: 1,
)
l’image montre trois Ă©crans de l’appli Inclusive CFF affichĂ©s sur un tĂ©lĂ©phone portable. Les deux premiers illustrent la vue dans l’onglet «En route». Sur l’écran de gauche, les textes trop longs sont tronquĂ©s par trois petits points. Sur le deuxiĂšme Ă©cran, ces mĂȘmes textes s’affichent correctement : l’application autorise les textes de plusieurs lignes. La troisiĂšme image reprĂ©sente l’onglet «Gare». Les textes dans les boutons sont affichĂ©s en taille rĂ©duite pour Ă©viter qu’ils ne soient tronquĂ©s.
Illustration 1: texte tronqué (à gauche), texte de plusieurs lignes (au centre), texte avec une taille de caractÚres limitée dans les boutons (à droite).

Dans de nombreux cas, l’agrandissement des contenus ne permet plus l’affichage intĂ©gral du texte sur l’écran. Les utilisateur·trice·s souffrant d’un handicap visuel rencontrent frĂ©quemment ce problĂšme. Il est donc recommandĂ©, lorsqu’un texte risque de s’étendre sur plusieurs lignes suite Ă  un fort agrandissement de sa taille, de configurer des vues dĂ©roulantes.

l’image montre deux Ă©crans extraits de l’on-boarding de l’appli Inclusive CFF. Le premier Ă©cran affiche l’image et le texte tirĂ©s du parcours on-boarding dans la taille standard. Le deuxiĂšme Ă©cran reprĂ©sente le mĂȘme contenu trĂšs agrandi. Pour ce faire, la taille de l’image est rĂ©duite et celle du texte sous l’image fortement augmentĂ©e. Le texte ne pouvant pas s’afficher intĂ©gralement sur l’écran, la crĂ©ation d’une vue dĂ©roulante est requise.
Illustration 2: les vues dĂ©roulantes permettent d’afficher tous les contenus, y compris lorsque la taille du texte est augmentĂ©e.

Autre disposition des éléments pour des contenus agrandis.

Malheureusement, mĂȘme les designs les plus simples ne fonctionnent pas toujours pour toutes les tailles de texte. Dans ce cas, il est conseillĂ© de crĂ©er une autre variante de mise en page qui permette de modifier la disposition des Ă©lĂ©ments en fonction de la taille du contenu. Il peut notamment s’avĂ©rer utile de masquer les icĂŽnes pour rĂ©server davantage d’espace aux informations plus importantes.

SwiftUI

@Environment(\.sizeCategory) var sizeCategory

if SizeCategories.accessibility.contains(sizeCategory) {
    TrainConnectionRowAccessibility(
)
} else {
    TrainConnectionRowNormal(
)
}

Flutter

final mq = MediaQuery.of(context);// Decide for yourself when to switch
if (mq.size.width <= 330 || mq.textScaleFactor >= 1.4) {
    TrainConnectionRowAccessibility();
} else {
    TrainConnectionRowNormal();
}
L’image montre deux Ă©crans de l’appli Inclusive CFF au contenu identique. Il s’agit de la vue standard des prochains dĂ©parts disponible dans l’onglet «Gare». Le mĂȘme Ă©cran est reprĂ©sentĂ© Ă  droite avec un fort grossissement. Les dĂ©parts sont rĂ©organisĂ©s dans le tableau correspondant de maniĂšre Ă  ĂȘtre plus lisibles. La catĂ©gorie de train et le numĂ©ro de ligne ainsi que l’heure de dĂ©part, la destination, les vias et la voie de dĂ©part ne s’affichent pas horizontalement les uns Ă  cĂŽtĂ© des autres mais en grande partie verticalement les uns en dessous des autres.
Illustration 3: le mĂȘme affichage avec une taille de police standard (Ă  gauche) et une police de caractĂšres agrandie (Ă  droite).

Recommandation n° 2 : sĂ©lectionner les couleurs avec circonspection.

Pour les personnes avec un handicap visuel, l’application doit garantir une bonne qualitĂ© de contrastes pour ĂȘtre performante. Il est recommandĂ© d’utiliser une palette de couleurs avec un nombre limitĂ© de nuances soigneusement sĂ©lectionnĂ©es. IdĂ©alement, on y trouvera des couleurs de premier plan et d’arriĂšre-plan prĂ©sentant un fort contraste les unes par rapport aux autres.

De nombreux utilisateurs et utilisatrices avec un acuitĂ© visuelle rĂ©duite utilisent le mode sombre pour Ă©viter l’éblouissement. Pour la mise en Ɠuvre, le team chargĂ© du dĂ©veloppement de l’appli Inclusive CFF a mis au point une sĂ©rie de couleurs sĂ©mantiques. Une couleur sĂ©mantique est toujours utilisĂ©e pour un usage prĂ©cis. Exemple: la couleur textBlack est rĂ©servĂ©e Ă  tous les textes ordinaires de l’appli. Un couple chromatique est ensuite attribuĂ© Ă  la couleur sĂ©mantique pour le mode clair et le mode sombre. La palette de couleurs n’est ainsi dĂ©finie qu’une seule fois et sera systĂ©matiquement appliquĂ©e de la mĂȘme maniĂšre dans toute l’application.

SwiftUI

Text(“Bern”)
    .foregroundColor(SBBColor.textBlack)

Flutter

Text(
    ‘Bern’,
    style: Theme.of(context).textTheme.bodyText1
        .copyWith(color: SBBColors.textBlack),
);
L’image reprĂ©sente deux Ă©crans de l’appli Inclusive CFF au contenu identique, l’un en affichage standard, l’autre en mode sombre. Il s’agit de la vue standard des prochains dĂ©parts disponible dans l’onglet «Gare».
Illustration 4: que ce soit en mode clair (à gauche) ou en mode sombre (à droite), les couleurs sémantiques prédéfinies garantissent une bonne qualité de contrastes.

Recommandation n° 3 : optimiser l’affichage pour les lecteurs d’écran.

Se familiariser avec les lecteurs d’écran.

VoiceOver et TalkBack sont d’autres Ă©lĂ©ments importants Ă  prendre en compte lors de la programmation d’une appli accessible aux personnes en situation de handicap. En tant que dĂ©veloppeur ou dĂ©veloppeuse, il est conseillĂ© d’utiliser soi-mĂȘme rĂ©guliĂšrement les lecteurs d’écran et de les configurer sous la forme de raccourcis sur son propre appareil. Cela permet d’avoir une idĂ©e concrĂšte de ce qui est vĂ©ritablement important pour garantir une bonne utilisation de l’application. À cet Ă©gard, il est recommandĂ© de prendre Ă©galement en compte les feed-back des utilisateurs et utilisatrices tests, ces personnes maĂźtrisant parfaitement l’usage du smartphone avec leur handicap.

Masquer les informations visuelles non essentielles.

VoiceOver et TalkBack lisent Ă  haute voix chacun des Ă©lĂ©ments visuels affichĂ©s sur l’écran. Mais cette fonctionnalitĂ© n’est pas toujours utile, notamment lorsqu’une appli a souvent recours Ă  des symboles ou Ă  des images pour illustrer le texte. La rĂ©pĂ©tition ainsi engendrĂ©e est superflue pour les personnes utilisant un lecteur d’écran. Il convient donc, dans ce cas, de masquer ce type d’informations.

SwiftUI

Image(”train-small”)
    .accessibilityHidden(true)

Flutter

Image.asset(
    Images.trainSmall,
    excludeFromSemantics: true,
)

Fournir des textes mieux adaptĂ©s aux lecteurs d’écran.

Souvent, l’information proprement dite ne devient claire qu’une fois ses diffĂ©rents Ă©lĂ©ments assemblĂ©s. Il est donc important d’associer ces donnĂ©es entre elles pour les lecteurs d’écran Ă©galement.

Information ligne par ligneInformations combinées
“12:39”
“12:40”
“Flawil”
“12:39, 12:40, Flawil, 
”
Sur cette image, deux Ă©crans de l’appli Inclusive CFF sont de nouveau reprĂ©sentĂ©s avec cette fois le focus du lecteur d’écran illustrĂ© par un cadre. Sur l’écran de gauche, seule l’heure (d’arrivĂ©e Ă  Flawil) est encadrĂ©e. Sur l’écran de droite, l’ensemble de l’information est encadrĂ© avec les heures d’arrivĂ©e et de dĂ©part, l’arrĂȘt, la voie d’arrivĂ©e et le cĂŽtĂ© de la descente. En d’autres termes, l’écran de droite place le focus sur tout le bloc de texte qui sera ainsi lu comme une entitĂ© Ă  part entiĂšre.

SwiftUI

Group {
    Text("12:39")
    Text("12:40")
    

}.accessibilityElement(children: .combine)

Flutter

MergeSemantics(
    child: Column(
        children: const <Widget>[
            Text('12:39'),
            Text('12:40'),
            

        ],
    ),
),

Un design est considĂ©rĂ© intelligent lorsqu’il fournit un contexte aux informations reprĂ©sentĂ©es sans le mentionner explicitement. L’écran ci-dessous en donne un exemple: au vu de l’ordre d’affichage des donnĂ©es, on peut en dĂ©duire que le train arrive Ă  Flawil Ă  12h39 et en repart Ă  12h40. Ces informations ne sont toutefois pas explicitement communiquĂ©es par le biais de textes. Pour les personnes utilisant un lecteur d’écran, ces corrĂ©lations visuelles font dĂ©faut. On ajoutera donc des Ă©lĂ©ments de liaison sous la forme de textes supplĂ©mentaires.

AvantAprĂšs
“12:39, 12:40, Flawil,  ”« Flawil, arrivĂ©e Ă  12h39, dĂ©part Ă  12h40, voie n° 2, descendre Ă  gauche »

Mais pour ce faire, l’ajout d’un simple attribut au code ne suffit pas. Il est de ce fait conseillĂ© de configurer un TextFormatter dĂ©fini par l’utilisateur·trice, lequel prendra en charge la mise Ă  disposition de textes pertinents.

SwiftUI

Group {
    

}
    .accessibilityLabel(Text(TextFormatter.stopStation(for: stopStation).voiceover))

Flutter

Semantics(
    value: createSemantics(stopStation),
    child: 
,
)

Pour accĂ©der plus rapidement au contenu souhaitĂ©, les lecteurs d’écran permettent la navigation de titre en titre. Ceux-ci doivent donc ĂȘtre identifiĂ©s en consĂ©quence dans le code.

SwiftUI

Text(”Einstellungen")
    .accessibilityAddTraits(.isHeader)

Flutter

Semantics(
    header: true,
    child: Text('Einstellungen'),
)

Bien que les lecteurs d’écran soient trĂšs performants, tant sous iOS que sous Android, il est parfois nĂ©cessaire de leur donner un coup de pouce. C’est notamment le cas avec les horaires affichĂ©s par dĂ©faut de maniĂšre peu comprĂ©hensible.

SwiftUI

Text(trainConnection.departureTime)
    .accessibilityValue(DateFormatter.hourMinuteVoiceoverTime.string(from: trainConnection.departureTime))

Identifier les cas oĂč VoiceOver et TalkBack ne sont pas parfaits demande la rĂ©alisation de tests rĂ©guliers par tous les membres du team de dĂ©veloppement.

En résumé.

Concevoir une application accessible n’est pas si complexe dĂšs lors que les principes essentiels de l’accessibilitĂ© numĂ©rique sont connus et pris en considĂ©ration. Il est important d’intĂ©grer ces principes dĂšs la phase de conception et de sensibiliser le team de dĂ©veloppement en consĂ©quence. Le travail de programmation supplĂ©mentaire sera ainsi minime. En outre, l’application s’adressera dĂšs son lancement Ă  un public potentiellement plus large, dans la mesure oĂč les personnes en situation de handicap pourront Ă©galement l’utiliser de maniĂšre intuitive. L’accessibilitĂ© numĂ©rique offre un voyage passionnant et instructif Ă  forte valeur ajoutĂ©e, aussi bien pour les utilisateur·trice·s que pour les teams de dĂ©veloppement.

Information à propos des auteur·e·s

Ce texte a Ă©tĂ© publiĂ© pour la premiĂšre fois en aoĂ»t 2020, en anglais, sur le blog Medium de l’AppBakery des CFF. La prĂ©sente version a Ă©tĂ© actualisĂ©e et remaniĂ©e.

Reto Allemann travaille en tant que Product Owner de l’appli Inclusive CFF. Il est en outre responsable de l’innovation et accompagne les teams dans le cadre d’organisations de travail agiles.

Nicolas Brunner a occupĂ© jusqu’en 2022 la fonction de dĂ©veloppeur iOS de l’appli Inclusive CFF. En aoĂ»t 2020, il a par ailleurs publiĂ© la version de base de cet article dans un blog paru sur Medium.

Jeanne Fleury travaille depuis 2022 en qualitĂ© de dĂ©veloppeuse iOS de l’appli Inclusive CFF.

Les dĂ©veloppeur·euse·s de l’appli Inclusive CFF travaillent pour le compte de l’AppBakery, une agence interne aux CFF chargĂ©e de crĂ©er des solutions innovantes Ă  partir de nouvelles technologies.