BrowserUX Blog

Développement Front-End

HTML CSS JS 🧩 UX

Fluidifier les transitions de page avec l’API View Transitions

CSS :focus accessibilité

Dans une époque où chaque détail compte dans l’expérience utilisateur, même les transitions entre pages peuvent faire la différence. L’API View Transitions, introduite récemment dans certains navigateurs modernes, permet de créer des animations fluides et synchronisées entre deux états du DOM. Elle facilite la continuité visuelle entre les pages ou composants d'une application web.

Combinée à quelques lignes de JavaScript et de CSS, on peut créer des effets visuels esthétiques comme une barre de chargement animée pendant les transitions.

I. Qu'est-ce que l'API View Transitions ?

L'API View Transitions est une fonctionnalité relativement récente introduite dans certains navigateurs Chromium, permettant d'animer les transitions entre deux états de l'interface utilisateur de manière fluide et native, sans avoir à recourir à des librairies JavaScript tierces ou des hacks CSS.

Elle est particulièrement utile pour améliorer la continuité visuelle dans les applications web, qu'elles soient de type MPA (Multi Page Application) ou SPA (Single Page Application).

1. La méthode

La clé de cette API est la méthode suivante :


document.startViewTransition(() => {
    // Ici, on effectue un changement d'état 
    // ou une modification du DOM
});

