J’ai pu participer à la refonte du site de l’agence Parenti Design il y a peu.
Comme ce site m’a permis d’expérimenter pas mal de choses, un bon gros billet technique s’impose !
Idées autour du projet
Le projet est parti d’une suggestion d’un site responsive qui comprenait moult animations. Seule ombre – haha – au tableau, le site présenté était une usine à gaz… à la limite du bon sens. 7,3 Mo pour une page standard ! Oui vous avez bien lu. Autant le dire de suite, j’ai essayé de l’afficher sur un mobile connecté en wifi – j’allais pas essayer en 3G ! – pour voir si c’était possible, le mobile en question n’a pas été d’accord et s’est mis en grève. Je ne pouvais pas lui en vouloir ceci dit.
Le graphisme a finalement été arrêté et fourni par l’agence, et mon travail a pu commencer. Au final, une page standard hors grosses photos et/ou vidéos était plutôt de l’ordre de 250 ko. Si quelqu’un croit encore que le développeur front-end éclairé est un luxe, envoyez-le moi !
Gérer l’imprévisibilité en atomique
Le projet étant quelque peu mouvant (des tonnes de petits changements en permanence si vous préférez), je reconnais que les classes atomiques m’ont bien facilité la vie. Particulièrement pour gérer le petit cas particulier qui devient la règle avant de redevenir le petit cas particulier.
L’évolution récente du site confirme cet état : définitivement, penser trop gros objets sur ce genre de projets, c’est casse-gueule. Autant fonctionner en petits objets.
En tout cas, j’étais déjà fan des em
, et… je le suis de plus en plus, surtout dans les média-queries. :)
SVG, le bonheur du retina et pas seulement
Comme il était clair qu’une optimisation retina (dans les limites du bon sens) serait de la partie, l’utilisation de SVG a été massive : images – certes décoratives – de contenu, icônes, images CSS, animation sur la page d’accueil, etc.
J’ai utilisé cette méthode pour les images de contenus, bien qu’ancienne, elle reste très robuste : du SVG pour vos logos. Elle permet de charger une image en PNG si l’agent utilisateur ne supporte pas le SVG.
Pour l’animation du SVG sur la home page, j’ai suivi ce tutoriel : Animated line drawing in SVG, ce qui m’a permis d’utiliser des propriétés CSS que je n’utilise pas souvent : fill
, stroke-dasharray
, stroke-dashoffset
, stroke-width
, stroke
, etc. :)
Mon graphiste s’est fait un plaisir de me fournir les SVG, après optimisation avec SVGO, ces derniers se sont souvent avérés plus légers que leurs équivalents en PNG. Comme en plus ces derniers sont future-ready (si un nouveau smartphone a une densité de pixels encore plus élevée, aucun souci), je me demande pourquoi SVG n’est pas plus massivement utilisé…
Amélioration progressive
Comme je ne voulais pas déclencher des animations inutiles, j’ai utilisé modernizr avec un tout petit build. J’avais besoin de savoir si le visiteur supportait SVG, les transitions, les animations CSS, flexbox, etc.
Chaque fois que j’utilisais un de ces éléments, un simple préfixage par les classes de modernizr a permis de ne servir les propriétés qu’aux navigateurs les supportant (y a un exemple juste après avec flexbox).
Le header
fixé – entre autres – m’a forcé à ruser quelque peu, notamment avec des liens vers des ancres internes. Partant de l’idée qu’un lien vers une ancre est la meilleure solution si JavaScript est désactivé, l’idée fut simple : chopper la hauteur du header
, et gérer le décalage à prendre en compte à cause du header
fixé.
Autre point, j’ai dû utiliser flexbox pour un positionnement impossible sans (sur la page d’accueil), encore une fois, passage en mode amélioration progressive. J’ai codé le site sans, puis j’ai refait les classes préfixées par .flexbox
, comme ici :
/* sans flexbox */
.glider-container {
display: table;
}
/* … */
.flexbox .glider-img-container {
display: flex;
}
C’est peut-être moins parfait sans flexbox, mais au moins cela ne cassera pas. D’ailleurs, si je ne vous l’avais pas dit, vous ne vous en seriez jamais aperçu ! :)
Des animations en CSS, lancées par du jQuery
Le principe était le même : quand on scrolle sur les pages, certaines parties devaient apparaître. Très simplement, l’idée a été de détecter quand le bas de l’écran arrive sur la zone en question, et de déclencher l’animation.
Afin de le faire proprement, j’avais une classe pour dire « tel bloc va être animé », et une classe pour faire l’animation inverse quand on arrive dessus. Par exemple :
.csstransitions .transition-opacity1 {
opacity: 0;
-webkit-transition:opacity 2s ease;
-moz-transition:opacity 2s ease;
-o-transition:opacity 2s ease;
transition:opacity 2s ease;
}
.csstransitions .transition-opacity1--active {
opacity: 1;
}
Là, l’élément sur lequel j’applique la classe transition-opacity1
, si l’agent utilisateur supporte les transitions CSS, va devenir complètement transparent. Quand on lui ajoutera la classe transition-opacity1--active
, la transition le fera réapparaitre. Pas plus compliqué que cela !
Seul regret, j’avais créé plusieurs types d’animations :
- effet d’apparition en zoom (
transform: scale
) - effet de fondu (
opacity
) - arrivée du contenu par la droite (
left
), la gauche (right
) ou le bas (bottom
) - etc.
Et au final, seules quelques unes ont été utilisées. En même temps, il me semblait avoir indiqué en début de projet que trop d’animation tuait l’animation, dommage qu’il ait fallu que je les mette toutes sur une page pour qu’on m’écoute ! :)
J’ai utilisé cet outil pour générer la courbe de Béziers : CSS Easing Animation Tool. Ainsi, ça m’a permis de générer ce genre de courbe.
Les animations et transitions CSS sont un vrai régal à utiliser, plus je faisais des essais, plus je me disais que je pouvais faire potentiellement n’importe quoi. Le gros caillou dans la chaussure, c’est quand on doit animer une propriété non stabilisée. La gestion des préfixes devient très pénible, par exemple : -webkit-transition: -webkit-transform
. Si vous voulez animer une propriété dont la standardisation ne suit pas celle des transitions, attention à la profusion de préfixes.
BEM et ses petits problèmes
J’ai utilisé une notation de type BEM pour les classes CSS. Je l’utilise depuis quelques projets, et je dois reconnaître que cette notation est assez agréable et pratique : c’est clair et informatif.
Ne me demandez pas pourquoi je suis parti en inversant l’utilisation du --
(normalement les modifieurs) et celle des __
(normalement celles des éléments enfants), j’avais codé la moitié du template quand je m’en suis rendu compte. Ceci dit, ce n’était pas gênant, un simple commentaire au début de la CSS fixe l’information, et… indiquer le style de notation au début de chaque CSS est devenu un standard dans mes intégrations, justement pour éviter à celui qui reprendra de devenir dingue si je recommettais cette petite inversion.
Mais ! Car il y a un « mais », bien sur. Utilisant massivement du SVG pour des images de contenu, j’ai utilisé la méthode citée plus haut pour permettre aux vieux Internet Explorer d’avoir une roue de secours en PNG. Et malheureusement, il m’est arrivé d’avoir à adjoindre des classes sur ces éléments.
Autrement dit, des classes module--enfant
se sont retrouvées prises dans des commentaires conditionnels ou plus simplement dans des commentaires HTML tout simples. Patatrac, le validateur ne supporte pas que la chaîne --
soit dans un commentaire ! Verbotten, warning, niet, nada, que dalle. J’ai même proposé un bug à la spécification HTML5 (car c’est également gênant pour utiliser les futures variables CSS), mais on m’a aimablement répondu de passer mon chemin. :)
J’avoue que si je dois réutiliser BEM avec beaucoup de SVG, cela va me poser quelques gros soucis. Une première piste serait d’utiliser les tirets cadratin ou demi-cadratin (ce que j'ai fait pour certaines classes), mais ce n’est pas excessivement pratique. Affaire à suivre !
En conclusion
Ce projet a été l’occasion pour moi d’utiliser des choses que je ne fais pas souvent, et de maintenir un projet pas toujours simple. Animations/transitions CSS, SVG, etc. C’est un vrai régal à utiliser. Quand les vieux navigateurs qui ne supportent pas SVG auront dégagé, on va vraiment se régaler comme des cochons ! :)
De plus en plus, j’apprécie de coder moi-même les demandes en jQuery, même si je ne suis pas encore une brute dans ce domaine, loin de là ! :)
Ce qui est par contre terrible, c’est que je doive encore autant hurler pour défendre un site fait main au lieu d’une usine à gaz de 7 Mo. Sérieusement, les jolis effets, etc., c’est sympathique, mais il serait temps que les chefs de projet, les techniciens, etc. refusent de vendre leurs âmes à des clients qui demandent des trucs à côté de la plaque. Je suis peut-être un peu dur, mais des usines de 7 Mo, c’est un non-sens absolu, cela ne devrait pas exister, et cela ne devrait pas arriver qu’un client puisse nous demander ça parce qu’il l’a vu !
Côté mauvais points, j’ai également maudit Webkit à plusieurs reprises, notamment via sa gestion catastrophique des valeurs avec des décimales (j’ai dû revenir aux pixels dans certains cas, fort heureusement pour des images seulement).
Si vous êtes curieux, la feuille de style est joignable en ligne directement : CSS de Parenti Design. Définitivement, produire des feuilles de styles maintenables n’est plus un luxe, mais un pré-requis pour éviter de sombrer dans une dépression nerveuse quand il faut y revenirֺ… à bon entendeur ! :)
En ce qui concerne les soucis liés à la notation BEM, l'usage du cadratin et du demi-cadratin peut poser problème si le codage utilisé n'est pas l'UTF-8 (de nos jours, nous sommes censés travailler sur de l'UTF-8 ; mais, nous ne sommes pas, pour autant, à l'abri d'une mauvaise surprise ou d'une contrainte incompréhensible en matière de codage de caractères) ou que le développeur front-end ne travaille pas avec un clavier Mac, où la saisie de ces deux caractères est bien plus facile que sur un clavier PC, qui oblige à mémoriser la combinaison Alt + touches du pavé numérique (je laisse deviner la galère avec un clavier de PC portable dépourvu de clavier numérique distinct ou obligeant à utiliser une touche supplémentaire pour ladite combinaison au clavier, en osant espérer que le développeur ne s'est pas cassé un bras). Une suggestion possible serait d'utiliser le double underscore pour introduire l'élément BEM et le quadruple underscore pour le modifieur BEM, comme suit : block__element____modifier.
En ce qui concerne le fallback pour les images de contenu en SVG embarquées au moyen de l'élément img, le recours aux commentaires conditionnels n'est pas très pertinent : en effet, les versions d'IE antérieures à la 9 ne sont pas les seules à ne pas comprendre le SVG, il y a aussi les versions du navigateur Android antérieures à la 3. Pour ma part, je code un élément img dont l'attribut src appelle l'image au format PNG et qui est accompagné d'un attribut data-* dont la valeur est le nom du fichier au format SVG, puis procède, en JavaScript, au remplacement de la valeur de l'attribut src par celle de mon attribut data-*, après avoir détecté que le navigateur comprend bien le SVG (en vérifiant si la propriété window.SVGSVGElement ne vaut pas 'undefined'). Ainsi, les vieux Android ne seront pas pénalisés par cette amélioration progressive. Un exemple est disponible sur le site de la BNFA, refondu par mes soins pour la partie front-end.
Enfin, quant à la gestion des préfixes, ton préprocesseur préféré et un mixin font l'affaire.