La Cascade

Un peu de tout sur CSS, HTML, SVG et JS,traduit du web anglophone
Rechercher

Les dégradés SVG

par Joni Trythall, 6 juin 2014, svg, article original paru le 3 juin 2014 dans Sitepoint

Les dégradés SVG permettent de remplir quasiment sans effort une forme complexe, et par rapport aux dégradés CSS ils présentent l'avantage d'être présents dans le DOM


Pourquoi utiliser les dégradés SVG plutôt que les dégradés CSS, c'est une longue discussion, mais dans cet article nous nous allons simplement nous concentrer sur l'utilisation pratique des dégradés SVG, si vous choisissez cette solution. (👉🏾 NdT : si vous voulez plus d'information sur les dégradés CSS, vous pouvez consulter cet article.).

Les dégradés SVG permettent de remplir quasiment sans effort une forme complexe, et par rapport aux dégradés CSS ils présentent l'avantage d'être présents dans le DOM. Cette approche est pratique en particulier quand un dégradé est une partie permanente de votre design. Nos styles CSS peuvent évoluer au fil du temps, mais le coeur de notre création artistique restera souvent inchangé, et du coup il est préférable que cette création réside dans le SVG lui-même, dans le DOM.

De plus, si vous décidez plus tard d'animer votre dégradé, vous pouvez ajouter cette animation directement dans l'élément SVG.

Les bases

SVG propose deux types de dégradés, linéaire et radial. Les détails sont définis à l'intérieur d'un élément <defs>. L'élément <defs> contient des instructions qui peuvent être réutilisées tout au long du document, mais qui ne donneront pas lieu à affichage tant qu'il n'est pas appelé. Le fait de définir les éléments du dégradé à l'intérieur d'un élément <defs> nous permet de mieux comprendre le contenu du SVG et offre une meilleure accessibilité.

SVG utilise la notion générale de paint server (“serveur de peinture”) qui est une méthode permettant au remplissage (fill) et au traçé (stroke) d'un objet d'être défini par une ressource disponible ailleurs. Les dégradés sont une des nombreuses options paint que l'on peut appeler pour remplir le background et les bordures de formes et de textes.

Pour illustrer cette notion, voici à quoi ressemblera la structure d'un dégradé linéaire simple :

<svg>
    <defs>
        <linearGradient id="gradientName">
            <stop offset="<%>" stop-color="<color>" />
            <stop offset="<%>" stop-color="<color>" />
        </linearGradient>
    </defs>
</svg>

Une fois que vous avez donné un ID à votre dégradé (dans notre exemple : gradientName ), il peut être appelé à travers les attributs fill et/ou stroke dans le SVG qui l'utilisera, par exemple en écrivant fill= "url(#gradientName)".

Les Dégradés linéaires

Les dégradés linéaires passent d'une couleur à une autre de façon régulière le long d'une ligne. Le dégradé est défini par un axe et éventuellement par un angle.

Chaque stop défini sur cette ligne représentera la couleur à l'intérieur de l'élément <linearGradient>. À chaque stop la couleur est à 100% de saturation et l'espace entre deux stops est le lieu où s'effectue la transition d'une couleur à la suivante. Il est possible d'utiliser des couleurs supplémentaires, comme nous le verrons tout à l'heure.

Regardons à quoi ressemble le code SVG pour un dégradé linéaire simple, comportant deux stops couleur, puis nous passerons en revue les options d'attributs disponibles.

un dégradé simple, de bleu à rouge
<svg>
    <defs>
        <linearGradient id="Gradient-1"
             x1="0" y1="0" x2="100%" y2="0">
            <stop offset="0%" stop-color="lightblue" />
            <stop offset="100%" stop-color="#ef5b2b" />
        </linearGradient>
    </defs>
    <rect x="450" y="10" width="200" height="100" fill= "url(#Gradient-1)" stroke="#333333" stroke-width="4px" />
</svg>

Attributs des dégradés linéaires

Comme nous l'avons vu, les détails du dégradé sont définis à l'intérieur d'un élément <linearGradient>. À l'intérieur de celui-ci, nous pouvons utiliser tout un tas d'attributs pour le personnaliser.

ID

Les dégradés doivent avoir un ID unique de façon à pouvoir être appliqués à nos formes ou textes SVG.

x1, y1, x2, y2

Les valeurs d'attributs x1, y1, x2 et y2 représentent les points de départ et d'arrivée qui définissent les stops (les changements de couleurs). Ces pourcentages s'appliquent sur l'axe choisi. S'ils ne sont pas spécifiés, toutes les valeurs seront égales à 0 par défaut, sauf x2 qui prendra la valeur 100% par défaut.

Ce sont aussi ces valeurs qui définiront si notre axe est horizontal ou vertical, ou quelque part entre les deux. Par exemple une valeur y de 100% et une valeur x de 0 produiront un axe horizontal, et l'inverse donnera un axe vertical. Si les deux ont une valeur de 100% (ou n'importe quelle valeur différente de 0), l'axe sera oblique.

