Originellement conçu pour des web designers, CSS se veut être un langage de description et non de programmation.
Mais ça c'était avant.
Le Web a évolué, nos usages et consommations également. CSS s'adapte petit à petit au contexte actuel et se complexifie pour devenir "un vrai langage" (avec variables, calculs et fonctions, notamment).
En attendant une hypothétique stabilisation du langage, nous en sommes aujourd'hui à déplorer des feuilles CSS de taille astronomique et de moins en moins maintenables en production.
Par exemple, sur le site alsacreations.com (hors forum), sur un fichier CSS de 32ko, l'outil StyleStats ne dénombre pas moins de :
-
46 occurences de
!important
-
41
float
inappropriés -
402 sélecteurs d'
ID
- 28 tailles de polices différentes
- 36 couleurs de texte différentes
- etc.
Une convention pour éviter la bidouille
Pour améliorer notre quotidien d'intégrateur, l'agence Alsacréations s'est constitué une mini Convention CSS contenant toutes les bonnes pratiques qui nous paraissent essentielles à ce beau langage qu'est CSS.
Ne nous lançons pas de fleurs : nous n'avons rien inventé, uniquement compilé les conseils et astuces de multiples autres sources.
Remarque : il s'agit d'une convention correspondant à nos besoins internes de petite agence web, vous devrez bien entendu l'adapter à votre environnement.
Lien vers la présentation : https://speakerdeck.com/goetter/mini-convention-css
Les bonnes pratiques CSS
Voici le contenu de cette mini convention CSS.
- Généralités
-
Bonnes pratiques générales
-
Modèle de boîte :
Opter pour le modèle de boîte CSS3 (box-sizing: border-box
) en début de la feuille de style -
Tailles de polices :
Opter pour des tailles de polices fluides (de préférence enrem
). -
Flux :
Éviter de sortir les éléments du flux (float
,position
) sans nécessité. -
Positionnement :
Positionner les éléments en choisissant de préférencedisplay
(block
,inline
), puisflexbox
, puisinline-block
outable-cell
-
Lecture :
Écrire des syntaxes compréhensibles par des êtres humains et des collègues. -
Namespaces :
Préfixer les classes par « namespace » pour les regrouper et les distinguer aisément.
-
Modèle de boîte :
-
Maintenance et lisibilité
-
Poids des sélecteurs :
Éviter de surcharger un sélecteur, car cela lui ajoute du poids inutilement. -
Sélecteur
#ID
:
Éviter d’utiliser le sélecteur d’id
, son poids est trop important et difficile à maintenir, éviter également le bazooka!important
-
Sélecteurs de structure :
Éviter les sélecteurs associés à la structure HTML, un élément doit pouvoir être ciblé quel que soit son conteneur ou son emplacement dans le DOM. -
Structure et apparence :
Séparer la structure de l’apparence dans les sélecteurs pour faciliter la factorisation. -
Factoriser les propriétés :
Toujours tenter de rassembler les propriétés identiques. -
Surcharge :
Éviter d’écraser une règle par une autre. -
Redondances :
Utiliser des pré-processeurs (Sass, LESS, Stylus) pour éviter les répétitions de code. -
Réutiliser les blocs :
Grouper les éléments par composants réutilisables. -
Ne pas trop réutiliser :
Se limiter à 4 noms de classes au maximum par élément HTML. Si l’on pense qu’il en faut davantage, il est temps d’envisager une classe personnalisée.
-
Poids des sélecteurs :
-
Performances
-
Animations gourmandes :
Éviter d’animer des propriétés autres quetransform
ouopacity
, ou alors ajouter la propriétéwill-change
et/ou le hack detranslateZ()
. -
@font-face performant :
N’imposez pas de chargements aux anciens navigateurs (IE8). Privilégiez.woff2
. Conservez l’astuce du#iefix
-
Propriétés raccourcies :
Préférer les propriétés raccourcies. -
Unités :
L’unité est inutile si la valeur est nulle. Ne pas donner d’unité àline-height
. -
Préfixes vendeurs :
Automatiser la gestion des préfixes à l’aide de Autoprefixer, ne pas le faire à la main et ne pas utiliser un mixin Sass/LESS pour cela.
-
Animations gourmandes :
Commentaires
Bonjour l'équipe Alsacréations,
Je ne peux pas être d'accord avec certaines des recommandations.
Certes la règle de "ne pas faire de style dans le HTML" n'est plus viable aujourd'hui. Mais lorsque je vois une classe nommée " .fr " pour "float: right" mes poils s'hérissent. Une telle écriture est totalement fermée et revient non-pas à attribuer un comportement à un objet mais à lui définir explicitement un attribut. Si après coup on se rend compte que l'attribut choisi n'était pas le plus judicieux nous sommes bon pour une réécriture du HTML. C'est une bien mauvaise manière de procéder.
Il est certes nécessaire aujourd'hui de factoriser ses classes. Mais pour une bonne maintenabilité il est essentiel de demeurer dans une logique de description comportementale. Dans l'exemple présent, en imaginant qu'il s'agisse d'un élément de navigation de slideshow par exemple, une classe " .next " serait la meilleure solution. Pourquoi pas " .right " ? Car le positionnement à droite de l'objet effectuant l'action "next" est un choix design. Celui-ci pourrait tout aussi bien être positionné en bas voir même avoir un positionnement différent selon l'affichage sur desktop ou mobile.
Pour le reste, j'estime que la plupart des conseils sont absolument évidents lorsqu'on sait développer en CSS... Mais j'ai été débutant et il est toujours bon de diffuser les bonnes pratiques. Good job !
@erwan21a : c'est un très très vaste débat.
Sois assuré que je suis un fervent défenseur des classes "sémantiques", mais au coeur de notre quotidien en production il est aujourd'hui nécessaire de se remettre en question : https://blog.goetter.fr/2012/09/09/css-la-grande-remise-en-question/
Ceci dit, et comme je l'ai précisé, ce sont les bonnes pratiques que *nous* considérons adéquates, il se peut que cela ne corresponde pas à tes besoins.
« Nothing is obvious to the uninformed! »
Merci pour le partage d'expérience :)
@Raphael :
Oui oui, nulle intention de ma part de lancer un débat sans issue. :)
Pour expliquer ma position (pour ceux qui lisent ces lignes), je suis web designer 'chez l'annonceur'. La question de la maintenabilité est donc au prépondérant dans mon quotidien. Globalement le produit que propose l'entreprise où je travaille change peu (développer une nouvelle fonctionnalité coûte cher). C'est donc au niveau graphique que le renouvellement s'opère en premier lieu. Notre produit peut s'avérer assez complexe également avec du HTML présent dans des fichiers JS pour le templating, voir écrit en Jade ; du HTML généré par un CMS ; ou simplement du html issu de différent projets. Toucher au HTML comporte toujours le risque d'oublier une occurrence et le risque croît avec la taille du projet. Les CSS étant unifiés pour la mise en production, il est rapide de contrôler que nous n'avons pas de doublons ou de classes inutiles (des tasks automatisées peuvent même le faire pour nous).
La souplesse se trouve davantage du coté CSS que du coté HTML. Mettre fin aux concepts intégristes des années 2000 et décloisonner le HTML du CSS était essentiel pour permettre au web design de se libérer d'une sémantiques trop limitée. Mais ne tombons pas dans un extrême inverse.
D'où ma recommandation de demeurer pragmatique dans la factorisation des classes CSS en conservant une possibilité d'évolution. Car l'évolutivité est tout l’intérêt de CSS. Quand je vois des classes de type " .w100p " dans KNACSS je me dis qu'il serait tout aussi simple d'ajouter un " style=width:100px; "...
ps : je sais j'abuse avec la petite pique envers KNACSS à la fin. Mais ça a été plus fort que moi. ahah
@erwan21a : toi tu ne vas pas apprécier les derniers concepts à la mode en CSS : pour le plaisir, je te laisse jouer avec http://acss.io/ (développé par Yahoo!) :p
@Raphael : J'ai toujours eu du mal avec le concept de mode...
Je n'étais pas au courant de ce projet (merci !). Personnellement j'imagine davantage une fusion entre JS et CSS qu'entre CSS et HTML. On verra ce que l'avenir nous réserve. :)
@Raphael : Oh putain, j'ai pas regardé dans le détail mais à priori quand tu en arrives à ce niveau de classite c'est autant écrire du style en ligne !!!
Définitivement je reste un enfant du CSS Zen Garden.
@Gaby22 : ne t'inquiète pas, ils ont des arguments pour cela : http://acss.io/frequently-asked-questions.htm...
@Raphael : Nan mais en vrai... C'est un coup du Gorafi ? :D
Tous leurs arguments sont propres au fait de bien développer. Faut-il donc comprendre que les intégrateurs de chez Yahoo sont tellement nuls qu'il a fallu leur créer un langage adapté ? ^^
Il est aussi amusant de comparer les statistiques affichées à la réalité des sources (tableau comparant le nombre de rules, selectors, declarations...). En effectuant soit même la mesure avec la source citée (http://cssstats.com) on obtient des résultats bien différents.
@erwan21a : ça ne fera pas plaisir à Thierry Koblentz (un vrai expert CSS selon moi), ni à Hugo Giraudel (qui n'est pas trop mauvais non plus paraît-il).
Allez, j'en rajoute une couche fraîche : https://speakerdeck.com/hugogiraudel/local-styling-with-css-modules
Attention, tout dépend du contexte n'est-ce pas ? Ce ne sont certainement pas des pratiques à reproduire massivement et systématiquement.
Tiens, Thierry Koblentz vient justement de publier une argumentation intéressante en faveur de Atomic CSS : http://cssmojo.com/a-retort-to-reuse-on-maint...
Lisez-le et forgez votre avis selon votre contexte, environnement et compétences.
Bonjour, n'est-il pas problématique en termes de performances d'utiliser systématiquement le sélecteur étoile (*), alors qu'il ne serait - du moins, dans mes projets - requis que dans certains cas ?
(« il » = la règle « box-sizing: border-box »)
@Raphael :
Un truc qui me surprend dans de nombreux discours aujourd'hui est la phobie d'écrire en CSS... "In other words… write more css!". En quoi est-ce préférable d'écrire plus dans le HTML que dans une CSS ? Chacun a son rôle.
N'est-ce pas de la mauvaise foi que de déclarer "Meaning when you use an Atomic class, you know exactly what it styles and how it styles it." ? Nous sommes d'accord que lorsqu'un dev voit dans le HTML une classe Bdc(t) il comprend qu'un "border-color: transparent" sera appliqué. Ok. Mais lorsque le même dev voit dans le CSS la règle "border-color: transparent" il comprend tout autant ce qui sera appliqué.
Encore un sophisme sur la partie "It says it’s too many tasks/rules" ou est déclaré "Is it 6 declarations for 1 module? 60 declarations for 10 modules? 600 for 100 modules? And so forth?". Si les modules ne sont pas différents, un même ensemble de classes sera évidement utilisé. Utiliser CSS ne signifie pas être idiot. Avec Atomic Css, si 60 modules sont présents dans la page, il faudra écrire 60 fois les longues déclarations de classes. Pour reprendre l'exemple de 3 éléments imbriqués composant le module et en se basant sur la limite de 5 classes maximums par élément, avec Acss on obtient (3 * 5 * 60) 900 classes à taper dans son HTML alors qu'avec CSS on en tape que 180 + 15 lignes de CSS (3 * 5). Et l'auteur de conclure par un "An approach that leads to the most dreaded CSS issues: [...] unmaintainable style sheets" paraissant un brin abusé au regard de la lisibilité d'un bout de HTML utilisant 900 classes...
"Authors never have to fear to change a style, [...] all authors need to do is create a new class for that new style. And that’s not redundant code, because regardless of the approach you take, you’ll be using different classes for different values." Franchement c'est quoi cette histoire d'avoir peur de modifier une règle CSS, de craindre que la personne qui intervient sur le code créer de la redondance ou du conflit d'attribut ? Il suffit d'embaucher des personnes compétentes !
Encore un sophisme dans le paragraphe "It says reuse causes bloat" qui expose un constat général en se basant sur un (mauvais) exemple précis donné par son interlocuteur. Il est comparé la syntaxe Acss avec des classes "someModule", "someModule-someComponent" et "someModule-someOtherComponent". Mais qu'est-ce qui interdit en CSS de nommer ses classes de manière courte comme par exemple "md", "md-c" et "md-oc" ?
Puis concernant la sémantique des classes, on touche le fond. "Indeed, we have no idea how elements to which “semantic classes” are attached are represented." Sait-on comment un <p> sera représenté ? Le rendu visuel ne peut être convenablement évalué qu'au cas par cas une fois rendu par les navigateurs. Prétendre que l'objectif de la lecture d'un fichier HTML est la compréhension de la représentation des éléments est un non-sens total. Au contraire, la surcharge du HTML brouille la lisibilité de sa réelle fonction : la structuration des éléments. Les exemples donnés dans le paragraphe "It says reuse breaks semantics" sont criants. Dans le premier exemple, non sémantique, on comprend qu'il y a un élément rouge vers la gauche et une colonne. On est bien avancé avec ça... Dans l'exemple sémantique, on sait qu'il y a un en-tête, un élément relatif au panier, un élément relatif au produit et un élément de recherche. En situation de dev, votre client ou collègue vous dit le plus souvent "hey, tu pourrais modifier le truc rouge, parfois bleu, qui est sur la gauche de la page ou en haut sur mobile" ou bien "hey, tu pourrais modifier le bouton d'accès au panier" ? Honnêtement...
Je ne doute pas qu'Atomic Css soit applicable. Il est évident que comparé à de mauvaises pratiques CSS c'est un progrès. Mais dans l'absolue je trouve que ça ne résout aucun des problèmes que ça prétend combler. :)
@Raphael : Oups, je me suis un peu lâché là :D
@Saoryx : non, le problème de "performance" du sélecteur universel (*) est complètement négligeable.
Aux dernières nouvelles (il y a 3-4 ans), dans des tests de pages avec des DOM et des CSS gigantesques truffés de sélecteurs * partout, cela se jouait à... 6 millisecondes au final.
@erwan21a : Très honnêtement, je suis moi-même encore mitigé par rapport à ces classes atomiques.
Je ne compte pas pour le moment les employer systématiquement et universellement. Ceci dit, dans certains cas, de temps à autre, pouvoir bénéficier de certaines classes "utilitaires" réutilisables et simples à comprendre et transmettre est un réel avantage.
Allez encore quelques liens (qui datent de 2013 déjà) :
- http://www.nicolas-hoffmann.net/source/1600-L...
- http://www.nicolas-hoffmann.net/source/1601-L...
- https://www.smashingmagazine.com/2013/10/challenging-css-best-practices-atomic-approach/
@Raphael :
Voila, les propos de Nicolas Hoffmann sont déjà bien plus raisonnables. :)
Fondamentalement je suis pour le concept de classe atomique. J'en utilise d'ailleurs de plus dans mes projets. Mais l'usage doit être pragmatique et raisonné. Les extrêmes ne sont jamais bons.
Merci pour ces lectures Raphael
@erwan21a : Ah mais en fait tu étais d'accord depuis le début ?! :p
@Raphael : Chut, il ne faut pas le dire...
Je me permets d'intervenir sur la 2nde slide et la recommandation d'unifier toutes les CSS en 1 seul fichier, media query compris.
Idéalement selon moi, il faut mettre la CSS "mobile" sans media query en premier, puis les autres breakpoints importants + print en <link media>.
Cela permet de laisser la possibilité au navigateur d'optimiser les chargements de ces CSS s'il en a envie. Exemples :
* ne pas charger le print avant qu'on demande l'impression, ou ne la charger que lorsque toute le reste est chargé
* ne jamais charger 1 CSS qui est plus grande que la taille maximale de l'écran de mobile
Ces règles ne sont je crois pas appliqué aujourd'hui, mais ça pourrait être le cas un jour.
De plus, grâce à l'HTTP2, on doit maintenant repenser notre façon de penser et la philosophie du "je dois avoir 1 minimum de requête HTTP, même si alourdi pour rien le contenu global chargé"
En effet, en HTTP2, le fait d'avoir 1 ou 100 requêtes ne change plus rien au niveau du temps de chargement et de connexion au server. On est sans doute plus efficace avec plusieurs petits fichiers, car le parsing par le navigateur de chacun d'eux peut commencer plus tôt. Et cela permet aussi d'alléger le poids total de chaque page, pour ne charger que ce que l'on a besoin.
Enfin, quant aux questions de mettre plus ou moins de classes, je pense plus que cela dépend des projets au final, et de sensibilité des développeurs.
Pour un petit projet, n'avoir que des petites classes avec répétition ne pose pas trop de problèmes car léger à maintenir.
Pour un gros projet, on essaiera sans doute de plus raisonner avec les modules réutilisables à mon avis, de façon à limiter la taille de la CSS et rendre plus simple une mise à jour future ; il faut alors bien affecter ces modules en ayant vraiment compris qu'ils devront toujours être affiché de la même façon.
Là encore, la taille du fichier CSS final au niveau du temps de chargement n'aura pas d'incidence sur les poids réel téléchargé dès lors qu'on le gzip.
Avec les classes atomiques, il n'est plus question de 'alternate stylesheet', si j'ai bien compris... il est vrai que c'est peu utilisé...
Je suis d'accord avec Erwann dans l'ensemble.