Niveau Niveau débutant

Appliquer des styles CSS à SVG : le guide complet

Tutorielcss

Publié par le (1215 lectures)

inline externe svg masque symbol use light dark

Les images SVG (Scalable Vector Graphics) offrent de nombreux avantages : légèreté, agrandissement infini et possibilité de manipulation via CSS. Cependant, leur stylisation peut s'avérer complexe selon la méthode d'intégration choisie. Ce guide vous explique comment appliquer efficacement des styles CSS sur vos SVG selon différents scénarios.

Comprendre le contexte des SVG

Les SVG fonctionnent dans leur propre espace de nommage XML. Cette particularité explique pourquoi les interactions entre le CSS de votre page et les éléments SVG ne sont pas toujours évidentes. Deux mondes coexistent :

  • Le document HTML principal avec son CSS
  • Le document SVG avec son propre contexte de style

Les méthodes d'intégration des SVG

La façon dont vous intégrez un SVG détermine comment vous pourrez le styliser :

  1. SVG inline : intégré directement dans le HTML (entièrement manipulable via CSS)
  2. SVG externe : référencé via une balise <img>, background-image ou autres méthodes (limité en terme de stylisation),
  3. SVG via l'élément <use> : approche hybride permettant réutilisation et stylisation.

1. Styliser des SVG inline

Les SVG inline (insérés directement dans le HTML) sont les plus flexibles en termes de stylisation, car ils font partie intégrante du DOM.

Exemple de base

<svg width="100" height="100" viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="40" fill="tomato" class="circle" />
</svg>
.circle {
  fill: pink; /* Change la couleur de remplissage */
  stroke: black; /* Ajoute un contour */
  stroke-width: 2px; /* Définit l'épaisseur du contour */
  transition: fill 0.3s; /* Ajoute une transition */

  &:hover {
    fill: hotpink; /* Change la couleur au survol */
  }
}

currentColor fait généralement le job

La valeur currentColor fait office de "variable" en CSS puisqu'elle adopte automatiquement la couleur de texte environnante. En clair, elle copie la valeur de color du parent, même si celle-ci change. Idéalement, elle peut être appliquée aux attributs SVG fill et strokepar exemple :

<svg width="100" height="100" viewBox="0 0 100 100">
  <circle fill="currentColor" class="circle" />
</svg>
.circle {
  color: pink; /* Définit la couleur du cercle */

  &:hover {
    color: hotpink; /* Change la couleur au survol */
  }
}

Bonnes pratiques pour les SVG inline

  • Utilisez currentColor pour que les éléments SVG héritent automatiquement de la couleur du texte parent (utilisez fill="currentColor" et/ou stroke="currentColor" pour les icônes qui doivent s'adapter à la couleur du texte),
  • Nettoyez vos SVG des attributs de style superflus (voir outils en fin d'article),
  • Ajoutez des classes pertinentes aux éléments que vous souhaitez cibler.

2. Styliser des SVG externes

Les fichiers SVG externes (balise <img> ou background-image) sont naturellement plus capricieux à styliser du fait de leur principe de compartimentage : rien n'entre ni ne sort d'un SVG, ou presque.

Cas 1 : SVG externe modifiable

Si vous avez accès au fichier SVG, vous pouvez y incorporer des styles directement via l'élément <style>, mais vous n'irez pas très loin :

<svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
  <style>
    .icon-path {
      fill: black;
    }
  </style>
  <path class="icon-path" d="…" />
</svg>

Limitations importantes :

  • Les valeurs doivent être stipulées en dur (pas de currentColor, ni de var(--ma-couleur))
  • Les interactions comme :hover fonctionnent uniquement dans certains contextes (SVG dans <object> ou <embed>, pas dans <img>)

Cas 2 : SVG externe non modifiable (masques CSS)

Cette technique utilise la propriété CSS mask pour appliquer une couleur à un SVG externe sans devoir le modifier.

  • Un élément HTML (comme un <span>) est utilisé comme conteneur,
  • Une couleur de fond (background-color) est appliquée à cet élément,
  • Le fichier SVG externe est utilisé comme masque via la propriété mask,
  • Seules les parties opaques du SVG laissent apparaître la couleur de fond.

C'est comme si le SVG agissait comme un pochoir : il définit la forme visible, mais la couleur provient de l'élément HTML lui-même. La contrepartie est que la teinte sera forcément monochrome.

<span class="icon icon-star"></span>
<span class="icon icon-cart"></span>
.icon {
  /* Dimensions */
  display: inline-block;
  width: 1rem;
  height: 1rem;

  /* Couleur de l'icône (modifiable à volonté) */
  background-color: currentColor;

  /* Application du masque SVG */
  mask: var(--svg) no-repeat center;
  mask-size: contain;
}

.icon-star {
  --svg: url("icons/star.svg");
}

.icon-cart {
  --svg: url("icons/cart.svg");
}

/* Exemple d'interaction */
.icon:hover {
  background-color: hotpink;
}

/* Exemple pour dark mode */
@media (prefers-color-scheme: dark) {
  .icon {
    background-color: white;
  }
}

Voir une démo

Les masques CSS en action :


3. Utiliser l'élément <use> pour optimiser vos SVG

L'élément <use> offre un excellent compromis en permettant de regrouper des SVG en "sprites" tout en gardant la possibilité de les styliser individuellement.

Rassemblement de plusieurs <symbol> (sprite)

Chaque élément (ici, chaque icône) est défini dans un <symbol> avec un ID unique, le tout regroupé dans <svg> unique. Ces symboles sont ensuite instanciés via <use>.

<symbol> est un conteneur qui ne sera pas affiché directement, mais qui peut être utilisé pour créer des instances de ce symbole (des clones) ailleurs dans le document.

<!-- N'importe où dans votre document HTML -->
<svg style="display: none">
  <symbol id="icon-cart" viewBox="0 0 24 24">
    <path d="…" />
  </symbol>

  <symbol id="icon-star" viewBox="0 0 24 24">
    <path d="…" />
  </symbol>
</svg>

Affichage d'un <symbol> avec use

use permet d'instancier chacun des symboles définis précédemment. Vous pouvez les placer où vous le souhaitez dans la page et les styliser comme n'importe quel autre SVG inline.

<svg class="icon">
  <use href="#icon-cart" />
</svg>

<svg class="icon icon-big">
  <use href="#icon-star" />
</svg>
.icon {
  width: 1rem;
  height: 1rem;
  fill: currentColor;

  &:hover {
    fill: hotpink;
  }
}

.icon-big {
  width: 2rem;
  height: 2rem;
}

Référencer un fichier SVG externe avec <use>

Il est également possible de faire référence à un fichier SVG externe contenant plusieurs symboles. Cette fonctionnalité évite de devoir insérer l'ensemble du sprite SVG de manière inline :

<!-- sprite.svg est un fichier externe contenant des symbols -->
<svg class="icon">
  <use href="/icons/sprite.svg#icon-cart" />
</svg>

Voir une démo

Les sprites CSS en action :

Remarques importantes :

  • Le SVG référencé doit être sur le même domaine ou avec CORS configuré (Cross-Origin Resource Sharing),
  • Le SVG doit contenir des éléments avec ID pour y faire référence.

Des outils pour symbol et use

Diverses applications permettent de faciliter la composition de symboles (sprites) de SVG.

Pour commencer, l'excellente ressource Icônes.js du talentueux Anthony Fu propose une palette de plusieurs milliers d'icônes SVG récupérables dans tous les formats possibles (y compris frameworks) et notamment sous forme de symbol SVG.

Option symbol" pour une icone SVG

L'outil svgsprit.es quant à lui s'applique à générer votre sprite SVG à partir d'un lot de fichiers que vous lui téléversez.

Outil pour générer des sprites SVG


Adaptation au thème clair/sombre (Dark Mode)

S'adapter au mode d'apparence (clair ou sombre) offre une expérience utilisateur souvent grandement améliorée. SVG est parfaitement malléable sur ce sujet également.

Dark Mode avec SVG inline

Manipuler le mode de couleurs des SVG inline est relativement simple. Il est possible d'utiliser :

  • currentColor pour que la couleur du SVG s'adapte à la couleur du texte parent,
  • light-dark() pour appliquer des couleurs spécifiques au SVG sans être dépendant de la couleur du parent,
  • des media queries pour appliquer des styles spécifiques selon le mode de l'utilisateur,
  • des attributs data pour appliquer des styles spécifiques selon le mode de l'utilisateur.
<svg class="icon" width="24" height="24" viewBox="0 0 24 24">
  <path d="…" fill="…" />
</svg>
.icon {
  /* S'adapte automatiquement à la couleur du texte */
  fill: currentColor;

  /* OU avec la fonction light-dark() */
  fill: light-dark(#333333, #ffffff);

  /* OU avec media query */
  @media (prefers-color-scheme: dark) {
    fill: #ffffff;
  }

  /* OU avec attribut data */
  [data-theme="dark"] & {
    fill: #ffffff;
  }
}

Dark Mode avec SVG externe modifiable

Légèrement plus contraignant, il est possible ajouter un élément <style> dans le SVG pour appliquer les styles CSS suivants (ici la classe .path a été ajoutée à l'élément dont la couleur doit s'adapter).

Notez que là aussi, les valeurs doivent être stipulées en dur (pas de currentColor, ni de var(--ma-couleur)) :

<svg width="24" height="24" viewBox="0 0 24 24">
  <style>
    .path {
      fill: #333333;
    }

    /* Adaptations pour dark mode */
    @media (prefers-color-scheme: dark) {
      .path {
        fill: white;
      }
    }

    /* Adaptations via attribut data */
    [data-theme="dark"] path {
      fill: white;
    }
  </style>
  <path class="path" d="…" />
</svg>

SVG et Dark Mode


Bonnes pratiques et astuces

Selon vos contraintes (SVG inline ou externe, modifiables ou non), divers scénarios permettent d'appliquer des styles CSS aux éléments SVG. Dans tous les cas, pensez à respecter quelques bonnes pratiques générales :

  1. Optimisez vos SVG : Utilisez des outils comme SVGOMG pour nettoyer vos fichiers SVG de métadonnées et attributs inutiles.
  2. Testez différentes approches : Utilisez la technique la plus adaptée selon le contexte. Un sprite SVG combiné avec <use> est souvent la solution la plus flexible, mais aucune approche n'est réellement parfaite.
  3. Évitez les styles inline : Pour faciliter la maintenabilité et la cohérence des fichiers, préférez les styles "classiques" dans un fichier CSS plutôt que des styles inline (<style>) dans le SVG… quand c'est possible.
  4. Testez vos SVG sur différents navigateurs : Certaines fonctionnalités avancées peuvent ne pas être supportées par tous les navigateurs.
  5. Adaptez vos SVG au mode sombre : Utilisez currentColor, light-dark() ou les media queries pour adapter automatiquement vos icônes au thème préféré de l'utilisateur.
  6. Profitez des transitions CSS : Les propriétés SVG comme fill, stroke et opacity peuvent être animées avec des transitions CSS. Attention toutefois aux éventuels problèmes d'accessibilité et de performance.

Conclusion et pense-bête

La stylisation des SVG avec CSS offre de nombreuses possibilités créatives, mais nécessite de comprendre les différences entre les méthodes d'intégration. En choisissant l'approche adaptée à vos besoins spécifiques et en suivant les bonnes pratiques, vous pouvez créer des graphiques vectoriels attrayants, accessibles et parfaitement intégrés à votre interface utilisateur.

À retenir :

  1. SVG inline : Facile à manipuler en CSS.
    • fill/stroke="currentColor" adopte la couleur de texte du parent (color),
    • fill/stroke="var(--ma-couleur, currentColor)" applique une couleur de variable,
    • fill/stroke="light-dark(couleur1, couleur2)" applique une couleur en fonction du choix de thème utilisateur,
    • Media Queries (dont dark mode) possibles.
  2. SVG externe : Limité en terme de styles.
    • <style></style> dans le SVG applique des styles CSS (les styles sont compartimentés),
    • Couleurs en dur (ex. fill/stroke="#FF69B4"), pas de currentColor, ni de var(--ma-couleur),
    • Media Queries (dont dark mode) possibles.
  3. SVG via l'élément <use> : Facile à manipuler en CSS, mais nécessite une préparation préalable.
    • Chaque élément est un <symbol> identifié via id, tous regroupés dans "sprite" <svg> et clonés via <use>,
    • Le sprite peut être un fichier SVG externe ou inline,
    • Tous les styles CSS sont appliquables comme pour les SVG inline.

Ressources complémentaires

Commentaires

Très bon article, merci !

J'ai eu ce genre de souci sur des icônes : autant les techniques ci-dessus marchent bien pour un thème dark et un light, mais quand tu as plusieurs thèmes ça peut se compliquer (notamment les fichiers externes, car les variables CSS ne passent pas). J'ai dû faire des refactos pour éliminer ces sprites via fichiers externes dans ce cas précis (et inliner le sprite).

Commenter

Vous devez être inscrit et identifié pour utiliser cette fonction.

Connectez-vous (déjà inscrit)

Oubli de mot de passe ? Pas de panique, on va le retrouver

Pas encore inscrit ? C'est très simple et gratuit.