Utilisation du SVG avec Media Queries

Dans les documents HTML, nous pouvons afficher, cacher ou réorganiser des parties de la page en fonction des conditions de la fenêtre d’affichage. Si la fenêtre du navigateur a une largeur de 480 pixels, par exemple, nous pouvons faire passer notre navigation d’une liste horizontale à une liste verticale et pliable. Nous pouvons faire quelque chose de similaire en utilisant SVG avec des requêtes média.

Cet article est un extrait du livre de Tiffany. CSS Master, 3e édition. Jetez-y un coup d’œil si vous souhaitez maîtriser d’autres fonctionnalités CSS3 avancées comme Flexbox et Grid !

En plus d’utiliser CSS avec HTML, nous pouvons également utiliser CSS avec SVG, ou Graphiques vectoriels évolutifs. SVG est un format de balisage permettant de décrire des images plates et bidimensionnelles. Comme c’est un langage de balisage, il possède un modèle d’objet de document et peut être utilisé avec CSS.

En utilisant CSS avec SVG, nous pouvons changer l’apparence de SVG en fonction de l’interaction de l’utilisateur. Il est également possible d’utiliser le même document SVG à plusieurs endroits et d’en afficher ou d’en masquer des parties en fonction de la largeur de la fenêtre d’affichage.

Tous les principaux moteurs de navigateur prennent en charge le format SVG 1.1 et ce, depuis des années. Le support des fonctionnalités de SVG 2 d’autre part, est toujours en cours de développement. Au moment de la rédaction de ce document, le support des navigateurs est limité pour certains des sujets abordés ici. Cela peut avoir changé au moment où vous lisez ces lignes. Gardez un œil sur le méta-problème de Chromium. Implémentation des fonctionnalités SVG2 – pour suivre la progression du développement dans les navigateurs basés sur Chromium. Regardez le Prise en charge des fonctionnalités de SVG 2 méta-problème pour suivre le travail d’implémentation de Firefox, et celui de WebKit. Implémentation de SVG 2 méta-problème pour Safari. Il peut être désagréable de naviguer dans les Issue Trackers, mais pour l’instant, c’est le meilleur moyen de suivre le support de SVG 2.

Avant d’aller plus loin, cependant, parlons de ce qu’est SVG et pourquoi vous devriez l’utiliser.

Images vectorielles et images matricielles

La plupart des images actuellement utilisées sur le Web sont des images matricielles, également appelées images bitmap. Images matricielles sont composées de pixels sur une grille fixe, avec un nombre défini de pixels par pouce. Les formats JPEG, WebP, GIF et PNG sont tous des exemples d’images matricielles.

Les images matricielles sont dépendent de la résolution. Une image PNG de 144 PPI (pixels par pouce) est très belle sur un appareil dont la résolution d’affichage est de 144 PPI. Cependant, lorsqu’elle est affichée sur un écran à plus haute résolution (400 PPI), cette même image peut sembler floue. Les images matricielles ont également des dimensions fixes et leur aspect est optimal dans leur taille d’origine. La mise à l’échelle d’une image de 150 par 150 pixels à 300 par 300 pixels la déforme.

Au lieu d’utiliser des pixels sur une grille, les formats d’image vectorielle décrivent les formes primitives – cercles, rectangles, lignes ou chemins – qui composent une image, ainsi que leur emplacement dans le système de coordonnées du document. Par conséquent, les images vectorielles sont indépendantes de la résolutionet conservent leur qualité quelle que soit la résolution ou les dimensions de l’écran.

L’indépendance de résolution est le plus grand avantage de SVG. Nous pouvons augmenter ou diminuer l’échelle des images sans perte de qualité. La même image est superbe sur les appareils à PPI élevé et faible. Cela dit, SVG est mal adapté à la quantité de données de couleur requises pour les photographies. Il convient mieux aux dessins et aux formes. Utilisez-le à la place des images PNG et GIF, et comme substitut plus souple des polices d’icônes.

