Définissez le graphique une seule fois dans un <symbol> SVG, puis référencez son ID avec <use> dans chaque SVG visible. Donnez à chaque instance sa propre taille et laissez CSS organiser le reste de la page. Structure d’un document SVG.

Ce tutoriel s’adresse à toute personne qui modifie une page HTML sur un Mac et souhaite afficher le même petit graphique à côté de plusieurs libellés textuels. L’exemple complet utilise des tuiles synthétiques, du HTML classique et du CSS. Il ne nécessite ni framework, ni JavaScript, ni illustration téléchargée, ni étape de compilation.

Comment un symbole produit-il plusieurs graphiques visibles ?

Un <symbol> est un modèle graphique. Il ne s’affiche pas de lui-même ; une référence <use> crée une instance visible. Placez la définition une seule fois dans le document, puis ajoutez un petit conteneur SVG à chaque endroit où le graphique doit apparaître. MDN indique que les deux éléments sont largement pris en charge. MDN : symbol.

Il faut distinguer le fait d’éviter de répéter les tracés dans le code source du fait d’éviter le travail de rendu du navigateur. Votre HTML contient une seule définition de tracé, mais le navigateur crée tout de même une instance rendue pour chaque <use>. MDN décrit ce processus comme un clonage dans un DOM non exposé. La réutilisation facilite la maintenance du code source ; cela ne signifie pas que plusieurs graphiques visibles deviennent un seul objet rendu. MDN : use.

Pour une page avec des libellés et des icônes, gardez les libellés en HTML et attribuez à chaque icône son propre conteneur SVG. WHATWG considère le SVG comme un contenu intégré, phrasé et de flux en HTML, ce qui permet de placer ces conteneurs parmi le contenu classique de la page. Norme HTML : SVG.

Créer une page complète avec une définition et trois instances

Dans un éditeur de texte brut sur votre Mac, créez un fichier nommé svg-reuse.html. Collez le document complet ci-dessous, enregistrez-le et ouvrez-le dans votre navigateur de bureau. Conservez l’extension .html et enregistrez le fichier en texte brut, et non comme document au format texte enrichi.

