Back

Créer des popovers accessibles avec CSS et JS modernes

Créer des popovers accessibles avec CSS et JS modernes

Les popovers présentent des informations contextuelles sans perturber le flux de travail de l’utilisateur—mais leur implémentation accessible reste un défi pour de nombreux développeurs. Que vous modernisiez du code legacy ou construisiez une bibliothèque de composants, comprendre la différence entre popovers, tooltips et modales est crucial pour créer la bonne expérience utilisateur.

Cet article couvre comment construire des popovers accessibles en utilisant CSS et JavaScript modernes, du positionnement dynamique à la navigation au clavier, tout en explorant les API natives du navigateur qui réduisent la complexité.

Points clés à retenir

  • Les popovers affichent du contenu riche et interactif qui persiste jusqu’à ce qu’il soit fermé, contrairement aux tooltips qui montrent de brefs indices au survol
  • L’API native Popover élimine la complexité JavaScript tout en fournissant des fonctionnalités d’accessibilité intégrées
  • Une gestion appropriée du focus et des attributs ARIA sont essentiels pour la navigation au clavier
  • Le positionnement dynamique garantit que les popovers restent visibles dans les limites de la fenêtre d’affichage

Comprendre les popovers vs. tooltips vs. modales

Les tooltips fournissent de brefs indices au survol, contenant généralement une seule ligne de texte. Ils disparaissent lorsque les utilisateurs déplacent leur curseur et ne peuvent pas contenir d’éléments interactifs.

Les popovers affichent un contenu plus riche—en-têtes, paragraphes, boutons ou formulaires. Ils restent visibles jusqu’à ce qu’ils soient explicitement fermés, permettant aux utilisateurs d’interagir à la fois avec le contenu du popover et la page en dessous.

Les modales créent une expérience focalisée en rendant l’arrière-plan inerte. Les utilisateurs doivent terminer l’interaction modale avant de retourner au contenu principal.

Exigences d’implémentation de base

Positionnement dynamique dans la fenêtre d’affichage

Les popovers modernes doivent s’adapter à l’espace d’écran disponible. Lorsqu’un popover s’étendrait au-delà du bord de la fenêtre d’affichage, il devrait se repositionner automatiquement :

const positionPopover = (trigger, popover) => {
  const triggerRect = trigger.getBoundingClientRect()
  const popoverRect = popover.getBoundingClientRect()
  
  let top = triggerRect.bottom + 8
  let left = triggerRect.left
  
  // Flip to top if insufficient space below
  if (top + popoverRect.height > window.innerHeight) {
    top = triggerRect.top - popoverRect.height - 8
    popover.classList.add('popover--top')
  }
  
  // Adjust horizontal position
  if (left + popoverRect.width > window.innerWidth) {
    left = window.innerWidth - popoverRect.width - 16
  }
  
  popover.style.top = `${top}px`
  popover.style.left = `${left}px`
}

Alignement de la flèche

Le CSS gère la flèche visuelle qui pointe vers l’élément déclencheur :

.popover::after {
  content: "";
  position: absolute;
  width: 12px;
  height: 12px;
  background: inherit;
  border: inherit;
  transform: rotate(45deg);
  top: -7px;
  left: 20px;
  border-bottom: 0;
  border-right: 0;
}

.popover--top::after {
  top: auto;
  bottom: -7px;
  transform: rotate(225deg);
}

Mécanismes de fermeture

Les popovers accessibles nécessitent plusieurs méthodes de fermeture :

// Click outside
document.addEventListener('click', (e) => {
  if (!popover.contains(e.target) && !trigger.contains(e.target)) {
    closePopover()
  }
})

// ESC key
document.addEventListener('keydown', (e) => {
  if (e.key === 'Escape' && isPopoverOpen) {
    closePopover()
    trigger.focus() // Return focus to trigger
  }
})

L’API native Popover

L’API Popover élimine une grande partie de la complexité JavaScript :

<button popovertarget="my-popover">Open Info</button>

<div id="my-popover" popover>
  <h3>Additional Information</h3>
  <p>This popover requires no JavaScript for basic functionality.</p>
  <button popovertarget="my-popover">Close</button>
