Les fiches d'aperçu fournissent un aperçu interactif du contenu lorsqu'un utilisateur s'intéresse à un lien (en le survolant ou en le sélectionnant). Il est présenté aux utilisateurs avant qu'ils ne naviguent, et leur fournit le contenu dont ils ont besoin ou les aide à vérifier que le lien contiendra le contenu qu'ils recherchent.
Si vous avez besoin d'info-bulles en texte brut non interactives plutôt que d'aperçus de liens structurés, consultez Afficher une info-bulle au survol.
1. Déclencher la fiche informative
Utilisez l'API Interest Invokers pour déclencher la fiche informative. Cela garantit que la carte s'affiche à la fois au survol et au focus, et gère automatiquement le câblage d'accessibilité.
- Ajoutez l'attribut
popover="hint"à votre conteneur de carte. Utilisezhintpour éviter de fermer les menus popover non liés qui pourraient être ouverts. - Ajoutez l'attribut
interestforau lien de déclenchement, en pointant vers l'idde la fiche.
<a href="/article" interestfor="article-preview">Article title</a>
<!-- The `id` must match the `interestfor` value on the trigger. -->
<div id="article-preview" popover="hint" class="hovercard">
<h2>The buzz on hummingbirds</h2>
<p class="byline">By Delphi Aguilar</p>
<div>
<img src="bird.jpg" alt="A vibrant hummingbird">
<p>Brief summary of the article...</p>
</div>
</div>
Il n'est pas nécessaire d'inclure un lien supplémentaire vers le contenu dans la fiche d'information, car il est redondant avec le lien de déclenchement.
Accessibilité intégrée à interestfor
Lorsque vous utilisez interestfor, le navigateur gère automatiquement la connexion à la technologie d'assistance :
- Sémantique implicite : une cible avec
popover="hint"obtient un rôle minimal implicite detooltip. NE DÉFINISSEZ PASrole="tooltip"vous-même. - Association implicite : le navigateur associe implicitement l'élément source à la cible via
aria-describedbylorsque la cible est du texte brut, ou viaaria-detailslorsque la cible contient du contenu interactif. N'AJOUTEZ PASaria-describedbyouaria-detailsau déclencheur. - Contenu interactif : étant donné que l'association passe à
aria-detailssi nécessaire, la cible PEUT contenir du contenu interactif (par exemple, un lien dans une "fiche d'intérêt").
2. Positionnement avec le positionnement d'ancrage
Positionnez la fiche d'info-bulle par rapport à son déclencheur à l'aide du positionnement des ancres CSS. Lorsque vous utilisez interestfor, le déclencheur devient une ancre implicite pour le popover.
[popover].hovercard {
/* Position the card below the trigger, aligned with its inline-start edge
and spanning toward the inline-end, flipping if it overflows the viewport. */
position-area: block-end span-inline-end;
position-try-fallbacks: flip-block, flip-inline;
}
3. Animer l'entrée et la sortie
Par défaut, l'intérêt est affiché et perdu pour les utilisateurs du clavier et de la souris avec un délai d'une demi-seconde. Cela empêche l'ouverture du popover ciblé lorsque vous parcourez une page à l'aide de la touche Tabulation ou que vous déplacez votre souris, et sa fermeture lorsque vous déplacez votre souris du déclencheur vers le popover. Pour ajuster le timing, utilisez la propriété CSS interest-delay.
[interestfor]{
/* Shorthand for interest-delay-start and interest-delay-end */
interest-delay: 0.2s 0.1s;
}
Si les utilisateurs sont susceptibles de déclencher plusieurs popovers en succession rapide, définissez le délai initial sur 0s si un popover déclenché par l'intérêt est déjà ouvert.
:root:has(:interest-source) [interestfor] {
interest-delay-start: 0s;
}
Utilisez @starting-style pour définir l'animation d'entrée et transition-behavior: allow-discrete (ainsi que display et overlay) pour animer la sortie de la couche supérieure, en limitant les transitions derrière @media (prefers-reduced-motion: no-preference).
[popover].hovercard {
opacity: 0;
transform-origin: top;
}
[popover].hovercard:popover-open {
opacity: 1;
transform: translateY(0) scale(1);
}
@starting-style {
[popover].hovercard:popover-open {
opacity: 0;
transform: translateY(-10px) scale(0.95);
}
}
/* MANDATORY: Respect user preference for reduced motion by selectively applying transitions. */
@media (prefers-reduced-motion: no-preference) {
[popover].hovercard {
transition:
opacity,
transform,
display,
overlay;
transition-duration: 0.4s;
transition-behavior: allow-discrete;
}
}
4. FACULTATIF : Transition fluide vers la page suivante
Vous pouvez éventuellement utiliser les transitions de vue entre documents pour créer une animation de morphing fluide entre la fiche informative et la page de destination. Consultez Transitions cohérentes entre documents pour obtenir des conseils sur l'implémentation.
En attribuant des valeurs view-transition-name correspondantes aux éléments de la fiche d'information et à leurs équivalents sur la page suivante, le navigateur les animera tout au long de la navigation. Vous pouvez nommer plusieurs éléments (par exemple, des titres, des images, des signatures) pour créer un effet de morphing complexe et multi-éléments. Attribuez l'view-transition-name aux éléments du popover ouvert à l'aide de :popover-open, afin d'éviter de créer des view-transition-name en double ou de nécessiter des view-transition-name spécifiques aux liens.
/* Opt-in to cross-document transitions on both pages */
@view-transition {
navigation: auto;
}
/* Don't show transitions when loading this page */
::view-transition-group(*) {
animation-duration: 0s;
}
/* Assign names ONLY when the popover is open to ensure only the correct elements are selected. */
[popover]:popover-open {
view-transition-name: --hovercard;
view-transition-class: morph;
h2 {
view-transition-name: --title;
view-transition-class: morph;
}
img {
view-transition-name: --image;
view-transition-class: morph;
}
}
OBLIGATOIRE : Pour que la transition soit stable et ne clignote pas, la page de destination doit utiliser blocking="render" et <link rel="expect"> pour attendre que le contenu critique soit analysé avant d'afficher le premier frame.
<!-- On the destination page: -->
<head>
<!-- Block rendering until the hero image and title are parsed,
ensuring the view transition snapshot is taken at the right time. -->
<link rel="expect" href="#main-content" blocking="render">
</head>
<body>
<main id="main-content">
<h1>The buzz on hummingbirds</h1>
<img src="bird.jpg">
</main>
</body>
/* On the destination page: */
main {
view-transition-name: --hovercard;
view-transition-class: morph;
}
h1 {
view-transition-name: --title;
view-transition-class: morph;
}
img {
view-transition-name: --image;
view-transition-class: morph;
}
/* By default no transition */
::view-transition-group(*) {
animation-duration: 0s;
}
/* Short transition for morphing elements */
::view-transition-group(.morph) {
animation-duration: 0.4s;
}
/* Disable transition if no `old` view */
::view-transition-new(.morph):only-child {
animation-duration: 0s;
}
Stratégies de remplacement
Comme le déclencheur est un lien <a href="..."> standard, les navigateurs qui ne sont pas compatibles peuvent toujours naviguer au clic si vous choisissez de traiter la fiche d'aperçu comme une amélioration progressive. Lorsque la compatibilité entre navigateurs est requise pour les fiches informatives, chargez des polyfills de manière conditionnelle, si nécessaire.
Solutions de remplacement et compatibilité des navigateurs pour Popover
L'API Popover est principalement une amélioration progressive, mais ses comportements déterminants (promotion de la couche supérieure, fermeture par clic en dehors de l'élément et appel de popovertarget) n'ont pas d'équivalent CSS uniquement. Les anciens navigateurs ont besoin d'un polyfill ou d'un remplacement manuel si vous préférez ne pas en fournir.
Polyfill : pour que l'attribut popover soit compatible avec les anciens navigateurs, chargez @oddbird/popover-polyfill de manière conditionnelle. OBLIGATOIRE : Détectez la fonctionnalité en vérifiant la propriété popover sur HTMLElement.prototype, et chargez le polyfill uniquement lorsque la compatibilité native est manquante. Ne le chargez PAS de manière inconditionnelle.
Avec un bundler ou une carte d'importation :
// MANDATORY: Feature detect 'popover' on HTMLElement.prototype.
if (!("popover" in HTMLElement.prototype)) {
import("@oddbird/popover-polyfill");
}
Sans bundler, importez depuis un CDN dans un <script type="module"> :
<script type="module">
if (!("popover" in HTMLElement.prototype)) {
import("https://unpkg.com/@oddbird/popover-polyfill@latest/dist/popover.min.js");
}
</script>
Mise en garde concernant l'application de styles : le polyfill ne peut pas définir la véritable pseudo-classe :popover-open. Il applique donc une classe .\:popover-open à la place. OBLIGATOIRE : Combinez les deux avec :is() ou :where(), sinon les navigateurs qui ne disposent pas de :popover-open ignorent l'intégralité de la règle :
[popover]:is(:popover-open, .\:popover-open) {
display: block;
}
Vous pouvez également utiliser position: fixed pour une solution de remplacement sans polyfill et calculer manuellement les coordonnées via getBoundingClientRect(), ou vous appuyer sur le positionnement par défaut avec inset: auto si cela convient à votre cas d'utilisation.
Créations de remplacement et compatibilité des navigateurs pour les déclencheurs d'intérêt
Les déclencheurs d'intérêt doivent être polyfillés de manière conditionnelle à l'aide du package polyfill interestfor de NPM. Privilégiez le regroupement du polyfill plutôt que l'utilisation du CDN.
OBLIGATOIRE : Détectez la fonctionnalité en vérifiant la propriété interestForElement sur HTMLButtonElement.prototype, et chargez le polyfill uniquement lorsque la compatibilité native est manquante.
<script type="module">
if (!HTMLButtonElement.prototype.hasOwnProperty("interestForElement")) {
// CDN link only used for example, prefer bundling.
await import("https://unpkg.com/interestfor@latest");
}
</script>
Mises en garde concernant les polyfills CSS
Lorsque vous utilisez le polyfill, l'API CSS change légèrement pour compenser l'absence de compatibilité native avec les pseudo-classes et les propriétés :
- Pseudo-classes : le polyfill ne peut pas définir de vraies pseudo-classes
:interest-sourceet:interest-target. Il applique donc les classes.interest-sourceet.interest-targetà la place. OBLIGATOIRE : Combinez-les avec:is()pour prendre en charge les états natifs et polyfilled.
/* Styles to apply when the effect is being previewed */
:is(:interest-source, .interest-source) { /* ... */ }
:is(:interest-target, .interest-target) { /* ... */ }
- Propriétés CSS : pour
interest-delay,interest-delay-startetinterest-delay-end, le polyfill nécessite l'utilisation de variables CSS, car il ne peut pas lire directement les propriétés personnalisées dans tous les navigateurs.
/* Adjust the start and end delay for interest invokers */
[interestfor] {
--interest-delay-start: 0.2s;
interest-delay-start: var(--interest-delay-start);
--interest-delay-end: 0.1s;
interest-delay-end: var(--interest-delay-end);
}