Un autre avantage de SVG est qu’il a été conçu pour être utilisé avec d’autres langages web. Nous pouvons créer, modifier et manipuler des images SVG avec JavaScript. Ou, comme nous le verrons plus loin, nous pouvons styliser et animer SVG à l’aide de CSS.

Associer les CSS aux documents SVG

L’utilisation de CSS avec SVG ressemble beaucoup à l’utilisation de CSS avec HTML. Nous pouvons appliquer le CSS en utilisant la fonction style d’un élément SVG, regrouper les CSS dans un document en utilisant l’attribut style . <style> ou établir un lien avec une feuille de style externe. Les avantages et les inconvénients de chaque méthode sont les mêmes que pour l’utilisation de CSS avec HTML.

Utilisation de la style Attribut

Voici un simple document SVG où le code crée un cercle noir :

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" 
➥enable-background="new 0 0 200 200">
    <circle cx="101.3" cy="96.8" r="79.6" />
</svg>

L’image ci-dessous montre le rendu de ce code dans un navigateur.

Un cercle en SVG

Donnons à notre cercle un remplissage rose en utilisant CSS et la fonction style et de l’attribut style :

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" 
➥enable-background="new 0 0 200 200">
    <circle cx="101.3" cy="96.8" r="79.6" style="fill: #f9f" />
</svg>

L’effet de cette mesure est illustré ci-dessous.

Utilisation de l'attribut style pour ajouter une couleur de remplissage

Voici une différence entre l’utilisation de CSS avec HTML et son utilisation avec SVG : les noms des propriétés. De nombreuses propriétés CSS que nous utilisons avec les documents HTML ne sont pas compatibles avec SVG, et vice versa. Nous reviendrons sur ce point plus tard dans le chapitre.

Utilisation de l’optionstylen’est pas la meilleure façon d’utiliser les CSS, bien sûr. Cela limite la possibilité de réutiliser ces styles dans plusieurs éléments ou documents. Il est préférable d’utiliser le CSS en ligne ou lié.

Incorporation de CSS dans les documents SVG

Au lieu d’utiliser l’optionstylenous pouvons utiliser l’attribut <style> élément :

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0
➥ 200 200" enable-background="new 0 0 200 200">
    <style type="text/css">
        circle {
            fill: #0c0;
        }
    </style>
    <circle cx="101.3" cy="96.8" r="79.6" />
</svg>

L’incorporation de CSS dans un document SVG nous permet de réutiliser ces styles pour plusieurs éléments dans le même document, mais elle empêche le partage de ces CSS entre plusieurs documents. C’est très bien pour les logos et les icônes. Mais si vous créez quelque chose comme une bibliothèque de styles de graphiques, il est préférable d’utiliser un fichier CSS externe.

À l’aide d’un éditeur de texte standard, vous pouvez également ajouter du CSS aux images SVG créées avec des logiciels tels que Sketch, Inkscape ou Illustrator. Cela n’affectera pas votre capacité à modifier l’image avec l’application de dessin, mais si vous modifiez le fichier à l’aide d’un logiciel d’image, l’application peut réécrire ou supprimer votre CSS.

Créer un lien entre un SVG et un fichier CSS externe

Comme pour le HTML, la liaison à un fichier CSS externe permet de partager les styles entre plusieurs documents SVG. Pour lier un fichier CSS externe, ajoutez <? xml-stylesheet ?> au début de votre fichier SVG :

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="https://www.gekkode.com/style.css" type="text/css"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0
➥ 200 200" enable-background="new 0 0 200 200">
    <circle cx="101.3" cy="96.8" r="79.6" />
</svg>

Utilisation de la fonction <link> Élément

Vous pouvez également utiliser le code HTML <link> . Si vous utilisez cette méthode, vous devrez inclure l’élément xmlns comme indiqué ci-dessous :

<link href="style.css" type="text/css" rel="stylesheet"
     xmlns="http://www.w3.org/1999/xhtml" />

Remarque : certains navigateurs plus anciens ont besoin de l’attribut <link> soit entouré de <defs> ou <g> tags.

