
MCP Server : Implémenter un serveur Model Context Protocol en TypeScript
Découvrez comment créer un serveur MCP en TypeScript à l'aide du SDK officiel. Apprenez à fournir un contexte riche aux LLMs.
Sommaire
•
Introduction aux notions d'accessibilité d'une barre de recherche
•
Le design minimaliste : un risque pour l’accessibilité ?
•
La barre de recherche pensée pour l’accessibilité universelle
•
Design minimaliste et accessibilité : le bon compromis
•
Comparatif
•
Conclusion : concevoir pour tous les profils d’utilisateurs
Sur de nombreux sites web, la barre de recherche est un composant d'interface essentiel.
Pourtant, mal conçue, elle peut devenir un véritable obstacle pour les utilisateurs qui dépendent des technologies d'assistance ou rencontrent des difficultés cognitives, motrices ou visuelles.
Dans cet article, je vous propose un tour d’horizon clair et concret :
Objectif : dépasser la simple conformité pour viser une accessibilité universelle, au service de toutes et tous.
Le minimalisme est une tendance forte du design web.
Épuré, élégant, il cherche à aller à l’essentiel, parfois jusqu’à effacer certains repères pourtant essentiels à l’accessibilité.
Dans la barre de recherche, cela se traduit souvent par :
Elle illustre parfaitement cette approche minimaliste, avec ses forces et ses points faibles en matière d’accessibilité.
<form>
natif, garantissant une navigation au clavier efficace.aria-label
, facilitant leur utilisation avec les technologies d'assistances.Ces choix de conception minimaliste, s'ils peuvent paraître élégants visuellement, présentent des défis réels pour l'accessibilité.
Minimalisme et accessibilité
Même si le minimalisme offre une esthétique épurée, il est essentiel de maintenir des repères visuels et textuels accessibles afin d'assurer une expérience utilisateur inclusive.
Pour garantir l’accessibilité de votre barre de recherche, commencez par les bases solides du HTML sémantique.
<form role="search" method="get" action="/recherche"> <label for="search-input">Rechercher sur le site :</label> <input type="search" id="search-input" name="q" placeholder="Exemple : accessibilité numérique" autocomplete="search" /> <button type="submit">Rechercher</button> </form>
Ce modèle est inclusif pour :
Astuce
Ajoutez l’attribut autocomplete="search"
pour améliorer l’expérience utilisateur et bénéficier des suggestions natives des navigateurs.
"use client";
import React, { useState, useCallback } from "react";
import { Box, InputBase, Button, Typography } from "@mui/material";
import SearchIcon from "@mui/icons-material/Search";
import { useRouter } from "next/navigation";
export default function AccessibleSearchBar() {
const [searchTerm, setSearchTerm] = useState("");
const router = useRouter();
const handleSubmit = useCallback(
(event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (searchTerm.trim()) {
router.push(`/recherche?q=${encodeURIComponent(searchTerm.trim())}`);
}
},
[router, searchTerm]
);
return (
<Box
component="form"
onSubmit={handleSubmit}
role="search"
aria-label="Recherche sur le site"
sx={{
p: "8px 12px",
display: "flex",
alignItems: "center",
width: "100%",
bgcolor: "background.paper",
borderRadius: 50,
boxShadow: 1,
mt: 5,
}}
>
<Typography component="label" htmlFor="search" sx={{ mr: 1 }}>
Rechercher :
</Typography>
<InputBase
id="search"
name="search"
placeholder="Tapez votre recherche ici"
inputProps={{ "aria-label": "Champ de recherche" }}
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
sx={{ flex: 1, borderBottom: "1px solid #ccc", px: 1 }}
/>
<Button
type="submit"
variant="contained"
color="primary"
startIcon={<SearchIcon />}
sx={{ ml: 1, borderRadius: 50 }}
>
Rechercher
</Button>
</Box>
);
}
Bonne nouvelle : minimalisme et accessibilité peuvent coexister, à condition de bien préparer la structure de votre composant.
L’idée est simple : conserver la structure accessible dans le code, même si certains éléments sont visuellement discrets ou masqués.
<form role="search" method="get" action="/recherche"> <label for="search-input" class="sr-only">Rechercher sur le site</label> <input type="search" id="search-input" name="q" placeholder="Rechercher..." /> <button type="submit"> <span class="sr-only">Rechercher</span> 🔍 </button> </form>
La classe sr-only
(abréviation de screen-reader only) permet de masquer visuellement du texte tout en le laissant lisible par les technologies d’assistance, comme les lecteurs d’écran.
Contrairement à des propriétés CSS comme display: none;
ou visibility: hidden;
, qui cachent totalement le contenu, la classe sr-only
utilise des techniques CSS spécifiques pour retirer le texte de l’affichage sans l’exclure de la lecture par les aides techniques.
Par exemple, voici un style robuste recommandé :
.sr-only { border: 0 !important; clip: rect(1px, 1px, 1px, 1px) !important; -webkit-clip-path: inset(50%) !important; clip-path: inset(50%) !important; height: 1px !important; overflow: hidden !important; padding: 0 !important; position: absolute !important; width: 1px !important; white-space: nowrap !important; }
sr-only
), mais reste accessible aux technologies d’assistance."use client";
import React, { useState, useCallback } from "react";
import { Box, InputBase, IconButton } from "@mui/material";
import SearchIcon from "@mui/icons-material/Search";
import { useRouter } from "next/navigation";
export default function AccessibleSearchBar() {
const [searchTerm, setSearchTerm] = useState("");
const router = useRouter();
const handleSubmit = useCallback(
(event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (searchTerm.trim()) {
router.push(`/recherche?q=${encodeURIComponent(searchTerm.trim())}`);
}
},
[router, searchTerm]
);
return (
<Box
component="form"
onSubmit={handleSubmit}
role="search"
aria-label="Recherche sur le site"
sx={{
p: "2px 4px",
display: "flex",
alignItems: "center",
width: "100%",
bgcolor: "background.paper",
borderRadius: 50,
}}
>
<InputBase
id="search"
name="search"
placeholder="Rechercher..."
inputProps={{ "aria-label": "Rechercher sur le site" }}
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
sx={{
ml: 1,
flex: 1,
"& input::placeholder": { color: "#444", opacity: 1 },
}}
/>
<IconButton
type="submit"
color="primary"
aria-label="Rechercher"
sx={{
bgcolor: "primary.main",
color: "white",
"&:hover": { bgcolor: "primary.dark" },
}}
>
<SearchIcon />
</IconButton>
</Box>
);
}
<Box component="form">
.aria-label
: contrairement à la version HTML qui utilise une étiquette masquée (sr-only
), cette implémentation React/MUI repose sur l’attribut aria-label
pour fournir un intitulé de champ de formulaire aux technologies d’assistance.aria-label
explicite : l’icône seule ne suffit pas, mais grâce à l’attribut aria-label="Rechercher"
, le bouton est compréhensible par les technologies d'assistances.Bon à savoir
Dans cette version React, nous n’avons pas ajouté d’étiquette masquée comme dans l’exemple HTML classique. Pour autant, l’attribut aria-label sur le champ de saisie et sur le bouton permet d’assurer une restitution correcte par les technologies d’assistance. Cette solution est parfaitement valide tant que le aria-label
est bien rédigé et suffisamment descriptif pour informer sur la fonction du champ et du bouton.
Astuce complémentaire
Pour améliorer encore l’accessibilité, vous pouvez utiliser les hooks MUI pour gérer le focus visuel, ou intégrer les annonces de résultats dynamiques via aria-live
.
Bon à savoir
Même avec un framework JavaScript moderne, privilégiez toujours la sémantique HTML et enrichissez-la progressivement avec des rôles et attributs ARIA seulement lorsque nécessaire.
Attention toutefois
Même avec ces bonnes pratiques, le design minimaliste présente des limites pour certains publics :
Attention
Un minimalisme accessible existe, mais il demande une rigueur de conception pour éviter les fausses bonnes idées — par exemple, supprimer l’étiquette de champ de formulaire au profit du seul placeholder.
Pour finir, voici un exemple concret de deux barres de recherche que nous avons vues ensemble :
En haut, la version minimaliste : épurée, discrète, mais avec des repères réduits.
En bas, la version avec une étiquette visible et un bouton explicite, plus rassurante pour l’ensemble des utilisateurs.
Et vous, laquelle pensez-vous être la plus compréhensible pour le plus grand nombre ?
La barre de recherche est un élément central de navigation.
Sa conception mérite plus que la simple conformité réglementaire : elle doit garantir une expérience fluide pour tous les utilisateurs.
Retenez ceci :
À retenir
Peu importe la solution que vous adoptez, retenez que l’accessibilité ne bride pas la créativité. Au contraire, elle enrichit vos interfaces pour les rendre plus robustes, inclusives et pérennes.
RGAA 4.1 — Référentiel général d’amélioration de l’accessibilité
Les critères précis appliqués dans cet article (intitulé de champ de formulaire, saisie assistée, ordre de tabulation, etc.)
La Lutine du Web — Julie Moynat
Le vaste monde des alternatives textuelles : le texte masqué en CSS
Excellente ressource pour comprendre l’utilisation et les bonnes pratiques autour de .sr-only
.
Access42 — Ressources sur l’accessibilité numérique
Bonnes pratiques et exemples de composants accessibles.
Design System de l’État Français (DSFR) — Barre de recherche
Exemples de mise en œuvre de composants accessibles dans des environnements gouvernementaux.
Auteur(s)
Marie Gautron
Astronaute développeuse JS 🚀 | En mission pour un web accessible et inclusif, pour toutes et tous
Vous souhaitez en savoir plus sur le sujet ?
Organisons un échange !
Notre équipe d'experts répond à toutes vos questions.
Nous contacterDécouvrez nos autres contenus dans le même thème
Découvrez comment créer un serveur MCP en TypeScript à l'aide du SDK officiel. Apprenez à fournir un contexte riche aux LLMs.
Découvrez comment créer un plugin ESLint en TypeScript avec la nouvelle configuration "flat config" et publiez-le sur npm.
L'Anchor positioning API est arrivée en CSS depuis quelques mois. Expérimentale et uniquement disponible à ce jour pour les navigateurs basés sur Chromium, elle est tout de même très intéressante pour lier des éléments entre eux et répondre en CSS à des problématiques qui ne pouvaient se résoudre qu'en JavaScript.