</div>

Cette approche native gère automatiquement le positionnement, la fermeture et la gestion du focus. Pour une accessibilité améliorée, combinez-la avec l’élément <dialog> :

<dialog id="enhanced-popover" popover>
  <h2>Accessible Popover</h2>
  <p>Combining dialog with popover provides semantic meaning.</p>
  <button popovertarget="enhanced-popover">Close</button>
</dialog>

Comparaison entre solutions de bibliothèque et natives

Les bibliothèques traditionnelles comme Popper.js offrent des algorithmes de positionnement étendus mais ajoutent 15-30KB à votre bundle. L’API native Popover fournit :

  • Zéro JavaScript pour les fonctionnalités de base
  • Fonctionnalités d’accessibilité intégrées
  • Gestion automatique du focus
  • Positionnement optimisé par le navigateur

Pour des exigences de positionnement complexes, les bibliothèques restent précieuses. Pour les cas d’usage standard, les solutions natives réduisent considérablement la complexité.

Considérations d’accessibilité essentielles

Attributs ARIA

Lors de la construction de popovers personnalisés sans l’API native :

<button 
  aria-expanded="false"
  aria-controls="custom-popover"
  aria-haspopup="dialog">
  Open Popover
</button>

<div 
  id="custom-popover"
  role="dialog"
  aria-labelledby="popover-title"
  aria-modal="false">
  <h2 id="popover-title">Popover Title</h2>
  <!-- Content -->
</div>

Gestion du focus

Un ordre de focus approprié garantit que les utilisateurs de clavier peuvent naviguer efficacement :

const focusableElements = popover.querySelectorAll(
  'a, button, input, textarea, select, [tabindex]:not([tabindex="-1"])'
)

// Trap focus within popover
popover.addEventListener('keydown', (e) => {
  if (e.key === 'Tab') {
    const firstElement = focusableElements[0]
    const lastElement = focusableElements[focusableElements.length - 1]
    
    if (e.shiftKey && document.activeElement === firstElement) {
      e.preventDefault()
      lastElement.focus()
    } else if (!e.shiftKey && document.activeElement === lastElement) {
      e.preventDefault()
      firstElement.focus()
    }
  }
})

Prévention du défilement en arrière-plan

Le CSS seul peut empêcher le défilement en arrière-plan lors de l’utilisation de l’API native :

body:has(dialog[popover]:popover-open) {
  overflow: hidden;
}

Conclusion

Construire des popovers accessibles nécessite d’équilibrer les besoins des utilisateurs avec l’implémentation technique. L’API native Popover simplifie le développement tout en maintenant les standards d’accessibilité, bien que les solutions personnalisées restent nécessaires pour les interactions complexes.

Concentrez-vous sur la navigation au clavier, l’implémentation appropriée d’ARIA et des modèles de fermeture clairs. Que vous utilisiez des API natives ou construisiez des composants personnalisés, l’accessibilité doit guider vos décisions d’implémentation—garantissant que vos popovers fonctionnent pour tous les utilisateurs, quelle que soit la façon dont ils interagissent avec votre interface.

FAQ

Utilisez l'API native Popover pour les implémentations standard car elle fournit une accessibilité intégrée et ne nécessite pas de JavaScript. Choisissez des bibliothèques comme Popper.js uniquement lorsque vous avez besoin d'une logique de positionnement complexe ou devez prendre en charge des navigateurs plus anciens qui ne supportent pas l'API native.

Les tooltips montrent un texte bref au survol et disparaissent automatiquement, nécessitant seulement des labels ARIA simples. Les popovers contiennent des éléments interactifs, nécessitent une gestion du focus, plusieurs méthodes de fermeture et des attributs ARIA appropriés incluant role dialog et aria-modal pour s'assurer que les lecteurs d'écran les annoncent correctement.

L'API Popover est supportée dans Chrome 114+, Edge 114+ et Safari 17+. Le support Firefox est en développement. Vérifiez toujours la compatibilité actuelle des navigateurs et fournissez des solutions de repli pour les navigateurs non supportés en utilisant la détection de fonctionnalités avant l'implémentation en production.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay