1478 sujets

Web Mobile et responsive web design

Bonjour,
Auriez vous des stats de performances de pages web comparant les performances avec font icon Vs avec images svg ?

Qu'utilisez vous de votre côté pour vos pictos et pourquoi ?

Merci Smiley biggrin
parsimonhi a écrit :
Bonjour,

C'est quoi "font icon" ?

Amicalement,


Il s'agit de créer une police via icomoon par exemple, en utilisant des picto vectoriel.
https://fontawesome.com/ utilise ce principe.

Cela a pour but de facilité les modifications sur les pictos (tailles, couleurs, animations)
Limiter le nombre de requête au serveur (1 appel à la police VS autant d'appel que de balise img)
Cela évite de mettre des illustrations décoratives en balise image (car concrètement pour le SEO, on s'en fout d'indexer une icone de loupe ou de flèche)
Modifié par jhabai (24 Mar 2023 - 09:44)
Modérateur
Bonjour,

Je vois.

Même s'il y avait un test de performance disponible, il ne serait pas forcément significatif car il me semble qu'il y a énormément de cas de figure différents d'un site à l'autre selon le nombre, la complexité et la manière de coder ces icones.

Si le poids en octet de ta "font icon" est bien optimisée (ne contenant par exemple que les icones du site sur lequel tu l'installes), ça pourrait être plus rapide que de charger des icones ayant chacune leur code svg dans un fichier distinct. Mais comme on peut aussi regrouper les svg dans un fichier unique, c'est peu clair qu'on gagne quelque chose avec une "font icon" si on optimise aussi correctement la méthode "images svg". Et puis, tout ça se retrouve vite en cache dans le navigateur.

Pour mes sites, j'utilise des fichiers svg individuels contenant chacun une icone, car je considère que combiner nécessite d'y passer pas mal de temps lors du développement si on veut optimiser correctement, et ferait gagner assez peu de toutes façons pour les visiteurs vu que les fichiers en question se retrouvent vite en cache et qu'ils ne sont pas très nombreux pour un site donné en général.

Amicalement,
Modifié par parsimonhi (24 Mar 2023 - 10:21)
Modérateur
Salut !

Effectivement coté perf j'ai pas de data mais je pense pas que ca change grand chose surtout de nos jours.

Ca va surtout dépendre de l'usage que tu veux en faire et de tes préférences personnelles.

Pour ma part je suis full font icon, je trouve ca léger et hyper pratique à mettre en place. La plupart du temps je passe par fontawesome (ou autre) et sinon je fait des font-icon perso (en SVG puis compilé grâce a un outil comme fontello). Au travail on a même fait notre propre générateur de font-icon basé sur les fichier svg des icones que l'ont produit.

Le seul blocage c'est pour les animations, c'est très limité avec une font. Le SVG restera gagnant la dessus (mais il doit etre inline dans le html pour profiter de tout les avantages des animations).

Une autre limitation de la font peut etre la couleur appliquée. On ne peut pas avoir des icones trop colorée c'est essentiellement du monochrome.
J'avais fait fait un POC de font-icon en double couleur pour donner un peu de fun dans mes icones. On peut facilement le décliner en plus de couleurs mais ca demande un peu de taff pour tout bien superposer : https://undless.github.io/bigoo/
FontAwesome a commencé a le faire dans sa dernière version aussi mais jme suis pas penché sur leur technique https://fontawesome.com/search?s=duotone&f=classic&o=r

Bonne journée
Modérateur
Bonjour

_laurent a écrit :
Le seul blocage c'est pour les animations, c'est très limité avec une font. Le SVG restera gagnant la dessus (mais il doit etre inline dans le html pour profiter de tout les avantages des animations).


On peut aussi mettre du css dans du code svg auquel cas il me semble que même sous forme de "font icon" fabriquée avec un outil approprié, on pourrait avoir des animations diverses et variées. Ceci étant je n'ai pas essayé, et ça devrait effectivement être quand même moins souple qu'avec du svg directement inséré dans le code html.

Amicalement,
Modifié par parsimonhi (24 Mar 2023 - 10:52)
Bonjour,

Auparavant j'utilisais un script pour convertir un dossier remplit de SVGs en font icons, mais désormais je convertis le dossier en sprites SVG.

Ça donne ça par exemple : icones.

C'est bien plus souple d'utilisation qu'une font icons (multicolore notamment), et ça évite les artfacts (les carrés blancs) lors des lags.

Le seul point qui reste en faveur des font icons c'est leur capacité à être utilisées avec des pseudo-éléments. Là, avec les SVG, je n'ai pas encore trouvé de solution.
Modifié par Olivier C (24 Mar 2023 - 22:53)
Modérateur
Bonjour,

Après avoir pas mal cherché, et contrairement à ce que j'ai écris un peu plus haut, il semble qu'on ne puisse pas mettre de css "à l'intérieur" d'une "font-icon" que l'on utiliserait ensuite dans du html comme on le fait avec FontAwesome.

Amicalement,
Modérateur
Bonjour,

Olivier C a écrit :
Le seul point qui reste en faveur des font icons c'est leur capacité à être utilisées avec des pseudo-éléments. Là, avec les SVG, je n'ai pas encore trouvé de solution.


Pour les pseudo-éléments, on peut utiliser la balise <view> au lieu de <symbol>. Par exemple, si on a 2 icônes qui seraient un triangle et un carré, on met dans le svg (qu'on va nommer par exemple "icons.svg") :
<svg width="32" height="32" viewBox="0 0 32 64" xmlns="http://www.w3.org/2000/svg">
<!-- triangle icon -->
<view id="triangle" viewBox="0 0 32 32"/>
<g><path d="M8 24H24L16 8z"/></g>
<!-- square icon -->
<view id="square" viewBox="0 32 32 32"/>
<g transform="translate(0,32)"><path d="M8 8H24V24H8z"/></g>
</svg>

Le html peut être :
<span class="pseudoTriangle"></span>
<span class="pseudoSquare"></span>

Et le css peut être :
span::before {
	display:inline-block;
	width: 32px;
	height: 32px;
	overflow:hidden;
}
span.pseudoTriangle::before {
	content:url("icons.svg#triangle");
}
span.pseudoSquare::before {
	content:url("icons.svg#square");
}
Si le pseudo-élément doit avoir une taille différente de la taille des icônes, on peut s'en sortir en utilisant la propriété transform dans le css. Dans l'exemple ci-dessus, si on veut des pseudo-éléments carrés de 16px de côté, on rajoutera :
span::before {transform: scale(0.5) translate(0, 16px);}


Amicalement,
Merci Parsimonhi, très intéressant. Je n'avais pas vu passer cette technique, c'est une nouvelle piste à explorer, il faudra que je prenne le temps de l'évaluer.
Modérateur
parsimonhi a écrit :
Bonjour,
Pour les pseudo-éléments, on peut utiliser la balise &lt;view&gt; au lieu de &lt;symbol&gt;. Par exemple, si on a 2 icônes qui seraient un triangle et un carré, on met dans le svg (qu'on va nommer par exemple "icons.svg") :
&lt;svg width="32" height="32" viewBox="0 0 32 64" xmlns="http://www.w3.org/2000/svg"&gt;
&lt;!-- triangle icon --&gt;
&lt;view id="triangle" viewBox="0 0 32 32"/&gt;
&lt;g&gt;&lt;path d="M8 24H24L16 8z"/&gt;&lt;/g&gt;
&lt;!-- square icon --&gt;
&lt;view id="square" viewBox="0 32 32 32"/&gt;
&lt;g transform="translate(0,32)"&gt;&lt;path d="M8 8H24V24H8z"/&gt;&lt;/g&gt;
&lt;/svg&gt;

Le html peut être :
&lt;span class="pseudoTriangle"&gt;&lt;/span&gt;
&lt;span class="pseudoSquare"&gt;&lt;/span&gt;

Et le css peut être :
span::before {
	display:inline-block;
	width: 32px;
	height: 32px;
	overflow:hidden;
}
span.pseudoTriangle::before {
	content:url("icons.svg#triangle");
}
span.pseudoSquare::before {
	content:url("icons.svg#square");
}
Si le pseudo-élément doit avoir une taille différente de la taille des icônes, on peut s'en sortir en utilisant la propriété transform dans le css. Dans l'exemple ci-dessus, si on veut des pseudo-éléments carrés de 16px de côté, on rajoutera :
span::before {transform: scale(0.5) translate(0, 16px);}

Amicalement,

Ca fait beaucoup de bazar a coté d'un :
<span class="icon-firefox"></span>

.icon-firefox:before {
    content: '\e801';
}


Smiley lol Smiley lol Smiley lol
Modérateur
Bonjour,

_laurent a écrit :

Ca fait beaucoup de bazar a coté d'un :
<span class="icon-firefox"></span>

.icon-firefox:before {
    content: '\e801';
}

Hum, tu triches un peu, là ! Smiley cligne

D'abord tu oublies de préciser qu'il faut bien "aussi" pour une font-icon mettre au point et charger le fichier de la police de caractères. Et en gros le contenu de ce fichier correspond au contenu du fichier icons.svg que j'ai indiqué un peu plus haut.

Et ensuite, on peut très bien avec les images svg se contenter de :
<span class="iconSquare"></span>

.iconSquare::before {
	content:url("icons.svg#square");
}
Le reste de ce que j'avais mis n'était qu'un exemple de style qu'on pouvait appliquer pour adapter la présentation.

Et enfin, comme tu l'écrivais, les font-icons sont assez limitées par rapport aux images svg. Par exemple :

1) On ajoute du css et 2 icônes animées au fichier icons.svg précédent (dont on peut envisager qu'il soit mis au point par des organisations tierces comme l'est la police fontAwesome) :
<svg width="32" height="32" xmlns="http://www.w3.org/2000/svg">
<style>
<![CDATA[
@keyframes a {
	to {
		stroke-dashoffset:0;
	}
}
.animated path {
	animation:a 5s linear forwards 1s;
	stroke-dasharray:104;
	stroke-dashoffset:106;
	fill:#0ff;
	stroke:#f00;
	stroke-width:2;
	stroke-linecap:round;
	stroke-linejoin:round;
}
]]>
</style>
<!-- square icon -->
<view id="square" viewBox="0 0 32 32"/>
<g><path d="M8 8H24V24H8z"/></g>
<!-- triangle icon -->
<view id="triangle" viewBox="0 32 32 32"/>
<g transform="translate(0,32)"><path d="M8 24H24L16 8z"/></g>
<!-- animated colored square icon -->
<view id="animatedSquare" viewBox="0 64 32 32"/>
<g class="animated" transform="translate(0,64)"><path pathLength="100" d="M8 8H24V24H8z"/></g>
<!-- animated colored triangle icon -->
<view id="animatedTriangle" viewBox="0 96 32 32"/>
<g class="animated" transform="translate(0,96)"><path pathLength="100" d="M8 24H24L16 8z"/></g>
</svg>
Note : on remarquera que le css peut être commun à plusieurs icônes.

Ensuite, le développeur d'un site a juste à mettre quelque chose du genre :
2) Dans le code css :
span.iconAnimatedSquare::before {
	content:url("icons.svg#animatedSquare");
}
3) Dans le code html :
<span class="iconAnimatedSquare"></span>

Note : évidemment, l'utilisation des images svg du fichier icons.svg n'est pas limitée aux pseudo-elements. Elles peuvent aussi être utilisées dans une balise <img>, dans un background css, etc.

Amicalement,
Modifié par parsimonhi (26 Mar 2023 - 12:50)
@Laurent : j'y vois un intérêt pour traiter les pseudo éléments (que n'arrivent pas à atteindre les sprites SVG).

Parce qu'ensuite, pour tous les autres cas de figure, les sprites SVG restent extrêmement simples dans leurs mise en œuvre :
<svg class="icon" role="img" focusable="false">
  <use href="/sprites/util.svg#ampersand"></use>
</svg>
Modérateur
Bonjour,

Olivier C a écrit :
@Laurent : j'y vois un intérêt pour traiter les pseudo éléments (que n'arrivent pas à atteindre les sprites SVG).


Il me semble que ça peut aussi servir quand on utilise la propriété css background-image. D'une manière générale, ça sert partout où on peut utiliser un url() comme valeur d'une propriété dans le css.

Amicalement,
Modérateur
Bonjour,

Ci-dessous quelques tests variés pour ceux qui veulent aller plus loin. Attention, il y a quelques passages non-triviaux, en particulier pour forcer les éventuelles animations des icônes à être rejouer quand on rafraîchit la page. La variable css --s sert à zoomer les icônes. Je n'ai pas réussi à faire fonctionner l'exemple "Inline svg (<view>) + <use>" sous firefox. S'il y en a un qui y arrive, je suis preneur.

EDIT: j'ai finalement trouvé une manière de faire fonctionner l'exemple "Inline svg (<view>) + <use>" sous firefox. Il fallait remplacer :
svg.svgViewIcons g {
	transform: scale(var(--s));
}
par
g[id$="G"] {
	transform: scale(var(--s));
}
Les raisons pour lesquelles ça ne marchait pas sous firefox sont un peu complexes. En gros, la manière de styler quelque chose qui est dans le shadow DOM est délicate (pour ceux qui veulent tout comprendre, ils peuvent essayer de lire https://stackoverflow.com/questions/27866893/svg-fill-not-being-applied-in-firefox pour avoir un aperçu des difficultés à ce propos). J'ai fait la modification dans le code ci-dessous qui est donc prêt à l'emploi.

1) le fichier html (qui est en fait du php et doit donc avoir l'extension .php)
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
:root {
  --s: 3;
}
body {
	margin: 0;
	padding: 1em;
}
svg, span, img, object {
	display: inline-block;
	width: calc(var(--s) * 32px);
	height: calc(var(--s) * 32px);
	border-radius: 50%;
	background: #eee;
}
svg.hidden {
	display: none;
}
span.triangle,
span.square,
span.disk,
span.animatedTriangle,
span.animatedSquare,
span._L {
	background-repeat: no-repeat;
	background-size: 100% 100%;
}
span.triangle {
	background-image: url("icons-view.svg#triangle");
}
span.square {
	background-image: url("icons-view.svg#square");
}
span.disk {
	background-image: url("icons-view.svg#disk");
}
span.animatedTriangle {
	background-image: url("icons-view.svg?z=<?=rand()?>#animatedTriangle");
}
span.animatedSquare {
	background-image: url("icons-view.svg?z=<?=rand()?>#animatedSquare");
}
span._L {
	background-image: url("icons-view.svg?z=<?=rand()?>#_L");
}
span::before {
	display: inline-block;
	width: 32px;
	height: 32px;
	transform: scale(var(--s));
	transform-origin: top left;
	border-radius: 50%;
}
span.pseudoTriangle::before {
	content: url("icons-view.svg#triangle");
}
span.pseudoSquare::before {
	content: url("icons-view.svg#square");
}
span.pseudoDisk::before {
	content: url("icons-view.svg#disk");
}
span.pseudoAnimatedTriangle::before {
	content: url("icons-view.svg?z=<?=rand()?>#animatedTriangle");
}
span.pseudoAnimatedSquare::before {
	content: url("icons-view.svg?z=<?=rand()?>#animatedSquare");
}
span.pseudo_L::before {
	content: url("icons-view.svg?z=<?=rand()?>#_L");
}
g[id$="G"] {
	transform: scale(var(--s));
}
</style>
</head>
<body>
<h1>Svg &lt;symbol&gt; vs &lt;view&gt;</h1>
<h2>Inline svg (&lt;symbol&gt;) + &lt;use&gt;</h2>
<?php include "icons-symbol.svg";?>
<svg><use href="#triangleS"/></svg>
<svg><use href="#squareS"/></svg>
<svg><use href="#diskS"/></svg>
<h2>Inline svg (&lt;view&gt;) + &lt;use&gt;</h2>
<?php include "icons-view.svg";?>
<svg><use href="#triangleG"/></svg>
<svg><use href="#squareG"/></svg>
<svg><use href="#diskG"/></svg>
<h2>External svg (&lt;view&gt;) + &lt;span&gt; + css background-image</h2>
<span class="triangle"></span>
<span class="square"></span>
<span class="disk"></span>
<span class="animatedTriangle"></span>
<span class="animatedSquare"></span>
<span class="_L"></span>
<h2>External svg (&lt;view&gt;) + &lt;span&gt; + css pseudo-element</h2>
<span class="pseudoTriangle"></span>
<span class="pseudoSquare"></span>
<span class="pseudoDisk"></span>
<span class="pseudoAnimatedTriangle"></span>
<span class="pseudoAnimatedSquare"></span>
<span class="pseudo_L"></span>
<h2>External svg (&lt;view&gt;) + &lt;img&gt;</h2>
<img src="icons-view.svg#triangle">
<img src="icons-view.svg#square">
<img src="icons-view.svg#disk">
<img src="icons-view.svg?z=<?=rand()?>#animatedSquare">
<img src="icons-view.svg?z=<?=rand()?>#animatedTriangle">
<img src="icons-view.svg?z=<?=rand()?>#_L">
<h2>External svg (&lt;view&gt;) + &lt;object&gt;</h2>
<object type="image/svg+xml" data="icons-view.svg#triangle"></object>
<object type="image/svg+xml" data="icons-view.svg#square"></object>
<object type="image/svg+xml" data="icons-view.svg#disk"></object>
<object type="image/svg+xml" data="icons-view.svg#animatedSquare"></object>
<object type="image/svg+xml" data="icons-view.svg#animatedTriangle"></object>
<object type="image/svg+xml" data="icons-view.svg#_L"></object>
</body>
</html>

2) Le fichier icons-symbol.svg
<svg class="hidden svgSymbolIcons" width="32" height="32" xmlns="http://www.w3.org/2000/svg">
	<symbol id="triangleS" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
		<path d="M8 24H24L16 8z"/>
	</symbol>
	<symbol id="squareS" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
		<path d="M8 8H24V24H8z"/>
	</symbol>
	<symbol id="diskS" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
		<circle cx="16" cy="16" r="8"/>
	</symbol>
</svg>

3) Le fichier icons-view.svg
<svg class="hidden svgViewIcons" width="32" height="32" xmlns="http://www.w3.org/2000/svg">
<style>
<![CDATA[
@keyframes a {
	to {
		stroke-dashoffset:0;
	}
}
.animated path {
	animation:a 5s linear forwards 1s;
	stroke-dasharray:104;
	stroke-dashoffset:106;
	fill:#0ff;
	stroke:#f00;
	stroke-width:2;
	stroke-linecap:round;
	stroke-linejoin:round;
}
]]>
</style>
<!-- square icon -->
<view id="square" viewBox="0 0 32 32"/>
<g id="squareG"><path d="M8 8H24V24H8z"/></g>
<!-- triangle icon -->
<view id="triangle" viewBox="0 32 32 32"/>
<g id="triangleG" transform="translate(0,32)"><path d="M8 24H24L16 8z"/></g>
<!-- animated colored square icon -->
<view id="animatedSquare" viewBox="0 64 32 32"/>
<g id="animatedSquareG" class="animated" transform="translate(0,64)"><path pathLength="100" d="M8 8H24V24H8z"/></g>
<!-- animated colored triangle icon -->
<view id="animatedTriangle" viewBox="0 96 32 32"/>
<g id="animatedTriangleG" class="animated" transform="translate(0,96)"><path pathLength="100" d="M8 24H24L16 8z"/></g>
<!-- _L icon -->
<style>
<![CDATA[
.animated path[clip-path="url(#_Lclip)"] {
	stroke-width:33;
	fill:none;
	stroke:#1cace4;
	stroke-linecap:butt;
	stroke-linejoin:miter;
}
#_Lshape {fill:none;stroke:none;}
}
]]>
</style>
<view id="_L" viewBox="0 128 200 200"/>
<g id="_LG" class="animated" transform="translate(0,128)">
<path id="_Lshape" d="M 28,58H172L162,75H57L100,150L131,96H150L100,183Z"/>
<defs><clipPath id="_Lclip"><use href="#_Lshape"/></clipPath></defs>
<path pathLength="100" d="M172,58H28L100,183L150 96" clip-path="url(#_Lclip)"/>
</g>
<!-- disk icon -->
<view id="disk" viewBox="0 328 32 32"/>
<g id="diskG" transform="translate(0,328)"><circle cx="16" cy="16" r="8"/></g>
</svg>

Amicalement,
Modifié par parsimonhi (27 Mar 2023 - 12:12)