Le site <link> n’est pas un élément SVG. Il appartient au HTML et au XHTML. Le XHTML est une variante du HTML qui est analysée selon les règles du balisage XML. Selon les règles du XML, nous pouvons emprunter des éléments et leur comportement à d’autres dialectes XML, comme le XHTML. Pour ce faire, toutefois, nous devons indiquer au navigateur l’espace de nom auquel l’élément appartient à l’aide de la balise xmlns .

Utilisation de @import

Nous pouvons également créer un lien vers une feuille de style externe en utilisant @import à l’intérieur de <style> et </style> tags :

<style type="text/css">
@import("https://www.gekkode.com/style.css");
</style>

Cette méthode fonctionne de manière similaire à la méthode <link> .

SVG et le <img> élément : Limites

L’établissement de liens entre des fichiers SVG et des ressources externes, y compris des fichiers CSS, ne fonctionne pas avec l’élément <img> ne fonctionne pas avec l’élément <img> . Il s’agit d’une limitation de sécurité de l’élément <img> qui est intégré dans les navigateurs.

Si vous souhaitez utiliser des CSS liés avec vos images SVG, vous devez effectuer l’une des deux opérations suivantes :

  • utiliser l’option <style> dans votre document SVG pour placer votre CSS en ligne.
  • Utilisez un élément <iframe> ou <object> élément (voir note ci-dessous)

En général, vous devriez utiliser <iframe> plutôt que <object>. Cependant, la <object> peut être l’enfant d’un élément <a> tandis que l’élément <iframe> ne le peut pas. Utilisation de <iframe> ou <object> rend également l’arbre du document SVG disponible pour l’arbre du document parent. Cela signifie que nous pouvons utiliser JavaScript pour interagir avec lui (par exemple, avec document.querySelector('iframe').contentDocument).

SVG en ligne et actifs externes

Lors de l’ajout de SVG au HTML, le navigateur ne chargera pas les actifs externes référencés par le document SVG. Cependant, nous pouvons créer un lien vers le CSS de notre document SVG à partir de la balise <head> de notre document HTML :

<head><link href="svg.css" type="text/css" rel="stylesheet" />
</head>

Les éléments SVG dans les documents HTML font également partie de l’arbre du document HTML. Si vous utilisez des éléments SVG en ligne, il est tout à fait possible de combiner les feuilles de style CSS relatives au HTML et au SVG dans la même feuille de style.

Différences entre SVG et HTML

Bien que SVG et HTML soient tous deux des langages de balisage, il existe deux différences significatives entre eux qui affectent la façon dont ils fonctionnent avec CSS :

  • SVG n’adhère pas au modèle de boîte CSS.
  • SVG ne dispose pas d’un schéma de positionnement

Le SVG n’adhère pas au modèle de boîte CSS

Lorsqu’elle est utilisée avec HTML, la mise en page CSS suit les règles du modèle de boîte CSS. SVG, en revanche, utilise des coordonnées pour la mise en page. Il adhère à ce qui peut être mieux compris comme un « modèle de forme ».

Les formes SVG ne sont pas limitées aux boîtes rectangulaires. Par conséquent, la plupart des propriétés liées au modèle de boîte ne s’appliquent pas aux éléments SVG. Vous ne pouvez pas, par exemple, modifier l’élément padding ou margin d’un élément SVG. Vous ne pouvez pas non plus utiliser l’option box-sizing, box-shadow, outlineou border-* propriétés. La disposition en grille, les flotteurs et la Flexbox ne fonctionnent pas non plus.

Vous pouvez toutefois utiliser CSS pour définir ou modifier une série de propriétés et de valeurs d’attributs SVG. La liste complète est présentée dans le document SVG 2 bien que la prise en charge par la plupart des navigateurs soit incomplète. Certaines propriétés CSS, telles que filter peuvent être utilisées avec SVG ou HTML. Nous en aborderons quelques-unes dans ce chapitre, dans le cadre de techniques spécifiques.

SVG manque d’un système de positionnement

