Retour d’expérience de la refonte du site de l’agence Prezenz (CSS responsive en mobile-first)

Retour d’expérience de la refonte du site de l’agence Prezenz (CSS responsive en mobile-first) (le 27 décembre 2013)

Enfin ! Depuis le temps que je souhaitais refondre le site légèrement désuet qu’était le site de mon agence, cette fois, l’occasion est arrivée. Le nouveau site de Prezenz a été mis en ligne il y a quelques semaines, et le moins qu’on puisse dire, c’est que côté intégration j’ai eu quelques défis bien sympas à relever sur ce site !

Cette refonte ayant touché beaucoup de domaines, pour ce billet, je m’en tiendrai « juste » à l’intégration, car il y a déjà beaucoup à dire.

Prezenz

Les objectifs

Les objectifs ont été clairs : pour le site de l’agence, on va mettre le paquet. Site en responsive, mobiles, micro-datas, optimisation SEO, etc. D’entrée de jeu, j’ai imposé une intégration en mobile-first, et tant qu’à faire les besoins en JavaScript seront faits autant que possible à la main !

Les navigateurs cibles seront en premier les modernes, les vieux ne seront pas oubliés pour autant, mais ils passeront clairement après les modernes.

De nombreux contenus ont été rédigés, un gestionnaire de site sur mesure a été créé, Google Analytics a aussi eu de quoi faire, de nombreux trackers ont été mis en place afin de voir clairement si les choix qui ont été faits sont compris et utilisés.

Construction d’une CSS mobile-first, responsive avec Sass/Compass et RÖCSSTI

Mon micro-framework était construit en desktop-first, et du coup, avec ce site, une version Sass de RÖCSSTI construite en mobile-first a été mise au point. Le début a consisté à changer l’ordre de la CSS : on part du plus petit dénominateur commun pour aller vers les résolutions plus élevées, en ne changeant que ce qui est nécessaire à chaque étape.

Je dis bien « au départ » car quelques légères modifications ont dû suivre, j’y reviendrai.

L’intégration mobile-first est un exercice de style intéressant, même si j’en avais déjà fait une pour mon site personnel, là c’était un poil plus compliqué, et donc plus intéressant.

Autant le dire de suite, j’avais des wireframes et des guides de styles très précis, et je ne vois pas comment intégrer un site correctement (comprenez sans perdre de temps et en respectant autant que possible l’intention du design). Si parfois sur un site desktop, on peut se permettre d’improviser les points imprécis, sur une intégration construite en mobile-first, j’aurais tendance à le déconseiller vivement !

Alors certes, avec les vrais contenus, certaines adaptations en cours de route ont dû être faites, mais l’idée générale m’a bien guidé.

Structure du projet avec Sass

À l’inverse de bon nombre d’intégrateurs, je ne suis pas un fan de tout morceler mes CSS en plein de fichiers. C’est sûrement utile avec des CSS immenses, mais je ne suis pas allé aussi loin.

Par contre, quand j’ai eu le guide de styles en mains, j’ai fait un sous-fichier avec tous les paramètres : notamment toutes les couleurs données en référence ont été mises dans des variables et nommées telles quelles, comme par exemple $prz-grey: #363636;. Et je me suis interdit d’utiliser autre chose que ces variables !
Ainsi, toute référence venant des graphistes et qui serait en-dehors des clous posés par… eux-mêmes (!) aura vite été remise dans le droit chemin. Seule exception, je n’ai pas créé de variable pour le blanc pur.

Les autres sous-fichiers (qui a dit includes ?) étaient principalement pour la gestion des sprites, afin de ne pas surcharger le fichier principal, qui, avec les commentaires, est resté très facilement maintenable et lisible.

Les em, j’aime !

Je reste légèrement surpris que la conférence de Nicolas Hoizey à Paris-Web sur l’unité em ait presque un goût de grande nouveauté pour beaucoup, car c’est vraiment un régal à utiliser dès qu’on en a pris l’habitude. Pour ma part, je les utilise depuis de nombreux projets, et je me surprends parfois à ne plus raisonner en pixels pour des padding et autre margin, mais directement en em.

Cette intégration, à l’exception des images, est intégralement construite en em, media-queries comprises ! Et le moins que je puisse dire, c’est que cela a des effets de bords… plutôt sympathiques !

Le premier est de permettre un zoom global ou un zoom texte sans aucun souci. Le site va très bien s’adapter si par exemple je zoome fortement sur mon navigateur desktop. Autrement dit, c’est un pur régal si on a des contraintes d’accessibilité où l’on doit permettre un zoom texte conséquent. Autre avantage non négligeable : le site s’accommode parfaitement de toutes les tailles de fonte définies ou différentes par défaut.

