CSS et évolutivité

Cet article est une traduction de l’article d’Adam Morse (@mrmrs_) intitulé CSS and Scalability. Le terme “scalability” n’a pas d’équivalent évident en français. Il fait référence à l’utilisation de CSS sur des projets qui évoluent, qui grandissent. Kaelig Deloumeau-Prigent parle de CSS “maintenables”, dans son livre du même nom, pour évoquer des problématiques comparables. J’ai choisi de traduire “scalability” par “évolutivité”.

Il y a plusieurs années, je me suis demandé comment les utiliser les CSS sur des projets de grande envergure. Quand j’ai commencé, il y avait beaucoup moins de ressources sur le sujet qu’aujourd’hui. Il y avait quelques livres que des amis m’avaient prêtés et deux ou trois articles de blog intéressants. Mais les CSS étaient encore un sujet relativement récent et la plupart des gens n’avaient pas encore commencé à réfléchir sérieusement ou à découvrir par la pratique les concepts de maintenabilité lors du travail d’équipes sur de grosses applications web.

“En ce temps là”, CSS zen garden était une démo très influente. La plupart de mes collègues et moi pensions que ce site illustrait parfaitement la puissance de la cascade. Il était possible de modifier profondément l’apparence d’un site sans toucher au HTML.

Au début, les gens m’ont présenté ça comme une fonctionnalité. En écrivant des CSS, il était possible de faire un changement qui se propageait partout. En théorie, ça a l’air très intéressant. Mais onze ans plus tard, mon expérience dans des équipes, grandes ou petites, m’a fait constater que c’est là la chose la plus terrifiante des CSS et qu’elle peut gravement nuire à la capacité d’une organisation à faire évoluer son produit.

Deux propriétés CSS entrent dans un bar.

Ailleurs, dans un autre bar, un tabouret tombe.

– @thomasfuchs

Après avoir participé à la mise en œuvre de nombreux systèmes CSS qui “tombaient en panne” et devenaient difficile à maintenir au fur et à mesure que les applications et les équipes grossissaient… j’ai découvert que je ne voulais plus des “fonctionnalités” de la cascade.

J’ai longtemps blagué en disant que le gros problème du développement front-end, c’est que les autres personnes qui résolvent vos problèmes sont des développeurs front-end. Mais ces dernières années, beaucoup de gens intelligents se sont intéressés aux CSS, ce qui a mené à des discussions fascinantes sur comment construire des interfaces “évolutives” et comment cela s’appliquait aux CSS. Quand j’ai commencé à m’intéresser à l’évolutivité, j’ai naturellement lu tous les articles de blog et regardé toutes les conférences que j’ai pu trouver. Il y a des nombreuses “bonnes pratiques” qui proposent de vous expliquer comment utiliser Sass/Less/Stylus, etc. vous aidera à créer des CSS maintenables. Comment les mixins peuvent rendre votre code plus DRY. Comment les extends garderont votre HTML propre et agréable à lire. Comment BEM rendra votre code si parfait que vous en pleureriez presque.

Mais quelle est la réalité ? Qu’est-ce qui est réellement envoyé en production ? Que font tous ces trucs et astuces à nos CSS en production ? Comment est-ce que cela affecte l’équipe entière ? Et, plus important, comment est-ce que l’utilisateur est impacté ?

Quand il s’agit de créer et de livrer des produits, j’aime bien penser à la réalité des choses. Ce qui est parfois un challenge. J’ai assisté à trop de réunions durant lesquelles les gens ne veulent pas parler ou entendre parler de la réalité. Ils parlent de possibilités hypothétiques avec des phrases vides de sens. J’aime bien prendre de la drogue et parler comme ça aussi, parfois. Mais, si vous ne prenez pas en compte votre situation précise, il peut être assez difficile de comprendre quels sont vos problèmes. Et la probabilité de trouver de solutions à des problèmes inconnus est, disons, pas énorme.

Me voilà donc, au printemps 2014, nouvel employé d’une société technologique reconnue et récompensée qui a un site web. Et ce site web a beaucoup de CSS. Pour me familiariser avec le code existant, j’ai ouvert les outils de développement et j’ai commencé à lire les CSS du site.

Ligne par ligne.
Du début à la fin.

J’ai parfois ri :

/* Start of reusable styles here */

J’ai parfois pleuré.

.homepage-promos .grid-50 {
    width: 100%
}
.homepage-promos .grid-33 {
    width: 100%
}
.homepage-promos .grid-34 {
    width: 100%
}

J’ai parfois ri et pleuré en même temps.