Lorsque CSS est utilisé avec HTML, les cases des éléments peuvent :

  • exister dans un flux normal
  • être retiré du flux normal avec le float propriété
  • être retiré du flux normal avec le position propriété

La spécification CSS y fait référence en tant que schémas de positionnement. Les schémas de positionnement n’existent pas dans SVG. Le site position n’a aucun effet sur les éléments SVG. De même, les propriétés telles que top, left et bottomqui dépendent du positionnement des éléments. Vous ne pouvez pas non plus faire flotter des éléments dans un document SVG.

Au lieu de cela, SVG utilise un système de coordonnées pour le placement des éléments. Pour créer un <circle>par exemple, vous devez définir les coordonnées de son point central à l’aide de la balise cx et cy et définissez une longueur de rayon à l’aide de l’attribut r et définissez la longueur du rayon à l’aide de l’attribut r. Un polygone est constitué d’une série de coordonnées de points et de segments de ligne tracés entre eux. En d’autres termes, vous pouvez définir l’endroit où un élément sera dessiné dans le canevas SVG, mais vous ne pouvez pas le « positionner » au sens CSS du terme.

En relation avec les schémas de positionnement, SVG n’a pas non plus la notion de z-index et des contextes d’empilement.

Remarque : le SVG 2 La spécification définit un comportement pour z-index et les contextes d’empilement dans les documents SVG, mais la plupart des navigateurs ne le prennent pas encore en charge.

Les éléments SVG sont empilés en fonction de leur ordre d’origine. Ceux qui apparaissent plus tard dans le document sont placés en haut de la pile. Si vous souhaitez modifier l’ordre d’empilement des éléments SVG, vous devrez les déplacer dans la source ou utiliser JavaScript pour les réorganiser dans l’arbre DOM.

En fait, la plupart des propriétés CSS 2.1 ne s’appliquent pas aux documents SVG. Les exceptions sont les animations et les transformations, display, overflow, visibility, filteret quelques propriétés liées à la police et au texte. À la place, vous devrez utiliser Propriétés de style spécifiques à SVG pour les documents SVG. La plupart de ces propriétés peuvent également être exprimées en tant qu’attributs d’éléments SVG.

Stylisation des éléments SVG

Voici un exemple simple de la façon de styliser des éléments SVG à l’aide de CSS. Commençons par notre document SVG, qui est un fichier autonome :

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="https://www.gekkode.com/styles.css" type="text/css" ?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink=
➥"http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 497
➥ 184" enable-background="new 0 0 497 184" xml:space="preserve">
    <polygon id="star" points="77,23.7 98.2,66.6 145.5,66.5 111.2,
➥106.9,119.3,154 77,131.8 34.7,154 42.8,106.9 8.5,67.5 55.8,
➥66.6 "/>
    <circle id="circle" cx="245" cy="88.9" r="67.5"/>
</svg>

Ce balisage crée l’image ci-dessous.

Une image SVG simple de cercle et d'étoile

Bien que nous ne puissions pas utiliser la plupart des propriétés CSS avec les documents SVG, nous pouvons utiliser CSS pour changer la couleur d’un élément. Faisons en sorte que notre étoile soit jaune :

#star {
    fill: hsl( 44, 100%, 50% );
}

Vous verrez souvent l’élément fill utilisé avec les balises SVG, par exemple, <circle fill="rgb( 255, 185, 0 )" cx="3" cy="10" r="100"> – mais c’est aussi une propriété qui peut être utilisée avec les CSS.

Nous pouvons également utiliser les CSS pour ajuster les propriétés de l’élément. stroked’un élément, qui est le contour d’une forme SVG. Le contour d’une forme existe, même si aucun élément stroke n’est définie. Donnons à notre cercle une bordure en pointillés bleu foncé de dix pixels de large. Nous allons également définir sa propriété fill à cornflowerblue:

circle {
    fill: cornflowerblue;
    stroke: darkblue;
    stroke-width: 10;
    stroke-dasharray: 10, 15;
    stroke-linecap: round;
}

L’ensemble nous donne le résultat ci-dessous.

Une image SVG simple de cercle et d'étoile