Ci-dessous un exemple de site en version zoomée à 200% :

Une page du site Prezenz en zoom à 200%

Même si effectivement, les em sont un peu plus simples à gérer avec un pré-processeur comme Sass, il ne faut pas hésiter, même sans Sass, cela se gère bien et ils apportent de nombreux avantages. Les em, c’est sensass’, même sans Sass.

Optimisation retina

Histoire de faire les choses comme il faut, vu que le site cible clairement les mobiles, il eut été dommage de ne pas penser à l’optimisation aux écrans à haute densité de pixels, que j’appellerai retina par simple fainéantise ! :)

Comme le site utilise autant que possible du texte avec une webfont, de ce côté-là, pas de souci. Pour le logo du site, pas de souci, SVG a été choisi et est « fallbacké » avec un PNG.

Pour les icônes – le site en utilise énormément –, le choix d’un doublement de résolution a été préféré à SVG, cela a été plus simple à gérer pour tout le monde, y compris moi-même pour une histoire de sprites CSS, j’aborde ce point plus loin.

De ce que j’avais pu lire sur le sujet, le principe utilisé est souvent de charger d’abord les images normales, et seulement ensuite de charger les images de meilleure qualité. Comme l’objectif était clairement les mobiles, les navigateurs modernes et les écrans retina, j’ai pris le parti inverse : d’abord charger uniquement les images en « haute qualité », afin d’éviter des requêtes supplémentaires pour les mobiles retina. Les navigateurs modernes gérant parfaitement background-size, le léger surpoids était très limité pour ces derniers, en tout cas, rien de comparable avec des requêtes HTTP supplémentaires.

Seuls les vieux navigateurs auront eu des images en taille normale en plus, autrement dit, IE7 et 8.

Considérations sur Flexbox et CSS3 multicolumn

Histoire de me faire plaisir, j’ai pu expérimenter l’utilisation de Flexbox pour quelques parties, disons-le tout net, ce positionnement de boîtes flexibles est un pur bonheur : surpuissant, très simple, ne nécessitant que peu de code… c’est gé-nial.

Sauuuuuf… quand on doit regarder chez les navigateurs qui ne le supportent pas, là ça devient la misère (les fallbacks ne sont franchement pas terribles, pour ne pas dire inexistants). C’est cela qui m’a conduit à en limiter l’usage là où je pouvais me raccrocher aux branches avec du table-layout avec des largeurs en pourcentages.

Certains éléments demandés m’ont été impossibles à styler sans CSS3 multi-column. Typiquement, la navigation secondaire (découvrir, attirer, etc.) sur la page portrait de Prezenz qui passe d’une colonne à deux, puis trois colonnes… impossible de faire cela autrement !

Comme Flexbox, le problème était la compatibilité sur les vieux navigateurs, qui a dit IE ? Heureusement, ces derniers n’ayant que faire des versions responsive et la version desktop s’affichant sur une colonne, au final, ce problème délicat s’est réglé en partie tout seul !

Pour la liste des services associés à une rubrique, par exemple le développement web, le problème de non-support était moins gênant : les navigateurs ne le supportant pas afficheront la liste sur une unique colonne.

Ce type de positionnement est vraiment à réserver pour des menus de navigation ou des listes, je l’imagine plutôt désagréable pour lire un texte ainsi morcelé.

Autre point faible, débrouillez-vous que pour le nombres de colonnes et d’éléments soient des multiples, sinon le résultat est catastrophique ! Je n’ai pas eu le problème avec les catégories de services (6 se divise bien par/en 2 et 3), mais pour la navigation secondaire de la partie portrait (5 éléments), tintin ! Du coup, j’ai rajouté un élément vide qui n’apparaît que quand il y a deux ou trois colonnes (autrement dit à partir des smartphones en paysage et sur les tablettes), afin de pallier ce petit problème.

Une navigation secondaire du site Prezenz, utilisant CSS3 Multicolumn

Bref, des possibilités sympas, mais à utiliser avec grand discernement.

Une CSS réutilisable

Je continue de progresser en matière de CSS modulaires et réutilisables, et le moins que je puisse dire, c’est que cela rend beaucoup, mais alors vraiment beaucoup de services !

Typiquement, les demandes du genre « tu peux transformer ce bloc en lien » qui forcent parfois à replonger dans la CSS, se règlent instantanément. La CSS ne reposant pas sur une structure HTML donnée, elle reste très flexible.

