Le WordPress d'aujourd'hui, décodé pour les développeurs

Blocs Gutenberg

useResizeObserver ajuste l’aperçu d’un bloc à la largeur de son conteneur

Un bloc placé dans une colonne étroite n'a pas la même largeur qu'un bloc en pleine page, même sur le même écran. useResizeObserver réagit au conteneur réel, pas à la fenêtre.

Par WordPress Développement • 17 février 2022 • 4 min de lecture • Aucun commentaire
useResizeObserver ajuste l'aperçu d'un bloc à la largeur de son conteneur

Un même bloc « grille de statistiques » posé en pleine largeur d’une page affiche quatre colonnes confortablement lisibles. Le même bloc, une fois placé à l’intérieur d’une colonne étroite d’un bloc core/columns à trois volets, doit idéalement basculer sur une seule colonne pour rester lisible, alors même que l’écran de l’ordinateur du rédacteur n’a pas changé de taille entre les deux cas.

Ce constat révèle une limite du hook useViewportMatch, vu dans un précédent article : il réagit à la taille simulée de l’écran dans l’éditeur, pas à la largeur réelle du conteneur qui accueille le bloc. Le hook useResizeObserver, également fourni par @wordpress/compose, comble précisément ce manque.

Étape 1 : ce que résout ce hook

useResizeObserver s’appuie sur l’API native ResizeObserver du navigateur pour mesurer la largeur (et la hauteur) réellement disponible pour un élément donné, indépendamment de la taille de l’écran ou de la fenêtre. C’est exactement ce qu’il faut pour un bloc dont l’apparence doit s’adapter au conteneur qui l’accueille, qu’il s’agisse d’une colonne étroite, d’une barre latérale, ou d’un widget.

Étape 2 : mettre en place le hook dans le composant Edit

L'essentiel à retenir : Réagit à la largeur réelle du conteneur, pas à la taille de l'écran ; Retourne un élément de mesure à insérer et une largeur observée ; Se combine avec useViewportMatch pour les cas mixtes
import { useResizeObserver } from '@wordpress/compose';

function Edit() {
    const [ elementMesure, tailleObservee ] = useResizeObserver();
    const estEtroit = tailleObservee.width && tailleObservee.width < 400;

    return (
        <div className="grille-statistiques">
            { elementMesure }
            { estEtroit ? <StatistiquesEnColonne /> : <StatistiquesEnGrille /> }
        </div>
    );
}

Le hook retourne un tableau à deux éléments : un élément React à insérer une seule fois dans le rendu (généralement invisible, chargé de la mesure), et un objet contenant la largeur et la hauteur observées, initialement à null tant que la première mesure n’a pas encore eu lieu.

Étape 3 : gérer l’état initial avant la première mesure

Un point d’attention fréquent concerne le rendu avant que la première mesure ne soit disponible. Sans traitement particulier, un bloc peut afficher brièvement sa version « pleine largeur » avant de basculer vers la version étroite dès que la mesure arrive, produisant un effet de saut visuel désagréable à l’ouverture de l’éditeur :

const [ elementMesure, tailleObservee ] = useResizeObserver();

if ( null === tailleObservee.width ) {
    return <>{ elementMesure }<Placeholder /></>;
}

Afficher un composant Placeholder neutre pendant cette phase initiale évite ce saut visuel perceptible, en particulier sur des blocs dont le rendu diffère fortement selon la largeur mesurée.

Étape 4 : combiner avec useViewportMatch pour les cas mixtes

Certains blocs ont besoin des deux informations simultanément : la largeur du conteneur pour la disposition interne, et le mode d’aperçu de l’éditeur pour, par exemple, masquer une fonctionnalité entière sur mobile quel que soit le conteneur :

import { useResizeObserver, useViewportMatch } from '@wordpress/compose';

function Edit() {
    const [ elementMesure, tailleObservee ] = useResizeObserver();
    const editeurMobile = useViewportMatch( 'small', '<' );
    const conteneurEtroit = tailleObservee.width < 400;

    const disposition = editeurMobile || conteneurEtroit ? 'colonne' : 'grille';

    return (
        <div>
            { elementMesure }
            <Statistiques disposition={ disposition } />
        </div>
    );
}

Coût et limites à connaître

  • ResizeObserver déclenche un nouveau rendu à chaque changement de taille détecté : un bloc très lourd ne doit pas recalculer un traitement coûteux à chaque appel, une mémoïsation via useMemo reste recommandée pour tout calcul non trivial.
  • Le hook ne fonctionne que côté éditeur : le rendu final côté front doit s’appuyer sur des media queries CSS classiques pour un comportement équivalent visible par les visiteurs du site.
  • Un conteneur dont la largeur oscille rapidement (animation en cours, par exemple) peut générer une cascade de rendus : un léger anti-rebond (debounce) protège contre ce cas rare mais réel.

Sur les blocs composites destinés à être insérés dans des colonnes variables, on considère désormais useResizeObserver comme un prérequis, au même titre que la déclaration de supports.align.

En résumé

useResizeObserver répond à un besoin que useViewportMatch ne couvre pas : réagir à la largeur réelle du conteneur d’un bloc, quelle que soit la taille de l’écran. Les deux hooks se complètent plutôt qu’ils ne se concurrencent, chacun répondant à une source de variation différente dans l’éditeur.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi