X

Meilleure alternative SVG et direction artistique avec The Element – ​​Sara Soueidan, ingénieure en conception inclusive


Outre l’utilisation d’un SVG comme image d’arrière-plan dans CSS, vous pouvez servir des images de premier plan SVG en HTML en utilisant l’une des nombreuses techniques d’intégration, chacune ayant ses avantages et ses cas d’utilisation. Sauf si vous avez besoin d’interactivité ou de style externe, est la méthode standard pour charger une image SVG, mais elle présente un inconvénient : vous avez actuellement besoin de JavaScript pour fournir une solution de secours et/ou modifier la source de l’image pour la direction artistique. Dans ce post, je vais parler d’une meilleure façon de le faire, en utilisant le élément.

Ceci n’est pas une introduction à l’utilisation <picture>. Il existe de nombreuses ressources intéressantes dans la nature qui contiennent tout ce que vous devez savoir sur le <picture> élément, donc si vous n’êtes pas familier avec lui, reportez-vous à la dernière section de l’article pour une liste de ressources pour tout savoir à ce sujet. Cela étant dit, l’article ne nécessite aucun élément particulier ou fort <picture> compétences, car les exemples sont pour la plupart explicites comme vous le verrez.

Cet article est également disponible en russe.

Avant d’entrer dans le pourquoi <picture> est une excellente option pour SVG, exposons (un aperçu) les limites et les inconvénients de l’utilisation <img> pour un travail SVG réactif.

Normalement, si vous chargez un SVG en utilisant un <img> , vous pouvez fournir une solution de secours et modifier la source de l’image sur différentes tailles de fenêtre d’affichage à l’aide de la détection de fonctionnalités et des requêtes multimédias en JavaScript. Mon choix pour les deux serait d’utiliser Modernizr pour les deux ; c’est-à-dire, à moins que vous ne serviez qu’une seule image, auquel cas l’ajout de Modernizr pourrait être une surcharge de travail, et quelque chose comme ceci :

<img src="logo.svg" onerror="this.src=logo-fallback.png;this.onerror=null;" />

…serait plus simple et plus rapide.

En utilisant Modernizr, vous pouvez détecter la prise en charge du SVG par le navigateur et fournir une image alternative src lorsque SVG n’est pas pris en charge. L’URL de l’image alternative peut être stockée dans un attribut de données personnalisé. Cette approche est particulièrement utile lorsque vous avez plusieurs images sur la page dont src vous devez changer.

<img src="logo.svg" data-fallback="logo.png" />

À l’aide de Modernizr, vous pouvez détecter si le navigateur prend en charge SVG ou non, puis prendre les mesures nécessaires pour fournir la solution de secours en fonction du résultat du test :

if (!Modernizr.svg) {

}

Vous pouvez également utiliser la détection de requête multimédia de Modernizr pour modifier l’img src en fonction de la largeur de la fenêtre d’affichage lorsque vous souhaitez faire de la direction artistique et ne pas charger le même gros SVG sur des écrans plus petits :

if (Modernizr.mq('(max-width: 640px)')) {

}

Vous n’avez pas besoin de stocker d’URL dans les attributs de données dans ce cas si vous suivez une convention de dénomination spécifique pour vos images. Par exemple, si vos images sont nommées view-small.svg, view-big.svgvous pouvez simplement remplacer le view-* séparez-vous de celui qui convient dans le JavaScript et finissez-en.

Maintenant, si vous souhaitez fournir une alternative PNG ou JPEG pour votre SVG et fournir également différentes tailles de cette image de secours pour correspondre à la taille de la fenêtre d’affichage, Modernizr le fera également, mais cela deviendra un peu plus compliqué. Et la partie la plus importante est la suivante : vous avez besoin de JavaScript pour le faire.

Avec le <picture> élément, nous pouvons faire tout cela et plus encore, sans JavaScript. Bon type de. Continuer à lire.

Le <picture> L’élément nous fournit un meilleur moyen sans JavaScript de modifier l’image que nous servons en fonction de différentes requêtes multimédias et a pour fournir une solution de secours aux navigateurs non compatibles (ou aux navigateurs qui ne peuvent pas charger le SVG pour une raison quelconque).