Cette méthode prend une fonction de callback qui est exécutée pour appliquer les changements à l’interface. Voici comment cela se déroule en coulisses :

  • 1. Capture de l'état initial ("old view") : avant d'exécuter la fonction, le navigateur prend un instantané de l'état actuel du DOM.
  • 2. Exécution du callback : là où le développeur modifie le contenu ou le layout (nouvelle page, nouveau composant, changement d'état...)
  • 3. Capture de l'état final ("new view") : une fois les changements appliqués, un nouvel instantané est pris.
  • 4. Calcul de la transition : pour chaque élément ayant un view-transition-name, le navigateur gère automatiquement l'animation de l'état "ancien" vers le "nouveau".

Cette approche permet non seulement de réaliser des transitions complexes, mais aussi de maintenir des performances optimales, car tout est géré au niveau du moteur de rendu du navigateur.

Un point fort de cette API est sa simplicité : il suffit d'étiqueter les bons éléments avec view-transition-name et de passer par startViewTransition pour automatiser l'effet.

On peut ainsi animer :

  • des changements de page complets (navigation MPA)
  • des apparitions/disparitions de composants (SPA)
  • des changements de thèmes (mode clair/sombre)
  • des changements de layout
  • des transitions entre vues ou états UI complexes

L'API View Transitions s'inscrit donc dans une tendance vers une web UX plus naturelle, plus fluide, et plus intégrée aux standards du navigateur.

2. Le rôle des pseudo-éléments ::view-transition-old et ::view-transition-new

Lorsqu'une transition est déclenchée via document.startViewTransition(), le navigateur capture les états "avant" et "après" de chaque élément qui participe à l'animation en se basant sur leur view-transition-name.

Pour chaque élément ainsi identifié, le moteur de rendu génère deux pseudo-éléments spéciaux, visibles uniquement pendant la transition :

  • ::view-transition-old(nom) : une image visuelle (ou "snapshot") de l'élément avant la transition. Il reflète son apparence initiale.
  • ::view-transition-new(nom) : une image de l'élément après la transition, reflétant son état final.

Ces pseudo-éléments sont empilés et positionnés par le navigateur pour créer un effet de superposition entre l'état initial et l'état final. Vous pouvez les cibler en CSS pour leur appliquer des animations personnalisées (translation, opacité, mise à l'échelle, flou, etc.).

Exemple : animation de fondu entre deux versions :


::view-transition-old(my-element),
::view-transition-new(my-element) {
    transition: opacity 0.5s ease;
}

::view-transition-old(my-element) {
    opacity: 1;
}

::view-transition-new(my-element) {
    opacity: 0;
}

Cette flexibilité donne un contrôle très fin sur la façon dont les éléments apparaissent et disparaissent pendant les transitions, permettant de créer des effets cinématographiques ou ludiques sans JavaScript supplémentaire.

⚠️ Attention : ces pseudo-éléments n'existent que pendant la durée de la transition. Ils ne peuvent pas être inspectés directement via les outils de développement classiques, sauf en activant certaines options expérimentales.

3. view-transition-name : identifiant de synchronisation

Pour que le navigateur sache quels éléments doivent être liés entre l'état "avant" et "après" d'une transition, il faut leur attribuer un identifiant commun : le view-transition-name. C'est cette valeur qui permet de dire : "cet élément est la même entité logique dans les deux versions du DOM, applique-lui une animation de transition".

Sans ce nom partagé, les éléments seraient traités comme totalement différents, et aucune transition ne serait appliquée.

Il existe deux façons d'attribuer ce nom :

1. Via le CSS (recommandé)

La méthode la plus claire et maintenable consiste à le faire via une règle CSS :


.page-loader {
    view-transition-name: page-loader;
}

Cela permet une définition centralisée et cohérente dans vos styles.

2. Via un attribut HTML (optionnel)

On peut également le définir directement dans l’HTML via un attribut natif :


<div view-transition-name="page-loader"></div>

Cela a le même effet, mais peut être utile dans certains contextes dynamiques ou lorsque vous générez du contenu sans CSS.

⚠️ Important : l’attribut HTML est facultatif. La valeur retenue par le navigateur est celle de la propriété CSS view-transition-name, qu’elle soit définie dans une feuille de style ou en ligne. L’attribut HTML ne fait que définir cette valeur à travers le CSS utilisateur implicite.

En pratique, tant que l’élément conserve le même nom de transition avant et après l’appel à startViewTransition(), il sera animé automatiquement par le navigateur. Cela ouvre la voie à des effets avancés entre écrans, composants ou thèmes.

II. Exemple pratique : une barre de chargement

Prenons l'exemple d'une barre de progression visible uniquement pendant la transition.

1. HTML

On peut mettre directement le containeur dans le html :


<div class="navigate-loader"></div>

On l'injecter depuis le JavaScript :


const navigateLoader = document.createElement('div');
navigateLoader.className = 'navigate-loader';
document.body.prepend(navigateLoader);

2. JavaScript

On va créer une fonction qui intercepte le clic sur un lien de navigation et effectue une transition de page en utilisant l'API View Transitions, suivie d'une navigation classique (hard reload). Elle va permettre une transition visuelle fluide entre des pages partageant des éléments avec le même view-transition-name.


function navigateWithTransition(e) {

On arrête l'exécution si l'API View Transitions n'est pas supportée :


if (!document.startViewTransition) return;

On empêche le comportement par défaut du lien pour gèrer la navigation manuellement :


e.preventDefault();

On extrait l'URL cible à partir du lien cliqué :


const url = e.currentTarget.href;

On démarre une animation de transition de vue :


document.startViewTransition(() => {

On retourne une promesse pour indiquer au navigateur quand effectuer la navigation :


return new Promise(resolve => {

On met à jour l'URL manuellement (rechargement complet de la page) :


window.location.href = url;

On résout immédiatement la promesse après avoir déclenché la navigation (la nouvelle page interrompt l'exécution du script) :


resolve();

Puis on attache le comportement de transition à tous les liens de nav :


document.querySelectorAll('.nav a').forEach(link => {
    link.addEventListener('click', navigateWithTransition);
});

Code complet :


function navigateWithTransition(e) {
    if (!document.startViewTransition) return;
    e.preventDefault();
    const url = e.currentTarget.href;

    document.startViewTransition(() => {
        return new Promise(resolve => {
            window.location.href = url;
            resolve();
        });
    });
}

document.querySelectorAll('.nav a').forEach(link => {
    link.addEventListener('click', navigateWithTransition);
});

3. CSS

Ce bloc de code CSS met en place une barre de chargement animée. Lorsqu’une transition est déclenchée, le navigateur génère deux représentations temporaires de cette barre : ::view-transition-old et ::view-transition-new. Ces pseudo-éléments sont stylisés pour apparaître comme une fine ligne de 4 pixels fixée en haut de l’écran, s’étendant sur toute la largeur.

Le fond utilise un dégradé linéaire horizontal qui passe d’une couleur de fond à une couleur secondaire, puis revient à la couleur de fond. Ce dégradé est ensuite animé avec une translation continue de gauche à droite, simulant un effet de progression infinie. L’animation loaderBar joue en boucle (infinite linear) avec une durée d’une seconde, créant une sensation de vitesse et de fluidité.


.navigate-loader {
    view-transition-name: navigate-loader;
}

::view-transition-old(navigate-loader),
::view-transition-new(navigate-loader) {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 4px;
    background: linear-gradient(
        90deg,
        #eaeaea 0%,
        #0e93f0 50%,
        #eaeaea 100%
    );
    animation: loaderBar 1s infinite linear;
    z-index: 9999;
}

@keyframes loaderBar {
    0% {
        transform: translateX(-100%);
    }
    100% {
        transform: translateX(100%);
    }
}

III. Conclusion

L’API View Transitions offre une méthode simple mais puissante pour créer des expériences utilisateur plus fluides. En liant JavaScript et CSS, vous pouvez mettre en scène vos interfaces avec des animations qui ont du sens, sans surcharge de code ou frameworks complexes. Idéal pour des interfaces modernes et dynamiques.

Avantages

  • Création d'effets natifs, fluides et sans bibliothèque externe.
  • Intégration simple dans les MPA ou SPA.
  • Hautement personnalisable avec CSS.

Limites

  • API encore récente, support partiel (pas de support Firefox).
  • Demande une bonne organisation du DOM et des noms de transitions.

À propos

Ce blog a été conçu comme une extension naturelle des projets de l'écosystème BrowserUX.

Il a pour objectif de fournir des ressources complémentaires, des astuces ciblées et des explications détaillées autour des choix techniques, des bonnes pratiques et des principes d’accessibilité qui structurent ces outils.

Chaque article ou astuce vient éclairer un aspect précis du front-end moderne (CSS, accessibilité, UX, performance…), avec une volonté claire : expliquer le pourquoi derrière chaque règle pour encourager une intégration plus réfléchie et durable dans vos projets.