L’exemple définit deux tuiles diagonales avec un seul <path>. Trois références affichent cette même géométrie dans des tailles et couleurs différentes. Chaque référence utilise href="#demo-tiles" ; href est la forme actuelle, tandis que xlink:href est obsolète. MDN : attributs de use.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Reusable tile symbol</title>
  <style>
    body {
      margin: 2rem;
      font-family: system-ui, sans-serif;
      color: #263445;
    }
    .symbol-bank {
      position: absolute;
      width: 0;
      height: 0;
      overflow: hidden;
    }
    .samples {
      display: flex;
      flex-wrap: wrap;
      gap: 1.5rem;
    }
    .sample {
      display: flex;
      align-items: center;
      gap: 0.75rem;
      padding: 1rem;
      border: 1px solid #cbd5df;
    }
    .icon {
      display: block;
      width: 24px;
      height: 24px;
      flex: none;
    }
    .icon-large { width: 48px; height: 48px; }
    .icon-medium { width: 32px; height: 32px; }
    .blue { color: #2457a7; }
    .purple { color: #7140a0; }
  </style>
</head>
<body>
  <svg class="symbol-bank" width="0" height="0" aria-hidden="true">
    <symbol id="demo-tiles" viewBox="0 0 24 24"
            preserveAspectRatio="xMidYMid meet">
      <path fill="currentColor"
            d="M4 4H10V10H4Z M14 14H20V20H14Z"></path>
    </symbol>
  </svg>

  <main>
    <h1>Tile samples</h1>
    <div class="samples">
      <div class="sample">
        <svg class="icon" width="24" height="24"
             viewBox="0 0 24 24" aria-hidden="true">
          <use href="#demo-tiles" width="24" height="24"></use>
        </svg>
        <span>Small tiles</span>
      </div>

      <div class="sample blue">
        <svg class="icon icon-large" width="48" height="48"
             viewBox="0 0 24 24" aria-hidden="true">
          <use href="#demo-tiles" width="24" height="24"></use>
        </svg>
        <span>Large tiles</span>
      </div>

      <div class="sample purple">
        <svg class="icon icon-medium" width="32" height="32"
             viewBox="0 0 24 24" aria-hidden="true">
          <use href="#demo-tiles" width="24" height="24"></use>
        </svg>
        <span>Medium tiles</span>
      </div>
    </div>
  </main>
</body>
</html>

Le résultat attendu est constitué de trois échantillons encadrés contenant les mêmes tuiles diagonales. Le premier utilise la couleur du texte du corps de page, le deuxième est bleu et le troisième violet. Leurs zones SVG mesurent respectivement 24, 48 et 32 pixels CSS de côté. Réduisez la largeur de la fenêtre du navigateur pour vérifier comment les échantillons passent à la ligne.

Ici, les formes visibles sont décoratives, car les libellés adjacents fournissent l’information. C’est pourquoi les conteneurs SVG utilisent aria-hidden="true". Cela les retire de l’arborescence d’accessibilité sans les masquer visuellement. Réservez ce traitement aux graphiques décoratifs ; ne l’appliquez pas à une image qui transmet une information absente du texte. MDN : aria-hidden.

Quels paramètres contrôlent la mise en page et la disposition du SVG ?

Il y a trois tâches distinctes : disposer les composants HTML, dimensionner chaque zone SVG et faire correspondre le dessin à cette zone. Modifier le paramètre d’une tâche peut laisser les deux autres inchangées.

Tâche Paramètre dans l’exemple Élément à modifier
Disposer les échantillons sur la page .samples utilise flexbox et le retour à la ligne Modifiez ici l’espacement ou le retour à la ligne
Aligner chaque graphique avec son libellé .sample utilise flexbox et align-items: center Modifiez ici l’alignement du composant
Définir la zone SVG affichée .icon et ses classes de taille Modifiez ici la largeur et la hauteur CSS
Définir les coordonnées du dessin viewBox="0 0 24 24" Modifiez ce paramètre lorsque les limites de coordonnées du dessin changent
Dimensionner le symbole référencé à l’intérieur <use> a une largeur et une hauteur de 24 Conservez ces valeurs pour qu’elles correspondent à la zone de coordonnées interne de cet exemple
Ajuster proportionnellement le dessin preserveAspectRatio="xMidYMid meet" Modifiez ce paramètre uniquement si vous souhaitez un autre comportement d’ajustement

Flexbox dispose les enfants directs d’un conteneur flex. Le conteneur extérieur organise donc les échantillons, et chaque conteneur intérieur place un SVG à côté d’un libellé. Flexbox ne fonctionne que dans une dimension à la fois ; l’espace des lignes renvoyées est réparti indépendamment. Pour une conception qui nécessite des lignes et des colonnes coordonnées, CSS Grid est l’alternative adaptée à la mise en page. MDN : Concepts de base de flexbox.

Dans SVG, <use> suit un modèle de disposition différent. Ses valeurs x et y décalent les graphiques dans le système de coordonnées SVG. Elles ne définissent pas l’espacement entre les composants HTML. Sa largeur et sa hauteur peuvent dimensionner la fenêtre d’affichage d’un symbole référencé ; elles ne constituent pas une commande générale de mise à l’échelle pour un tracé ou un groupe référencé directement. W3C : disposition des graphiques réutilisés.

Pourquoi la grande instance conserve-t-elle des dimensions internes de 24 ?

Le viewBox du SVG extérieur décrit une zone de coordonnées de 24 sur 24. Sa zone CSS peut mesurer 48 sur 48 pixels alors que ses coordonnées internes restent inchangées. Le <use> remplit cette zone interne de 24 sur 24, et le SVG extérieur l’adapte à la zone affichée plus grande. MDN définit viewBox comme quatre nombres : x minimal, y minimal, largeur et hauteur. MDN : viewBox.

Pour un calcul illustratif avec ce dessin précis, une zone de 48 pixels adapte 24 unités de coordonnées à une échelle de 48 / 24 = 2. La géométrie des tuiles s’étend des coordonnées 4 à 20 ; son étendue totale peinte est donc de (20 - 4) × 2 = 32 pixels. L’espace restant provient des marges intentionnelles intégrées au dessin.

Cela explique pourquoi augmenter la largeur CSS d’une icône ne suffit pas nécessairement à faire occuper toute cette largeur à sa forme peinte. Vérifiez les limites de la géométrie dans le viewBox avant de modifier les marges de la page pour compenser.

Que se passe-t-il dans une zone SVG rectangulaire ?

Avec xMidYMid meet, le dessin est mis à l’échelle uniformément, reste centré et s’inscrit entièrement dans la zone d’affichage disponible. Un dessin carré placé dans un rectangle large laisse donc de l’espace sur les côtés. none autorise la déformation ; slice préserve les proportions, mais laisse une partie de la viewBox dépasser de la zone d’affichage. Utilisez meet lorsque le graphique complet doit rester visible. MDN : preserveAspectRatio.

Comment attribuer une couleur différente à chaque instance ?

Le tracé utilise fill="currentColor". Ce mot-clé reprend la valeur color de l’élément, ce qui permet au même dessin de suivre la couleur du texte environnant. Dans l’exemple, modifier la règle .blue ou .purple change à la fois le libellé et ses tuiles. MDN : mot-clé currentColor.

Cela fonctionne par héritage dans chaque instance. Le modèle de réutilisation de SVG transmet au contenu généré les styles hérités de l’élément hôte <use>. Une couleur fixe déclarée directement sur le tracé source est prioritaire sur une valeur de remplissage héritée fournie par un parent. Si chaque instance doit pouvoir avoir sa propre couleur, n’attribuez pas de couleurs fixes à la géométrie partagée. W3C : portée et héritage des styles.

Évitez de compter sur un sélecteur tel que .blue path pour atteindre un tracé généré à travers le conteneur visible. Le contenu généré appartient à l’arbre fantôme de réutilisation ; les relations entre ancêtres diffèrent donc de celles du HTML imbriqué classique. Définissez color sur le conteneur ou son parent et conservez currentColor dans la géométrie source. W3C : portée et héritage des styles.

Que vérifier si un symbole réutilisé ne s’affiche pas correctement ?

Commencez par la référence et remontez jusqu’à la source. Cette séquence permet de distinguer un graphique manquant d’un graphique mal dimensionné ou positionné, afin que chaque ajustement cible un mécanisme précis.

  1. Vérifiez la cible. Confirmez que href="#demo-tiles" correspond au id="demo-tiles" de la définition. Gardez cet ID unique dans l’arbre du document. W3C : attribut id.
  2. Vérifiez les dimensions du conteneur visible. Gardez la classe .symbol-bank, de taille nulle, uniquement sur le conteneur de définition. Chaque instance visible doit avoir une zone non nulle, comme dans .icon.
  3. Vérifiez les limites de coordonnées. Confirmez que le dessin tient dans le viewBox déclaré. Un espace vide inattendu peut provenir de coordonnées inutilisées. MDN : viewBox.
  4. Vérifiez le type de l’élément référencé. Si vous avez remplacé le symbole par une référence directe à un tracé, modifier la largeur et la hauteur de <use> ne le mettra pas à l’échelle de la même manière. Pour ce modèle, rétablissez le symbole et son viewBox. MDN : use.
  5. Vérifiez les déclarations de couleur. Recherchez les couleurs fixes dans la source avant d’ajouter d’autres sélecteurs d’instance.
  6. Vérifiez le conteneur de la page. Si le graphique s’affiche correctement mais se trouve trop loin de son libellé, ajustez l’écart CSS ou l’alignement du composant. MDN : Concepts de base de flexbox.

Pour intégrer l’exemple à une page existante, insérez la banque de symboles une seule fois, fusionnez les règles CSS et copiez uniquement le conteneur SVG visible dans les composants supplémentaires. Le petit document a fait l’objet de vérifications structurelles portant sur l’équilibre des éléments, l’unicité des ID et la résolution des trois références vers une seule définition de tracé ; ces vérifications ne confirment pas le rendu dans un navigateur. Ouvrez la page dans les navigateurs Mac que vous comptez prendre en charge et inspectez la taille, l’espacement et la couleur obtenus.

Pour modifier le dessin partagé, modifiez sa définition unique de tracé. Pour modifier une instance, changez la taille de son conteneur ou sa couleur héritée. En séparant ces responsabilités, vous obtenez des graphiques réutilisables et un contrôle prévisible de l’emplacement de chaque instance.

Sources