# Antipatterns de bouton fantôme : un div cliquable sans rôle ni focus

> Un simple élément div, stylé comme un bouton et cliquable en JavaScript, reste invisible pour le clavier et les lecteurs d'écran. Pourquoi le remplacer par un vrai bouton HTML règle tout.

- Auteur : WordPress Développement
- Publié le : 2023-10-03
- Mis à jour le : 2023-10-03
- Catégorie : Accessibilité
- URL : https://www.wpmoderne.fr/accessibilite/antipattern-bouton-fantome-div-cliquable/

## L’essentiel

- Un div n'obtient jamais le focus ni de rôle par défaut
- Trois attributs à ajouter manuellement pour compenser
- Remplacer par un bouton natif évite chaque compensation

Un rectangle stylé en CSS avec une couleur de fond, une ombre portée légère, un curseur en forme de main au survol, et un gestionnaire d'évènement `click` en JavaScript : voilà à quoi ressemble le bouton fantôme le plus fréquent, observé sur de nombreux sites construits vite, souvent sous la pression d'un délai de livraison serré. Visuellement indiscernable d'un vrai bouton, ce motif de conception échoue pourtant sur trois points fondamentaux dès qu'on retire la souris.

## Ce qu'on observe dans le code

Le code typique de ce bouton fantôme ressemble à ceci :

```
<div class="bouton-cta" onclick="validerFormulaire()">
  Envoyer ma demande
</div>
```

Rien dans cette ligne n'indique à une technologie d'assistance qu'il s'agit d'un élément interactif. Un `<div>` n'a, par défaut, aucun rôle sémantique particulier : un lecteur d'écran le traite comme un simple conteneur de texte, sans annoncer ni bouton ni action possible.

## Pourquoi c'est un problème, précisément

> L'essentiel à retenir : Un div n'obtient jamais le focus ni de rôle par défaut ; Trois attributs à ajouter manuellement pour compenser ; Remplacer par un bouton natif évite chaque compensation

Trois défauts s'accumulent sur ce type d'élément, chacun capable à lui seul de rendre l'action inaccessible :

- **Aucun rôle sémantique** : un lecteur d'écran ne l'annonce jamais comme « bouton », l'utilisateur ignore qu'une action est disponible à cet endroit ;
- **Aucun focus au clavier** : un `<div>` n'apparaît pas dans l'ordre de tabulation par défaut, impossible donc de l'atteindre sans souris ni écran tactile ;
- **Aucune activation au clavier** : même en forçant le focus, l'évènement `click` attaché en JavaScript ne se déclenche pas automatiquement avec les touches `Entrée` ou `Espace`, contrairement à un bouton natif.

## La compensation partielle, et ses limites

Il est possible de corriger ces trois défauts un par un, en ajoutant manuellement les attributs correspondants :

```
<div class="bouton-cta"
     role="button"
     tabindex="0"
     onclick="validerFormulaire()"
     onkeydown="if (event.key === 'Enter' || event.key === ' ') validerFormulaire()">
  Envoyer ma demande
</div>
```

Cette version corrigée fonctionne, mais elle demande quatre ajouts distincts (`role`, `tabindex`, gestion de `Entrée`, gestion d'`Espace`) pour reproduire un comportement qu'un élément natif offre sans aucune configuration. Elle oublie en général aussi un détail plus subtil : la touche `Espace` doit empêcher le défilement de la page par défaut, avec `event.preventDefault()`, une nuance presque systématiquement absente des corrections artisanales de ce type.

## La correction qui règle tout d'un coup

```
<button type="button" class="bouton-cta" onclick="validerFormulaire()">
  Envoyer ma demande
</button>
```

Un élément `<button>` natif possède, sans aucune configuration supplémentaire : le rôle `button` annoncé automatiquement, sa place native dans l'ordre de tabulation, l'activation par `Entrée` et par `Espace`, et même l'état désactivé géré nativement via l'attribut `disabled`, sans qu'aucune ligne de JavaScript supplémentaire ne soit nécessaire. Le style visuel, lui, reste entièrement personnalisable en CSS, un bouton natif ne dictant aucune apparence imposée.

```
.bouton-cta {
    background: #0b4f8a;
    color: #fff;
    padding: 12px 24px;
    border: none;
    border-radius: 6px;
    font: inherit;
    cursor: pointer;
}
```

## Un raccourci de vérification rapide

Un test suffit à repérer ce défaut sur un site existant : parcourir la page uniquement au clavier avec la touche `Tab` et observer si tous les éléments qui déclenchent une action visible reçoivent bien le focus, avec un contour identifiable. Tout élément cliquable qui n'apparaît jamais dans ce parcours est, presque systématiquement, un bouton fantôme construit sur un `<div>` ou un `<span>`.

> La question à se poser avant d'écrire un gestionnaire de clic n'est jamais « quel élément stylé le mieux », mais « quel élément HTML porte déjà nativement le comportement attendu ».

## En résumé

Le bouton fantôme reste l'un des antipatterns les plus simples à corriger, précisément parce que la solution ne demande aucun ajout : elle demande de retirer un mauvais choix d'élément HTML pour le remplacer par celui prévu depuis toujours pour cet usage. Un `<button>` natif règle en une ligne ce que quatre attributs ARIA et deux gestionnaires d'évènement tentent, souvent imparfaitement, de reproduire.