Commençons d’abord par le repli. Fournir une solution de secours aux navigateurs qui ne peuvent pas charger le SVG est aussi simple que d’envelopper votre <img> repli dans un <picture> élément et référencer votre SVG dans un <source> élément:

<picture>
<source type="image/svg+xml" srcset="path/to/image.svg">
<img src="path/to/fallback.png" alt="Image description">
</picture>

Le <picture> L’élément n’est qu’un wrapper pour les éléments utilisés pour charger l’image ou les images souhaitées et pour la solution de secours fournie avec l’élément <img> élément. Le <img> l’élément est requis pour <picture> pour fonctionner et est utilisé pour fournir une rétrocompatibilité pour les navigateurs qui ne prennent pas en charge <picture> ou, comme dans notre cas ici, les navigateurs qui ne peuvent pas charger ou ne prennent pas en charge les images [type] vous chargez dans le <source> élément.

Le <source> L’élément est l’endroit où nous spécifions la ou les images que nous voulons. Nous spécifions le type d’image que nous voulons (SVG) dans le type attribut, et en fournissant l’URL de cette image dans le srcset attribut. Et c’est tout ce qu’il y a vraiment à faire; c’est comme ça qu’il est simple de fournir une solution de secours pour une image SVG en utilisant <picture>— aucun JavaScript n’est nécessaire.

Vous pouvez aller encore plus loin et fournir plusieurs images de secours qui tiennent compte de la résolution de l’écran ; pour ce faire, vous pouvez spécifier ces images en utilisant le srcset attribut sur le <img>. Par exemple:

<picture>
<source type="image/svg+xml" srcset="path/to/logo.svg">
<img src="path/to/logo-1x.png" srcset="path/to/logo-2x.png 2x, path/to/logo-3x.png 3x" alt="Logo description">
</picture>

Le navigateur peut alors choisir l’image qu’il juge appropriée en fonction de la résolution de l’écran. Ceci est utile lorsque vous diffusez la même taille d’image (par exemple, un logo taille unique) mais que vous souhaitez fournir des versions 2x et 3x pour des résolutions plus élevées.

Mais si tu veux tu peux même le prendre plus loin. Avec l’aide du sizes vous pouvez utiliser des requêtes multimédias sur l’attribut <img> pour modifier la taille de l’image de secours sur différentes tailles d’écran, en fournissant une image plus grande pour les écrans plus grands et une plus petite pour les petits écrans.

<picture>
<source type="image/svg+xml" srcset="path/to/banner.svg">
<img
sizes="(min-width: 640px) 80vw, 100vw"
srcset="banner-300.jpg 300w,
banner-400.jpg 400w,
banner-700.jpg 700w,
banner-1200.jpg 1200w,
banner-1600.jpg 1600w,
banner-2000.jpg 2000w"

src="banner-default-fallback.jpg"
alt="Banner description">

</picture>

Ce que nous avons fait ici, c’est que nous avons dit au navigateur dans le sizes attribuer la taille que notre image occupera sur la page. Dans ce cas, si la largeur de la fenêtre d’affichage est de 640 px ou plus, l’image aura 80 % de la largeur de la fenêtre d’affichage et 100 % de la largeur dans le cas contraire.

Puis, dans le srcset , nous avons fourni au navigateur une liste d’images – elles sont toutes de la même image, mais dans des tailles différentes. Basé sur les tailles spécifiées dans sizesle navigateur choisira celle qui correspond le mieux à ces images et l’affichera.

Si un navigateur ne prend pas en charge srcset sur <img>il affichera simplement le repli spécifié dans le src attribut. Pour une explication détaillée de la façon dont cela fonctionne, reportez-vous à cet article sur A List Apart.

Le <source> L’élément que nous utilisons pour spécifier la ou les images que nous voulons est accompagné d’un autre attribut : media. Cet attribut nous offre la même flexibilité que nous avons pour modifier les images d’arrière-plan dans CSS à l’aide de requêtes média CSS, en nous permettant d’associer des sources d’images à des conditions de mise en page (les requêtes média) directement dans le code source.

Étant donné que nous servons une image SVG, nous n’avons pas besoin de servir plusieurs versions de l’image pour différentes résolutions d’écran en raison de la nature infiniment évolutive de SVG, ce qui lui donne une belle apparence sur n’importe quelle résolution. (Yay!)

Mais si nous avons un SVG que nous servons sur le bureau, par exemple, une image d’en-tête large, cette image pourrait avoir une taille de centaines de kilo-octets. Servir la même grande image pour les petits écrans n’est peut-être pas la meilleure idée si vous la regardez sous l’angle des performances. De plus, peut-être que vous venez de ne veux pas pour servir la même image sur des tailles plus petites, mais une version “recadrée” de cette image. J’ai récemment travaillé sur un projet client qui nécessitait exactement cela. Non seulement mon client voulait des images différentes sur des tailles plus petites, mais la composition complète faisait plus de 100 Ko, ce qui est évidemment trop pour être diffusé sur des appareils mobiles, nous avons donc servi des versions recadrées de cette image.

Dans ce cas, vous pouvez spécifier différents SVG à charger sur différentes conditions de support à l’aide de la commande media attribut sur le <source>. Dans le media vous spécifiez les conditions multimédias de la même manière que vous le faites dans les requêtes multimédias CSS.

<picture>
<source
media="(max-width: 640px)"
srcset="header--small.svg"
type="image/svg+xml">

<source
media="(max-width: 1024px)"
srcset="header--medium.svg"
type="image/svg+xml">

<source
srcset="header--full.svg"
type="image/svg+xml">


<img src="header--default-fallback.jpg" alt="Header description..">
</picture>

Bien sûr, vous pouvez spécifier différentes images de secours pour différentes résolutions et tailles, comme nous l’avons fait dans la section précédente. Par souci de brièveté, je vais sauter cette étape dans cette section, mais vous obtenez l’image. (Regarde ce que j’ai fait là?)

Vous pouvez également spécifier plusieurs tailles pour chaque image SVG et laisser le navigateur choisir celle qu’il trouve la meilleure, comme nous l’avons fait pour l’image de secours auparavant. Cependant, en raison de la nature évolutive de SVG, cela peut ne pas être nécessaire.

En effet, les options du <picture> L’élément est livré avec une couverture pratiquement n’importe quel scénario. Cet article sur le blog dev.opera couvre un grand nombre de ces cas d’utilisation avec des exemples pratiques et des extraits pour vous aider à démarrer.


Alors, voyez-vous, avec le <picture> élément, nous n’avons plus besoin d’utiliser JavaScript pour fournir un remplacement et/ou modifier l’image en fonction de différentes conditions de support. Bon type de…

Au moment de la rédaction de cet article, la prise en charge des navigateurs pour <picture> n’est pas à son meilleur, mais il s’améliore. Beaucoup de gens intelligents travaillent sur <picture> mise en œuvre sur tous les navigateurs. Gardez un œil sur le tableau de compatibilité sur CanIUse.com pour rester à jour sur la prise en charge du navigateur à l’avenir.

En attendant, et jusqu’à ce que la prise en charge des navigateurs devienne plus décente, vous pouvez utiliser un polyfill JavaScript pour les navigateurs non compatibles. Alors oui, nous avons besoin de JavaScript pour le moment, mais le code que vous écrivez sera à l’épreuve du temps et tout ce que vous aurez à faire à l’avenir, lorsque le support s’améliorera, sera de supprimer le polyfill, et votre code fonctionnera sans lui comme prévu. En utilisant <img> vous auriez besoin de faire beaucoup plus, ou, du moins, de continuer à utiliser Javascript.

Le polyfill Picturefill par les gens du groupe Filament est le courant de facto pour les navigateurs croisés <picture> soutien aujourd’hui. La page d’accueil de polyfill contient une documentation complète sur la façon d’utiliser le polyfill et des conseils sur l’utilisation <picture> en général avec des modèles généraux.

L’utilisation du polyfill est aussi simple que d’inclure le script dans le head:

<script src="picturefill.js" async></script>

Le async L’attribut indique au navigateur qu’il peut charger le remplissage d’image de manière asynchrone, sans attendre qu’il se termine avant de charger le reste du document. Selon la documentation Picturefill, si vous ajoutez cet attribut, vous devrez également ajouter une ligne de script avant la balise de script pour permettre aux anciens navigateurs de reconnaître picture éléments s’il les rencontre dans la page avant que Picturefill ait fini de se charger.

<script>

document.createElement( "picture" );
</script>
<script src="picturefill.js" async></script>

Si vous connaissez HTML5 Shiv, vous savez déjà à quoi sert cette ligne. En fait, si vous incluez déjà une version récente de HTML5 Shiv (parfois fournie avec Modernizr), vous n’aurez peut-être pas besoin de cette ligne car elle y est également incluse.

Alors que la plupart des versions d’IE (même les plus anciennes !) sont prises en charge [by Picturefill] Eh bien, IE9 a un petit conflit à contourner. Pour prendre en charge IE9, vous devrez encapsuler un video enveloppe d’élément autour du source éléments dans votre picture étiqueter. Vous pouvez le faire en utilisant des commentaires conditionnels. — Page d’accueil Picturefill

Comme le dit la documentation, le polyfill fournit un support pour <picture> à travers les navigateurs, mais IE9 exige que vous encapsuliez votre source éléments dans un video étiqueter. Et comme ce correctif n’est requis que pour IE9, vous pouvez le placer dans les commentaires conditionnels ciblant IE9 :

<picture>

<source srcset=".." type=".." >
<source srcset=".." type=".." >
<source srcset=".." type=".." >

<img src=".." alt=".." />
</picture>

Comme mentionné au début de l’article, le <img> élément, et naturellement le <picture> ne permet de charger qu’une image SVG statique, ou un SVG avec des animations définies en interne. Si vous devez charger une image de premier plan et que vous souhaitez que cette image soit interactive et stylisée, vous pouvez utiliser l’une des quatre méthodes disponibles : <object>, <iframe>, <embed> et en ligne <svg>.

Les deux <iframe> et <object> viennent avec un mécanisme de repli par défaut.

<object data="image.svg" type="image/svg+xml">

</object>

<iframe src="image.svg">

</iframe>

Un en ligne <svg> nécessite une approche différente pour fournir des solutions de repli ; une de ces approches utilise le <foreignObject> élément. Vous pouvez lire ici tout ce qui concerne ce sujet. Chris a également écrit sur la fourniture de secours pour SVG ici.

En utilisant <picture> nécessite actuellement l’ajout d’un polyfill JavaScript, l’utilisation du balisage HTML5 standard et la possibilité de changer d’image à l’aide d’éléments natifs est extrêmement puissant, et brancher le polyfill est aussi simple que 1. le télécharger, 2. ajouter un script à la page, 3. vous ‘est fait. Cela en vaut vraiment la peine si vous faites de la direction artistique ou si vous fournissez une solution de secours pour plusieurs images SVG de premier plan.

<picture> est plus susceptible de devenir le moyen standard de direction artistique SVG et de fournir img repli à l’avenir, alors pourquoi commencer à l’utiliser aujourd’hui ? Les deux img chemin et le nouveau picture nécessitent du JavaScript – pour le moment, mais ce dernier est définitivement plus propre et plus évolutif. Oui, img est également à l’épreuve du temps, mais à un moment donné, vous pouvez abandonner le polyfill et garder votre code inchangé si vous utilisez picturealors que img vous demandera soit de continuer à utiliser JavaScript ou refactorisez votre balisage pour passer à l’absence de JavaScript picture.

Que vous décidiez de commencer à utiliser <picture> pour SVG aujourd’hui ou non, il vaut vraiment la peine de mieux le connaître et de l’utiliser pour servir d’autres formats d’image réactifs. Voici donc une liste d’articles recommandés pour vous aider à démarrer :