#seo-container {
    display: none;
}

Je me suis parfois demandé d’où venaient les nombres

.product-tab {
  height: 530px;
  width: 99.7%;
}

J’ai parfois été content d’avoir lu les specs

.container-inner.promo-status {
     float: center;
  }

Et finalement, je suis tombé sur cette classe :

.left {
  float: left!important;
}

J’ai vu cette classe et je me suis dit : “au moins, on sait à quoi elle sert”. Contrairement au reste des CSS, elle avait l’air facilement réutilisable. Par n’importe qui aurait besoin de floater quelque chose à gauche.

J’ai continué à lire et je suis tombé sur ça :

.left-max-scr1,
.left-max-scr2,
.left-max-scr3,
.left-only-scr1 {
    float: left;
}

…suivi de ce blog de code assez similaire…

.left-min-scr2,
.left-min-scr3,
.left-max-scr3,
.left-only-scr3 {
    float: left;
}

Puis je me suis demandé la raison d’être du prochain bloc de code. Est-ce que c’est pour les éléments avec la classe .header-nav-list qui ne sont pas dans un élément avec la classe .header-nav-container?

.header-nav-container .header-nav-list {
    float: left;
}

.CA .header-nav-list.second {
    float: left;
}

#nav.challenger-a .submenu-3col li,
#nav.challenger-a .submenu-3col li {
    float: left;
}

Ici, nous commençons à voir un mélange de noms de classes se rapportant au contenu (.submenu) avec des noms de classes se rapportant à l’apparence (-3col).

.ie6 #footer-content .flex-control-nav li a,
.ie7 #footer-content .flex-control-nav li a,
.ie8 #footer-content .flex-control-nav li a {
    float: left;
}

#nav.challenger-a li.menu-products {
    float: left;
}

Les CSS sont intéressants, parce que contrairement à d’autres types de code, vous avez de grandes chances de trouver le code le plus récent vers la fin du fichier. Lire un fichier CSS du début à la fin révélera souvent, dans l’ordre chronologique, les raisons de la défaillance d’un système.

Dans les exemples ci-dessus, nous voyons des sélecteurs de plus en plus longs, qui ont de plus en plus de poids et qui ne donnent qu’une seule valeur à une seule propriété : float: left.

Pour information, il n’y a que trois options pour float. Contrairement à l’un des exemples de code au-dessus, il n’y a pas de float center. Simplement left, right et none.

Lire ces CSS m’a fait penser à beaucoup de chose. Une chose que je n’arrivait pas à me sortir de la tête était : pourquoi tout ce travail pour changer une chose ? Pourquoi écrire tout ce code juste pour faire flotter quelque chose à gauche ?

Pour moi, c’est le reflet de l’état d’esprit de la plupart des gens quand ils écrivent du code front-end. Ils essaient généralement de changer une ou deux choses dans une interface, et c’est tout. Et quand vous êtes dans cette situation, vous voulez limiter le nombre de choses que vous cassez. Tout en faisant le changement demandé dans un ticket jira qui a fini par vous être attribué.

J’ai aussi commencé à penser à propos de communication, et de comment elle se déplace dans plusieurs directions. Si je lis du HTML, je veux savoir ce que les CSS vont faire. Si je lis des CSS, je veux savoir ce qui va se passer si je l’applique à un bloc de HTML. Dans un bon système, l’information circule dans les deux sens. SI vous regardez les CSS, vous pouvez dire ce qui va se passer. Si vous regardez le HTML, vous savez ce que le code va faire.

Mais la plupart des systèmes front-end ne sont pas bons. L’information ne circule que dans un sens. Si je regarde un bloc de HTML et que je ne peux pas trouver TOUTES les CSS qui vont modifier sont affichage en moins de 5 secondes, je pense que ce système est défectueux. Donc, si je rencontre l’exemple vu au-dessus : .container-inner.promo-status cela signifie que je vais devoir trouver des éléments qui ont ces deux classes (mais pas forcément uniquement celles-là). Mais en regardant ce bloc de CSS, je n’ai aucun moyen de savoir s’il a été redéfini ailleurs. Donc je dois chercher à travers tout le système pour chercher les définitions de container-inner et de promo-status. Le temps de trouver ces définitions, j’aurai probablement oublié ce que je cherchais à faire, auquel cas je quitterai mon bureau pour aller me faire un café.

 

De l’autre côté, réfléchissez à cet exemple :

.red {
  color: #FF4136;
}