Utiliser les attributs SVG comme propriétés CSS

Nous pouvons également utiliser le CSS pour définir les valeurs des coordonnées de certains éléments de forme : <rect>, <circle>et <ellipse>. Typiquement, nous utiliserions des attributs SVG pour ces éléments :

<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
    <rect x="20" y="200" width="300" height="300" fill="#f60" />
</svg>

Cependant, SVG 2 a redéfini certains attributs SVG en tant que propriétés géométriques. Cela signifie que nous pouvons utiliser CSS pour définir leurs valeurs :

<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
    <style type="text/css">
      rect {
          x: 20px;
          y: 50px;
          width:  300px;
          height: 300px;
          fill: #f60;
      }
    </style>
    <rect />
</svg>

Propriétés de coordonnées (x et y), les propriétés des coordonnées centrales (cx et cy), et les propriétés du rayon (rx, ryetr), peuvent être définis à l’aide de CSS. Il en va de même pour width et height. Les unités sont facultatives pour les attributs SVG. En revanche, les valeurs CSS sont facultatives, nécessitent unités. Les longueurs et les pourcentages sont tous deux valables pour les propriétés mentionnées ici, mais sachez que les longueurs fonctionnent un peu différemment avec les documents SVG. Rappelez-vous que le S de SVG signifie scalable. La taille calculée d’un élément SVG dépend également de :

  • La taille calculée width et height de l’élément SVG racine
  • La valeur de l’élément racine viewBox de l’attribut
  • Toute transformation d’échelle appliquée à l’élément ou à ses ancêtres.

En d’autres termes, les coins de notre <rect> élément sont (20, 50), (20, 320), (350, 320)et (20, 350) dans le système de coordonnées SVG. Cependant, les réel Les dimensions réelles peuvent être plus grandes ou plus petites, selon les facteurs ci-dessus.

Tous les attributs SVG ne sont pas disponibles via CSS – du moins pas dans tous les navigateurs. Par exemple, Chrome et Edge prennent en charge l’utilisation de l’attribut CSS path() pour définir les données de chemin, ou la fonction d ou l’attributd:

path {
    d: path("M 454.45223,559.21474 -304.96705,163.45948 417.4767,-296.33928 Z");
}

À ce jour, ce sont les seuls navigateurs qui le font. Travail pour ajouter le support dans Firefox et WebKit n’a pas encore commencé.

Pour les autres éléments de forme, la spécification de SVG 2 est carrément incohérente. A ce jour, vous doit utiliser les attributs des éléments pour définir les propriétés des <line>, <polyline>et <polygon> éléments.

Cela dit, nous ne sommes pas limités à l’utilisation de sélecteurs de type (ou d’élément) pour définir les propriétés. Nous pourrions, par exemple, définir des cercles petits, moyens et grands en utilisant des sélecteurs de classe :

<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
    <style type="text/css">

    .small {
        cx: 20px;
        cy: 20px;
        r:  20px;
        fill:  #0c0;
      }

      .medium {
        cx: 80px;
        cy: 80px;
        r:  60px;
        fill:  #fc0;
      }

      .large {
        cx: 220px;
        cy: 220px;
        r:  120px;
        fill: #00f;
      }

    </style>

    <circle class="small" />
    <circle class="medium" />
    <circle class="large" />
</svg>

Quel que soit le sélecteur, l’utilisation de la syntaxe CSS pour spécifier les propriétés permet également de les animer facilement. Nous verrons comment le faire dans la section suivante.

Animation et transition des propriétés CSS SVG

L’utilisation de CSS avec SVG devient plus intéressante lorsque nous ajoutons des transitions et des animations au mélange. Le processus est le même que pour l’animation d’éléments HTML avec CSS, mais avec des propriétés spécifiques à SVG. Créons un effet d’étoile scintillante à l’aide du document SVG suivant :

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px"
 y="0px" viewBox="0 0 497 184" xml:space="preserve">
    <defs>
        <link href="twinkle.css" type="text/css" rel="stylesheet"
 xmlns="http://www.w3.org/1999/xhtml"/>
    </defs>
    <polygon class="star" points="77,23.7 98.2,66.6 145.5,66.5 111.2