Typiquement, pour les icônes passant de petite taille à grande taille dans certains menus, je me serais mal vu faire des classes spécifiques qui gèrent la même icône selon la résolution… multipliez ça par la gestion du retina et le nombre monstrueux d’icônes (une soixantaine), et c’eût été la Bérézina. Au final, j’ai opté pour un objet icône dans chaque taille (dépourvu d’infos de positionnement), que j’affiche ou non selon la résolution. D’une, cet objet a été réutilisable (ça m’a bien servi), et de deux c’était beaucoup plus simple à gérer.

Côté notation, chaque module avait ses objets, tous préfixés par le nom du module. Un changement de tag ? Rien à cirer, les styles sont appliqués sur les classes, pas sur le code. Un nouveau comportement JavaScript ? On s’en fout, les règles d’état sont là, et le JavaScript manipule des classes et non des styles en ligne.

Ajoutons à cela que les premières mises à jour pas prévues sont vite arrivées, et là, devoir replonger dans la CSS a été une étape dont je n’ai pas été mécontent… de me passer : pouvoir intégrer les nouvelles demandes uniquement grâce aux briques de RÖCSSTI, ce fut un gain de temps et de prises de tête.

Je crois avoir utilisé 4 !important dans la CSS (dont un temporaire pour les fêtes de fin d’année), à bon escient bien sûr. :)

Des performances et des sprites

Vu le nombre monstrueux d’icônes, l’option sprites CSS a vite déboulé sur le projet. Tout le monde m’avait vanté les mérites des fonctions magiques de Sass pour les sprites… j’en ai été pour mes frais ! Non pas que ces fonctions ne soient pas bien (générer une image de sprite à partir de plein d’autres, c’est vraiment pratique), mais… elles ne convenaient pas du tout à mes besoins. Cela m’a même fait perdre du temps d’essayer d’utiliser à tout prix ces fonctions. J’ai une icône pour l’état de lien, une pour l’état survolé, et une pour une troisième utilisation à part.

Du coup, j’ai bricolé une fonction Sass à la main, histoire de permettre de générer le code CSS des sprites facilement, peu importe la taille de la grille des sprites. J’avais expliqué quelques aspects de cette fonction dans un précédent billet, donc je ne m’étendrai pas plus sur le sujet. Bref, DIY : Do It Yourself (faites-le vous-même).

Un regret néanmoins, la CSS aurait pu bénéficier d’une classe factorisant le tout comme :

[class*=icon-48] {

}

J’ai pris connaissance de cette technique après avoir codé l’intégralité de la CSS… tant pis, je ferai encore mieux la prochaine fois pour les sprites, ou si je trouve le temps, je reviendrai dessus.

Côté performances, la règle d’or était : des sélecteurs courts ! Cela a d’ailleurs re-servi pour faciliter la surcharge CSS, donc pour la maintenabilité.

Des micro-datas

Afin d’avoir un contenu sémantisé, les microdatas ont été utilisées massivement. J’ai eu l’approche suivante : l’élément racine est l’agence web, comme les informations de cette dernière sont toujours juste avant le footer, pas de souci. L’élément de référence sera donc sur le body (body itemscope itemtype="http://schema.org/Corporation"), et les autres éléments viendront se greffer sur cet élément.

Ensuite, chaque item qui dépendait de l’agence était indiqué dans le contenu par la relation MakesOffer, comme les services sur une catégorie. C’est d’ailleurs cette relation qui indique que l’élément service est « enfant » de l’agence.

D’autres pages indiquent les personnes comme la page contact.

Curiosité, je pensais utiliser les metas du site pour stocker d’autres informations, malheureusement, il est impossible de balancer des id sur une balise meta, sinon le validateur ronchonne. Il ne faut d’ailleurs pas mettre d’attribut name à tort et à travers à la balise meta, sinon le validateur ronchonne un « meta name is not registered ». Par contre, il est possible de stocker des meta dans le body, sans que cela ne choque le validateur. Bizarre mais ça marche ! Comme illustré dans cette image.

Affichage des micro-datas dans le code du site Prezenz

Qu’il me soit encore permis de remercier Twikito qui les a beaucoup utilisées sur la page d’Opquast, cela m’a beaucoup aidé à comprendre comment faire.

Des petites astuces et considérations sur CSS par ci par là

Un box carré ?

Une demande particulièrement bête m’a donné du fil à retordre : certains blocs devaient être carrés, comme sur la page des services Web de Prezenz. Or, ces mêmes blocs étaient dimensionnés en pourcentages ou via Flexbox. Impossible donc de leur attribuer une hauteur.