Je dirais que ça rend rouge le texte d’un élément. Traditionnellement, on me disait que c’était un horrible nom de classe. Mais je l’aime bien. Le seul cas dans lequel je le trouverais mauvais, ce serait s’il changeait la couleur de l’élément pour du violet, du bleu, ou n’importe quelle couleur qui ne soit pas du rouge. Ou s’il était redéfini à plusieurs reprises pour différentes teintes de rouge. Mais nous reparlerons de ça.

Et si je voyais ce bloc de HTML :

<div class=“red”>Some text</div>

Je saurais, sans regarder les CSS, ce qui se passerait. L’information circule dans les deux sens. Il est facile d’apprendre un ensemble de classes simples qui font bien une chose et peuvent être réutilisées dans n’importe qu’elle contexte. Il devrait y avoir une relation un-pour-un entre une classe et sa définition. Une classe qui a plusieurs définitions, qui sont en permanence redéfinies en fonction du contexte ne résout aucun problème, ça en créé. Le concept d’immutabilité n’est pas nouveau, mais la communauté CSS l’a ignoré trop longtemps. Imaginez que vous ayez une fonction nommée ‘filesize’ à laquelle vous passez un nom de fichier et qui retournerait la taille du fichier. Ça semble assez sympa. Mais imaginez que parfois, la fonction vous retourne le nombre de lignes du fichier. Ça ne semble pas sympa du tout. Et bien c’est ce que vous faites à chaque fois que vous redéfinissez une classe CSS. C’est la pire situation pour les gens qui savent débugger des CSS. C’est encore plus horrible pour ceux qui débutent.

Quand nous regardons des CSS alambiqués, nous devons nous rappeler que derrière chaque ensemble de règles CSS, il y a une histoire. Peut-être que l’auteur était pressé et n’a pas eu le temps de vérifier qu’il y avait du code déjà écrit qu’il pouvait réutiliser. Peut-être qu’il se fiche des CSS et qu’à l’instant où quelque chose fonctionne, il enregistre, fait un commit et retourne écrire des monades. Quand j’écris du mauvais code, ce n’est pas parce que je n’essaie pas d’écrire du bon code. Il y a toujours d’autres forces en œuvre. Quelles sont les forces qui empêchent d’écrire du code propre et réutilisable ? Comment s’en débarrasse-t-on ? J’ai passé beaucoup de temps ces dernières années à faire des tests utilisateurs en observant comment les gens écrivent leur propre code front-end, à utiliser le code front-end d’autres personnes et à réfléchir au développement des interfaces en général. Cela a été une expérience très enrichissante (comme souvent lorsque l’on fait des tests utilisateurs). J’ai beaucoup appris sur les différents modèles mentaux que les gens utilisent, et comment essayer de construire des systèmes qui permettent à des gens aux compétences différentes de passer plus de temps à concevoir et construire et moins de temps à débugger, se battre et pleurer.

Note : (je ne sais pas où mettre ça)

Avant que je commence à faire des tests de performance et des tests utilisateurs, je n’aimais pas l’idée de CSS orientés objet / CSS atomiques. J’aimais écrire des classes monolithiques et traverser le DOM avec mes sélecteurs. Ça me semblait avoir beaucoup de sens et j’ai pu créer beaucoup de sites web de cette façon. Faire des tests et vérifier mes hypothèses m’a aidé à définir en grande partie la façon dont je vois le code aujourd’hui. Je ne suis pas très intéressé par ce que je peux faire avec les CSS. Je suis arrivé à un point où je suis intéressé par ce que je peux aider des groupes de gens à faire avec les CSS.

Si vous devez créer un nouveau composant, ou modifier une partie de l’interface de votre application, que faîtes-vous ? Je ne connais personne qui lise toutes les CSS disponible dans l’application pour chercher s’il y a quelque chose qu’ils peuvent réutiliser. Quia le temps de lire des milliers de lignes de code avant de commencer à travailler ? Et même si les gens en ont le temps, je n’ai trouvé personne dont ce soit la première pensée au moment de commencer à coder. Je ne les blâme pas.

Même si vous lisiez vraiment toutes les CSS disponibles et que vous tombiez sur du code dont vous pensez qu’il pourrait être réutilisable, que se passera-t-il si quelqu’un le modifie plus tard ? Si vous partez de l’hypothèse que votre CSS n’est pas réutilisable, votre première idée sera d’écrire de nouvelles CSS. Mais il est probable que vous ne soyez pas en train de créer des nouveaux styles graphiques. D’après mon expérience, il est probable que vous soyez en train de dupliquer des styles qui existent déjà.

Salesforce peut payer les gens beaucoup d’argent. Et ils peuvent gagner des Forbes Awards pour être les plus innovants. Mais ils ne sont pas connus pour engager des gens particulièrement forts en CSS. Leurs CSS sont tout sauf innovant. Après avoir lu tous les CSS et après avoir pleuré, m’être gratté la tête et avoir ri tout fort, j’ai conclu que ce problème n’existait que chez Salesforce. J’étais sur que de super boîtes comme Medium, GitHub, Adobe et Pinterest n’avaient pas ce genre de problèmes. Elles ont engagé certains des plus extraordinaires développeurs CSS que j’ai jamais rencontré. Ils doivent avoir compris comment faire évoluer leurs CSS.

J’ai donc naturellement ouvert leurs site et j’ai commencé à lire aussi leurs CSS. Ligne par ligne. Du début à la fin. Je voulais voir à quoi ressemblait la réalité de tout le monde.

J’ai trouvé exactement les mêmes choses.

Regardons ensemble les ensembles de règles qui définissent des éléments à display none :

Ça fait beaucoup de code pour passer des choses en display: none. Si vous regardez les fichiers ci-dessus, posez-vous quelques questions : Est-qu’ils semblent suivent les principes de DRY ? Est-ce que cela vous semble du code que vous sauriez comment réutiliser ?

Si je dois écrire des CSS, je veux que ce soit réutilisable. Si personne ne le réutilise, cela semble assez inutile.

Que signifie DRY, exactement ? Parce qu’il faut bien se répéter quelque part ! Soit vous vous répétez dans le HTML ou dans les CSS. Mais aussi bon que vous soyez en HTML, vous ne pouvez pas créer un nouveau composant  sans modifier du HTML. Mais il est possible de créer un nouveau composant sans écrire une seule ligne de CSS. Et c’est également applicable à un changement d’interface. Vous devriez pouvoir modifier la plupart des choses simplement en modifiant du HTML.

Quand vous vous répétez dans le HTML, ça n’est pas vraiment gênant pour la taille de votre fichier (c’est-à-dire que les modèles multi-classes ne vont pas faire gonfler votre HTML). Un utilisateur n’a pas besoin de télécharger chaque fichier HTML de votre site pour voir une page. Mais la plupart des sites web sont architecturés d’une façon qui nécessite que vous téléchargiez le CSS pour tout le site quand vous essayez de voir une page. C’est un modèle qui ne fonctionne pas.

Les fichiers ci-dessus sont dus à des auteurs de CSS qui écrivent des sélecteurs très longs, qui ajoutent beaucoup de poids à votre cascade pour faire une ou deux choses. Et plus le temps passe, plus il y a de choses dans votre cascade que vous devez surcharger. Donc vous sélecteurs deviennent de plus en plus longs, vos fichiers deviennent de plus en plus gros et le temps passé à débugger des CSS va augmenter.

Si vous suivez ce modèle, vous n’arrêterez jamais d’écrire des CSS. Refactoriser les CSS est difficile et prend du temps. Effacer des CSS inutilisées est difficile et prend du temps. Et le plus souvent, ce n’est pas un travail qui soulève l’enthousiasme. Conséquence ? Les gens continuent à écrire de plus en plus de CSS.

Ceci affecte l’évolutivité de deux façons. D’abord, cela rend le travail sur votre application plus difficile, parce qu’il n’est pas réaliste de mémoriser toutes les CSS de votre application. Et si ce code n’est pas internalisé, il y a peu de chances qu’il soit réutilisé. Cela signifie également que vos utilisateurs doivent télécharger de plus en plus de code. Et si vous vous dîtes “oh, ce n’est pas si grave, gzip va arranger tout ça”, et bien vous avez tort. Pinterest a plus d’1Mo de CSS non compressé, réparti sur 5 fichiers. Une fois gzippé, il y a toujours un énorme 159Ko. Ça fait beaucoup de CSS. Dont 97% n’est pas utilisé sur la page d’accueil. Je préférerais essayer d’envoyer à mes utilisateurs les 3% dont ils ont besoin.

Une partie de cette explosion de la taille du code est liée à l’utilisation de noms de classes se rapportant au contenu. Je suis honnêtement surpris qu’on puisse encore trouver des gens qui pensent que ce n’est pas la pire idée possible. Nicolas Gallagher a déjà écrit l’article définitif pour expliquer pourquoi cela ne fonctionne pas. Mais, pour une raison que j’ignore, on trouve encore des gens qui pensent que c’est la solution ultime. Je pense qu’internet ne fonctionne pas aussi bien qu’il le devrait. J’imagine donc que ce qu’on nous a appris est majoritairement faux.