➥,106.9 119.3,154 77,131.8 34.7,154 42.8,106.9 8.5,67.5
➥ 55.8,66.6 "/>
    <polygon class="star twinkle" points="77,23.7 98.2,66.6 145.5,
➥66.5 111.2,106.9 119.3,154 77,131.8 34.7,154 42.8,106.9
➥ 8.5,67.5 55.8,66.6 "/>
</svg>

Notre document contient deux éléments polygonaux en forme d’étoile, chacun avec un nom de classe de star. Pour créer l’effet de scintillement, nous allons animer le premier élément. Voici notre CSS :

@keyframes twinkle {
    from {
        fill-opacity: .4;
    }
    to {
        fill-opacity: 0;
        transform: scale( 2 );
    }
}
.star {
    fill: rgb( 255,195,0 );
    transform-origin: 50% 50%;
}
.twinkle {
    animation: twinkle 1.5s infinite forwards ease-in;
}

Ici, nous avons utilisé la propriété spécifique à SVG fill-opacity. Comme avec CSS, si nous pouvons interpoler la valeur d’une propriété de style SVG, nous pouvons l’animer ou la faire passer. Vous pouvez voir deux points différents de l’animation dans l’image ci-dessous.

Notre animation d'étoile pulsée

Regardons un autre exemple. Cette fois, nous allons créer un effet de dessin en faisant passer l’élément stroke-dasharray . Voici notre document SVG :

<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
➥xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
        viewBox="0 0 200 200" enable-background="new 0 0 200 200">
    <circle fill="transparent" stroke-width="16" cx="101.3"
 cy="96.8" r="79.6"/>
</svg>

Le site stroke-dasharray accepte une liste de valeurs de longueur ou de pourcentage, séparées par des virgules, qui créent un motif en pointillés. Les valeurs impaires déterminent la longueur du tiret. Les valeurs paires déterminent la longueur de l’espace. A stroke-dasharray valeur de 5, 10 signifie que l’attaque sera 5px long avec un écart de 10px entre chaque tiret. Une valeur de 5, 5, 10 alterne avec 5px et 10px longueurs de tirets avec 5px entre les deux.

On peut utiliser stroke-dasharray pour créer un effet de dessin en commençant par une longueur de tiret nulle et un grand espace, et en terminant par une longueur de tiret importante et un espace de tiret nul. Nous ferons ensuite une transition entre les deux. Voici à quoi ressemble notre CSS :

circle {
    transition: stroke-dasharray 1s ease-in;
    fill: transparent;
    stroke-dasharray: 0, 500;
}
.animate {
    stroke-dasharray: 500, 0;
}

Au début de la transition, notre trait est invisible parce que la longueur du tiret est de 10 cm. 0 et notre espace est 500. Mais lorsque nous ajoutons le animate à notre cercle, nous déplaçons la longueur du tiret à 500 et éliminons l’écart. L’effet est un peu comme dessiner un cercle avec une paire de compas. Pourquoi 500 ? C’est la plus petite valeur qui a permis de créer cet effet particulier.

Un chemin d’avenir animé

Vous vous souvenez de notre exemple de définition d’un chemin via CSS dans la section précédente ? Un jour, nous pourrons peut-être animer les chemins dans tous les navigateurs, à l’aide de CSS :

path {
    d: path("M357.5 451L506.889 192.25H208.111L357.5 451Z");
    transition: d 1s ease-in-out;
}
.straighten {
    d: path("M357.5 8871L406 -10113.75H208.111L357.5 351Z");
}

À ce jour, cependant, seuls les navigateurs basés sur Chromium, tels que Google Chrome et Microsoft Edge, prennent en charge l’animation des définitions de chemin de cette manière. Pour que cela fonctionne dans d’autres navigateurs, utilisez une bibliothèque JavaScript telle que GreenSock et son MorphSVGPlugin. En plus de sa compatibilité avec les navigateurs, GreenSock et le MorphSVGPlugin facilitent le morphing entre deux formes, quel que soit le nombre de points dans chacune d’elles.