J’ai bien glané quelques astuces sur le sujet, mais la plus simple m’a été inspirée par Nicolas Hoizey (entre Nicolas H. on se comprend) sur Twitter : utiliser une simple image carrée ! Du coup, j’ai créé une image carrée de 1 pixel de côté, et je lui ai donné une largeur de 100% de son conteneur. Ainsi mon bloc sera carré du fait de cette image. Les contenus seront positionnés en absolu dans ce bloc, qui lui sera donc en relatif.

Histoire de ne pas perdre bêtement une requête HTTP avec ce genre d’image rikikie, je les ai mises en Data-URI. Bref, KISS : Keep It Simple and Smart (restez simple et élégant).

Classes atomiques

Autre point, le recours aux classes atomiques est légèrement moins systématique lors d’une approche mobile-first par rapport à une intégration desktop-first (je n’ai pas eu envie de rentrer dans le .w60desktop et .w40mobile, j’ai préféré rester simple). Mon micro-framework en version mobile-first a appris pas mal de choses : répéter certaines classes selon la media-query utilisée, répéter certains layout, etc.

Qu’on soit clair : je ne dis pas que le concept est à jeter en mobile-first, je dis juste que j’y ai eu un peu moins recours dans ce cas. À voir si cela se confirme sur mes prochaines intégrations en mobile-first.

Approches utilisées

J’avais beaucoup apprécié la lecture de SMACSS, dont j’ai réutilisé certains de ses principes comme les règles d’état, excellent pour éviter de manipuler des styles en ligne en JavaScript (autant manipuler des règles d’état). Côté OOCSS, j’ai repris parfois quelques un de ses principes à mon compte. Idem pour l’approche BEM, et l’approche atomes/molécules.

Même si je ne les ai pas appliquées stricto sensus (BEM était trop verbeux pour mes besoins par exemple), j’en ai repris à ma sauce certains éléments pratiques :

  • les règles d’état .is-<état>, pratique et clair pour le JavaScript ;
  • les modules ;
  • quelques classes atomiques ;
  • etc.

Complexité de la CSS

Ne le cachons pas, ce genre de CSS est très efficace pour les performances, etc., mais elle est parfois complexe, autant à créer qu’à maintenir.

Ne lésinez vraiment pas sur les commentaires ni sur le sectionnage de vos CSS. Pour donner un ordre d’idée, la version Sass pèse à peu près 65 ko, la version CSS non minifiée pèse 115 ko, et la version minifiée de la CSS pèse 65 ko, 14 ko après GZIP.

Quoi qu’on en dise, ça doit être rangé là-dedans, nom d’un gadget !

Autres

Un point central : le table-layout m’a énormément servi. Si vous n’utilisez pas ce positionnement, vous devriez sérieusement reconsidérer votre avis, il est vraiment magique pour de nombreux cas, et évite un paquet de flottants et de délires d’intégrations.

D’ailleurs, selon moi, intégrer un design non trivial en mobile-first nécessité de pouvoir utiliser des positionnements relativement modernes en CSS (bref, sortir des flottants), sinon c’est la crise de nerfs assurée.

En conclusion

Non seulement cette intégration a été un bon défi, mais en plus travailler pour son agence, c’est encore plus motivant. Ne laisser que peu de concessions et mettre tout ce que je connaissais dans cette réalisation, cela m’a permis de progresser.

Un autre billet parlera des « à coté » : Google Analytics, le côté back-end et l’apport qu’il a donné au front-end, et tous les développements qui sont arrivés en plus, car lancés à plein gaz, on ne s’est pas arrêté en si bon chemin !

Ajout : petit bonus

Si vous êtes curieux, vous pouvez étudier la CSS de Prezenz version Sass.

Permalien :

Flux RSS des commentaires de ce billet : https://www.nicolas-hoffmann.net/rss/commentaires.php?id_news=1604

7 commentaires

Posté par Eric Lemoine le 27/12/2013 à 20:39:05
Bonsoir