On arrive donc au cœur du problème que j’ai avec n’importe quel system qui nécessite de lier des styles graphiques à des composants dans vos CSS. La sémantique des contenus N’A AUCUN RAPPORT AVEC LES STYLES VISUELS. Quand je construisais des choses en Lego, je ne me suis jamais dit “Oh, ça c’est un pièce pour faire un moteur”. Je me disais “Oh, cool, c’est un Lego bleu 1×4 et je peux faire ce que je veux avec”. L’important n’était pas que je construise la base sous-marine des aquanautes ou un avion : je savais exactement comment utiliser ce bloc de Lego.

Tout est dans ces pièces de Lego. Parce que je n’ai jamais eu besoin de recontextualiser ma compréhension des blocs de Lego. Je pouvais les utiliser pour différents “projets” et ils étaient toujours identiques. C’est ce dont je rêve pour ce monde de développement front-end. Je veux des blocs de Lego qui fonctionnent partout parce que pouvoir utiliser des solutions indépendantes du projet est très puissant.

En dehors de quelques éléments spécifiques comme des background-images, des dégradés, des couleurs, etc. la très grande majorité des CSS dont vous avez besoin pour votre site a déjà été écrite. Pourtant, nous sommes une communauté qui réinvente constamment la roue. C’est un peu comme fabriquer un appareil photo à chaque fois que vous voulez prendre une photo. Je pense que fabriquer des appareils photos est cool, et que c’est un passe-temps intéressant. Mais je ne veux pas le faire à chaque fois que je vais prendre une photo. Je veux juste prendre des photos.

Quand je lis ou écoute des avis sur la façon de faire évoluer les CSS d’une application, le cœur de la discussion concerne la façon d’écrire les CSS. La vraie façon de faire ces CSS qui fonctionne à grande échelle, c’est d’arrêter d’écrire des CSS. Extrayez les choses que vous utilisez le plus et utilisez un modèle multi-classe qui vous permet des créer vos modèles graphiques dans le HTML. Vous serez étonné de voir à quel point votre équipe va rapidement avancer.

Les gens qui écrivent des CSS apportent beaucoup de problèmes. Des valeurs inconstantes, l’introduction de nombres magiques, du code dupliqué, des modèles non-responsifs. Je suis certain qu’il y en a d’autres.

Si vous créez un système à la fois flexible et puissant, et que vous construisez à partir de cette base, vos designs seront plus harmonieux. Vous pourriez passer moins de temps à débugger la cascade. Vos pages chargeront probablement plus vite. Mais qui sait. Peut-être que ça ne fonctionnera pas pour vous. Tout ce que je sais c’est que le modèle actuel ne fonctionnera pas.

Écrire de nouvelles règles CSS devrait être l’exception, pas la règle.

Quelques idées pour finir

Si vous n’avez jamais lu vos CSS de production du début à la fin, je le conseille comme une façon extraordinaire d’apprendre de nombreuses choses à la fois sur les CSS et sur la façon dont les gens les utilisent. Après avoir lu les CSS de Salesforce, j’ai commencé à lire la totalité des CSS de nombreux sites. Je le fais encore ! Et j’apprends quelque chose de nouveau à chaque fois.

Ce n’est pas un dogme. Le vrai but de cet article est de vous encourager à remettre en cause vos hypothèses. Peu de gens s’assoient avec d’autres personnes qui construisent des interfaces just pour *observer* la façon dont ils construisent de nouvelles fonctionnalités ou en refactorisent d’anciennes. L’observation est une très bonne façon d’apprendre comment les gens font des choses. Vous pouvez apprendre beaucoup de gens qui sont très forts pour écrire du code front-end et aussi de gens qui sont de complets débutants. Je n’aurais pas appris grand-chose de tout ça si je m’étais assis dans mon coin à essayer de résoudre des problèmes tout seul ou en lisant les derniers articles de blogs à la mode. La réalité c’est que beaucoup de personnes avec des niveaux de compétences variés vont toucher à votre code front-end et que vous devriez mettre en place un système qui fonctionne pour tout le monde.

Merci à tous ceux qui m’ont donné leur avis sur ces pensées durant ces dernières années. Et des remerciements particuliers aux précurseurs qui ont eu le cran de remettre en question les bonnes pratiques existantes et qui m’ont donné le courage de faire la même choses, @stubbornella@necolas et @dam.

Leave a Reply

Your email address will not be published. Required fields are marked *