Utilisation de SVG avec Media Queries

Avec les documents HTML, nous pouvons afficher, cacher ou réorganiser des parties de la page en fonction des conditions de la fenêtre d’affichage. Si la fenêtre du navigateur a une largeur de 480 pixels, par exemple, nous pouvons faire passer notre navigation d’une liste horizontale à une liste verticale et pliable. Nous pouvons faire quelque chose de similaire avec les requêtes média et les documents SVG. Prenons un logo, tel que celui de la société fictive Hexagon Web Design & ; Development illustré ci-dessous.

Un logo bien réel pour une entreprise fictive

Sans media queries, ce logo SVG s’étirerait ou rétrécirait simplement pour s’adapter à la fenêtre d’affichage ou à son conteneur. Mais avec les requêtes média, nous pouvons faire des choses plus astucieuses.

Distinguons entre le viewport du document HTML et le viewport du document SVG. Lorsque SVG est en ligne, la fenêtre HTML et la fenêtre SVG sont identiques. Le document SVG se comporte comme n’importe quel autre élément HTML. D’autre part, lorsqu’un document SVG est lié – comme c’est le cas avec l’élément <iframe>, <object> ou <img> nous avons affaire à la fenêtre d’affichage du document SVG.

Les requêtes média fonctionnent dans les deux cas, mais lorsque le document SVG est lié, sa fenêtre d’affichage est indépendante de son document HTML. Dans ce cas, la taille de la fenêtre du navigateur ne détermine pas la taille de la fenêtre du document SVG. Au lieu de cela, la taille de la fenêtre d’affichage est déterminée par les dimensions du document <object>, <iframe>ou<img>élément. Prenons l’exemple du document SVG (abrégé) qui suit :

<svg version="1.1" id="HexagonLogo" xmlns="http://www.w3.org/2000/
➥svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
 viewBox="0 0 555 174" xml:space="preserve">
    <defs>
        <style type="text/css">
        /* CSS goes here */
        </style>
    </defs>
    <g id="hex">
        <polygon id="hexagonbg" points="55.2,162 10,86.5 55.2,11
➥ 145.5,11 190.7,86.5 145.5,162  "/>
        <path id="letterH" fill="#FFFFFF" d="M58,35.5h33v35.2h18.
➥4V35.5 h33.2v103.4h-33.2v-38.3H91v38.3H58V35.5z M77.5,126.5V87.
➥3h45.6v39.2h4V47.9h-4v35.6H77.5V47.9h-4v78.6H77.5z"/>
    </g>

    <g id="word-mark">
        <g id="hexagon-word">
            ...
        </g>
        <g id="web-design-and-dev">
            ...
        </g>
    </g>
</svg>

Note : une démonstration complète de cette technique, y compris la source complète de ce document SVG, est disponible dans le site web de la Commission européenne.

Dans des fenêtres plus petites, montrons seulement le H dans un symbole hexagonal :

@media (max-width: 320px) {
    [id=word-mark] {
        display: none;
    }
}

Maintenant, chaque fois que le conteneur de notre SVG est inférieur ou égal à 20emseule la partie symbole de notre logo sera visible.

Afficher/masquer les éléments en fonction de la taille de la fenêtre d'affichage SVG

Pour déclencher cette vue à partir du document HTML, définissez la largeur du conteneur SVG :

<iframe src="hexlogo.svg" style="width: 320px; border:0"></iframe>

Comme vous l’avez peut-être remarqué en regardant l’image ci-dessus, notre image SVG conserve ses dimensions intrinsèques même si une partie a été cachée. Ceci, malheureusement, est une limitation de SVG. Pour y remédier, nous devons modifier le paramètre viewBox du document SVG, mais uniquement lorsque la fenêtre d’affichage est inférieure à une certaine taille. C’est un excellent cas d’utilisation pour matchMedia