Retour d'expérience très intéressant et très riche, merci (sourire)
Une question sur la problématique des icônes : pourquoi ne pas avoir fait le choix des webfonts ?
Cela aurait résolu ta problématique de retina et de variante par couleur des différentes icônes.
Au niveau poids je ne sais pas ce que ça pourrait donner mais on voit que la version actuelle à base de PNG consomme 220ko sur le first hit (http://www.webpagetest.org/result/131227_E0_NX9/1/details/) ce que je trouve énorme pour des icônes.

Qu'en penses-tu ?

Eric

Posté par loick le 27/12/2013 à 20:50:37
Très intéressant, merci pour le partage (sourire)

J'pense m'inspirer de ton article pour quelques modifs sur mon site du coup.

Sinon, pour la problématique du carré, je l'ai eu aussi sur la home de mon site (http://loickpiera.com). J'ai utilisé des li avec une width de 33.3333% (3 li par ligne), une height de 0 et un padding horizontal de 16.6667%. Je profite du fait que le pourcentage d'un padding est relatif au width de l'élément (je ne sais plus où j'avais trouvé l'astuce). Si ça jamais ça peut servir a quelqu'un... (clin d’oeil)
Posté par Florian le 27/12/2013 à 21:40:23
Salut, très intéressant comme retour d'expérience.

Je n'ai pas compris l'intérêt des micros-datas, c'est pour le SEO ?

Je me demandais aussi, quel est le procédé utilisé pour servir du GZIP de ces CSS au serveur ? Ca fonctionne de quelle manière ?
Posté par Nico le 28/12/2013 à 8:42:50
Éric : effectivement c'était une option comme le SVG. Néanmoins, l'accessibilité des fontes icônes n'est pas fameuse, et comme le SVG, le rendu n'était pas pixel perfect comme le souhaitaient les graphistes. C'est qu'ils sont pinailleurs (sourire)

Loïck : je vais jeter un œil (clin d’oeil)

Florian : effectivement, l'un des intérêts des micro-datas est le SEO.

Pour les CSS gzippées, cela se fait au niveau serveur, la solution la plus passe-partout est via un fichier htaccess sur un serveur Apache :
AddOutputFilterByType DEFLATE text/css

Si ces sujets ne te disent rien, il faut aller lire sur le sujet http://openweb.eu.org/articles/le-fichier-htaccess (clin d’oeil)
Posté par Gaël Poupard le 29/12/2013 à 12:06:53
Super retour dˆexpérience, je vais le lire et le re-lire !!

Beaucoup de choses à décortiquer et s’approprier, c’est toujours un succès (clin d’oeil)
Posté par Pascal (eQRoeil) le 29/12/2013 à 22:45:57
Salut Nico, merci pour ce retour, c'est toujours intéressant et j'espère que cela en convertira au mobile-first ; )

Petite remarque pour "colonne à deux, puis trois colonnes… impossible de faire cela autrement !"

Plutôt que de longs discours j'ai fait une démo avec inline-block basée sur la grille de suitcss (grille que j'utilise et qui permet de gérer les colonnes très simplement), ça te sera peut-être utile plus tard ; )

Pas besoin d'un item vide.

http://codepen.io/eQRoeil/pen/zaulD

La grille de suit https://github.com/suitcss/grid et les "grid-layouts" https://github.com/suitcss/grid-layouts permettent de gérer les colonnes de la grille au niveau du conteneur .Grid avec variation .v2-Grid--2col (etc.) les v2- v3- correspondant aux MQ , bref, mobile-first, très souple jette un oeil à la démo http://suitcss.github.io/grid-layouts/


Pascal

Posté par Nico le 29/12/2013 à 23:01:25
Bien vu pour ce coup-là, je n'y avais pas pensé (même si ma méthode n'est pas à jeter, ouf, l'honneur est sauf (grand sourire) ). Très élégante méthode, je note précautionneusement.

Maintenant que tu as attisé ma curiosité : quid du support navigateur ? Ça marche jusqu'à quel IE ? (avec le display:inline-block sur le li, les vieux IE vont peut-être gueuler ?)

Ajouter un commentaire









L'option « Se souvenir de mes informations » utilise un cookie, elle ne sera pas effective si vous les avez désactivés.

Les balises HTML ne seront pas interprétées, il est donc inutile d'en mettre. Par contre, les sauts de lignes de votre commentaire seront pris en compte, ne mettez donc pas de <br />, le site s'en chargera. Bien sûr, un commentaire vide ne sera pas ajouté !

L'auteur (autrement dit moi) n'est pas responsable des éventuelles fautes d'orthographe dans les commentaires.
Tout propos raciste et/ou insultant sera supprimé sans préavis. Les commentaires hors de propos destinés à faire de la pub pour des sites seront également supprimés sans ménagement.

Je vous prie de me pardonner, j'ai énormément de mal à lire le "langage" SMS, il n'est donc pas du tout interdit de s'abstenir de l'utiliser. Qui plus est, vous avez sûrement un clavier digne de ce nom et pas celui d'un téléphone portable. Ne vous gênez pas pour utiliser l'option "Prévisualiser" si vous voulez vous relire avant de poster, je vous en remercie d'avance !

Cet article a été écrit par Nicolas Hoffmann.

Ce site est la propriété de Nicolas Hoffmann.
Tous droits réservés, les textes du blog sont publiés sous licence CC BY-NC-SA.