gradientUnits

L'attribut gradientUnits définit le système de coordonnées pour les valeurs x1, x2, y1 et y2. Les deux options possibles sont "userSpaceOnUse" ou "objectBoundingBox". userSpaceOnUse définit le système de coordonnées en unités absolues, alors que objectBoundingBox établit ce système à l'intérieur des limites de la forme SVG elle-même. Par défaut, la valeur de l'attribut est objectBoundingBox.

spreadMethod

La valeur de l'attribut spreadMethod spécifie la façon dont le dégradé va se répandre à travers la forme, s'il commence ou se termine à l'intérieur des limites du SVG. En gros, si le dégradé est défini d'une façon telle qu'il ne remplit pas toute la forme, qu'advient-il de l'espace vide ? Il y a trois options ici : pad, repeat ou reflect.

Une valeur de pad indique que la première et la dernière couleur du dégradé doivent couvrir le reste de la forme (voir l'exemple ci-dessous). Une valeur repeat indique que le dégradé doit répéter le motif depuis le début jusqu'à couvrir toute la surface. L'utilisation de reflect aura pour résultat de faire se refléter de manière continue le motif de dégradé, du début à la fin et de la fin au début, jusqu'à couvrir toute la forme (voir l'exemple ci-dessous).

Sans autre indication, la valeur par défaut est pad.

les trois effets spreadmethod

L'image ci-dessus montre comment les différentes valeurs de spreadMethod impactent visuellement le même dégradé. Il est important de se rappeler que ces valeurs d'attribut n'auraient aucun effet sur un dégradé remplissant déjà l'intégralité de la forme.

Les points de départ et d'arrivée du dégradé ci-dessus sont (voir le code complet plus bas) :

x1="20%" y1="30%" x2="40%" y2="80%"

gradientTransform

L'attribut gradientTransform est optionnel, il nous permet de transformer plus encore le dégradé avant de l'appliquer, comme avec CSS Transforms.

xlink:href

Avec cet attribut, vous pouvez appeler l'ID d'un autre dégradé, duquel le dégradé en cours devrait "hériter". Dans les images ci-dessus, il y a trois rectangles. Ces rectangles appellent tous les mêmes stops couleurs mais ils appellent également des valeurs spreadMethod qui résident dans un ID spécial à l'intérieur d'élément <linearGradient> additionnels.

Voici le code pour ces éléments :

<defs>
    <linearGradient id="Gradient-1"
    x1="20%" y1="30%" x2="40%" y2="80%">
        <stop offset="0%" stop-color= "#1cb98f" />
        <stop offset="50%" stop-color= "#f99450" />
        <stop offset="100%" stop-color= "#876fc3" />
    </linearGradient>

    <linearGradient id="pad"
                    xlink:href="#Gradient-1"
                    spreadMethod="pad" />

    <linearGradient id="repeat"
                    xlink:href="#Gradient-1"
                    spreadMethod="repeat" />

    <linearGradient id="reflect"
                    xlink:href="#Gradient-1"
                    spreadMethod="reflect" />
</defs>

Chaque rectangle appelle un ID spécifique décrivant une spreadMethod différente à chaque fois, mais ils héritent tous des stops couleur définis dans "#Gradient-1".

Voici comment ces dégradés sont appelés à l'intérieur de trois rectangles :

<rect x="10" y="10"
      width="200" height="100"
      fill= "url(#pad)"
      stroke="#333333"
      stroke-width="4px" />

<rect x="230" y="10"
      width="200" height="100"
      fill= "url(#repeat)"
      stroke="#333333"
      stroke-width="4px" />

<rect x="450" y="10"
      width="200" height="100"
      fill= "url(#reflect)"
      stroke="#333333"
      stroke-width="4px" />

👉🏿 NdT : SVG 2 a supprimé le besoin de l'espace de nom xlink, donc au lieu de xlink:href vous devriez utiliser href. Si vous devez prendre en charge des versions antérieures du navigateur, l'attribut xlink:href déprécié peut être utilisé comme solution de repli en plus de l'attribut href, e.g. .

Les stops

Maintenant que nous comprenons les bases des attributs de <linearGradient>, nous pouvons passer aux attributs de <stop> que nous avons aperçus dans l'exemple de code précédent.

Comme on l'a vu, les stops couleur sont définis à l'intérieur de l'élément <linearGradient>. Quelle couleur voulons-nous voir à un certain endroit ? Nous disposons de trois attributs ici : offset, stop-color et stop-opacity. L'offset indique à quel endroit fixer le stop couleur. Le stop-color définit la couleur. Vous pouvez également inclure une valeur stop-opacity qui appliquerait une opacité sur la couleur située au point stop.

<defs>
    <linearGradient id="Gradient-2">
        <stop offset="0%"
              stop-color="purple"
              stop-opacity=".3" />
        <stop offset="100%"
              stop-color="blue"
              stop-opacity=".5" />
    </linearGradient>
</defs>

Le dégradé est maintenant complété et peut être appelé sur les attributs fill ou stroke dans l'élément SVG, à partir de son ID, par exemple en faisant fill= "url(#Gradient-2)".

Autres exemples de dégradés linéaires

Voici quelques démos qui mettent en action toutes ces notions.

Pour la démo sur le texte “Apple” il y a un élément <text> à l'intérieur de notre élément <svg>. Les définitions de dégradés sont situées dans un élément <defs> qui se trouve aussi à l'intérieur de <svg> (cliquez sur HTML, CSS et Result pour voir les détails).

Pour avoir une autre perspective, regardons ces quelques icônes dans la démo qui suit. Chaque fruit SVG a sa propre définition de <linearGradient>. Les remplissages et les traits peuvent être constitués des mêmes dégradés ou de dégradés différents, ou peuvent être une couleur solide...

Les dégradés radiaux

Les dégradés radiaux sont à la fois très similaires et très différents des dégradés linéaires. Le dégradé, au lieu de se propager sur une ligne suit une expansion concentrique. Les stops commencent au centre du cercle et suivent le mouvement d'expansion.

Attributs des dégradés radiaux

La plupart des attributs sont les mêmes que ceux que nous avons vus, sauf le système de coordonnées qui est différent.

cx, cy, r

Les attributs cx, cy, r définissent le plus grand cercle (c'est à dire le plus externe) pour le dégradé radial. Le dégradé sera dessiné de telle façon que la limite de dégradé de 100% corresponde au périmètre de ce plus grand cercle. Si non spécifiées, les valeurs sont par défaut 50%. cx et cy sont les coordonnées du centre, r représente le rayon, en d'autres termes la longueur du dégradé. Une valeur r égale à 0 donnera une couleur unique jusqu'au dernier stop couleur.

fx, fy

Ces attributs représentent les coordonnées du foyer du dégradé, le cercle situé le plus à l'intérieur. Le dégradé sera dessiné de telle manière que la limite de dégradé de 0% corresponde au point (fx,fy). Si l'attribut fx n'est pas spécifié, la valeur de fx coïncidera avec celle de cx.

La démo ci-dessous montre un dégradé radial à l'intérieur d'un texte SVG. Ce premier exemple a un foyer de fx= "45%" fy= "45%".

voir SVG Radial Gradient example de SitePoint dans CodePen

L'exemple suivant a un foyer de fx="90%" fy="70%" :

Le foyer (un bleu-vert) s'est déplacé vers la droite. Pour rééquilibrer la répartition des stops, nous pourrions changer les valeurs de cx et cy.

Exemple de dégradé radial

Voici à nouveau les icônes repésentant des fruits, cette fois-ci avec des dégradés radiaux.

Compatibilité navigateurs

La compatibilité navigateurs de SVG est excellente, aussi bien pour les ordinateurs de bureau que pour les appareils mobiles.

Toutefois, Firefox et Safari semblent avoir des problèmes avec spreadMethod qui n'est pas réglée par défaut sur la valeur pad. Pour éviter cela, il suffit de faire en sorte que votre dégradé remplisse entièrement la forme, sauf évidemment si votre intention est d'avoir un remplissage partiel.


Ressources complémentaires en anglais

Ressources complémentaires en français

Autres ressources externes

Articles de Joni Trythall traduits dans La Cascade

Voir la page de Joni Trythall et la liste de ses articles dans La Cascade.
Article original paru le 3 juin 2014 dans Sitepoint
Traduit avec l'aimable autorisation de Sitepoint et de Joni Trythall.
Copyright Sitepoint © 2014