Le site viewBox comme son nom l’indique, détermine la zone visible d’un élément SVG. En l’ajustant, nous pouvons déterminer quelle partie d’une image SVG remplit la fenêtre d’affichage. Ce qui suit est un exemple utilisant matchMedia et d’une requête média pour mettre à jour l’image viewBox attribut :

<script type="text/javascript">
const svg = document.querySelector( 'svg' );

/* Store the original value in a variable */
const originalViewBox = svg.getAttribute( 'viewBox' );

/* Define our media query and media query object */
const mq = matchMedia( '( max-width: 320px )' );

/* Define the handler */
const updateViewBox = () {
    if (mq.matches) {
        /* Change the viewBox dimensions to show the hexagon */
        svg.setAttribute( 'viewBox', '0 0 200 174' );
    } else {
        svg.setAttribute( 'viewBox', originalViewBox );
    }
}

svg.addEventListener( 'SVGLoad', updateViewBox );

/* Fire if the media condition changes */
mq.addEventListener( 'change', updateViewBox );
</script>

Désormais, lorsque le conteneur SVG est inférieur ou égal à 320 pixels, la valeur de l’attribut viewBox sera "0 0 200 174". Lorsqu’elle dépasse 320 pixels, viewBox est rétabli à sa valeur initiale.

Ajustement de l'attribut viewBox en fonction de la largeur de la fenêtre d'affichage

Puisque cette technique utilise soit l’attribut onload ou l’attribut SVGLoad c’est une bonne idée d’intégrer nos CSS et JavaScript dans le fichier SVG. Lorsque le CSS est externe, l’attribut SVGLoad peut se déclencher avant la fin du chargement du CSS qui lui est associé.

Utilisation des requêtes média avec background-size

Les documents SVG et les requêtes média ne se limitent pas aux images de premier plan. Nous pouvons également redimensionner la fenêtre d’affichage SVG à l’aide de la requête CSS background-size propriété CSS.

Nous allons commencer avec ce document SVG :

<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
 xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
 viewBox="-20 -20 250 250" xml:space="preserve">
    <style type="text/css">
        circle {
            stroke: #000;
            stroke-width: 30;
            fill: #009688;
        }
        @media ( width: 100px ) {
            circle {
                fill: #673ab7;
            }
        }
        @media ( width: 300px ) {
            circle {
                fill: #ffc107;
            }
        }
    </style>
    </defs>
    <circle cx="100" cy="100" r="100" />
    <circle cx="100" cy="100" r="50" />
</svg>

C’est un cas simple. Notre site <circle> éléments reçoivent un nouveau fill à des largeurs de fenêtre spécifiques. Lorsque la fenêtre d’affichage a une largeur de 20 pixels, l’élément fill est sarcelle. Lorsqu’elle fait 300 pixels de large, elle est jaune.

Pour que cela fonctionne, nous devons utiliser notre image SVG comme image d’arrière-plan et définir l’attribut background-size du sélecteur. Dans le cas présent, nous utiliserons notre image comme arrière-plan pour la balise <body> et pour l’élément <li> éléments :

body, li  {
    background: url(circles.svg);
}
body  {
    background-color: #9c27b0;
    background-size: 300px auto;
}
li {
    background-position: left center;
    background-repeat: no-repeat;
    background-size: 1em auto;
    padding-left: 40px;
    font-size: 24px;
    margin: 1rem 0;
}

Le résultat est illustré ci-dessous.

Manipulation de la fenêtre d'affichage SVG avec la propriété CSS background-size

Conclusion

L’utilisation de SVG avec CSS nous donne plus de possibilités pour des documents flexibles et adaptatifs. Vous devriez maintenant savoir comment :

  • Utiliser les CSS pour styliser les éléments SVG
  • Animer les propriétés SVG
  • Employer les requêtes média CSS et le matchMedia API pour afficher et masquer des parties d’un document SVG.
Nouveau Tutoriel

Newsletter

Ne manquez jamais les nouveaux conseils, tutoriels et autres.

Pas de spam, jamais. Nous ne partagerons jamais votre adresse électronique et vous pouvez vous désabonner à tout moment.