// BLOG
La méthodologie CSS GPS
Ecrire du code CSS n'est pas très compliqué, en revanche organiser ses CSS et choisir une méthodologie de nommage pour s'y retrouver facilement et favoriser la maintenance de ce code dans le temps est une autre affaire. Et plus le projet prend de l'ampleur plus le problème se pose.
Introduction
Il existe des méthodologies pour aider les intégrateurs et intégratrices à s'organiser et essayer de mettre un peu d'ordre dans le code CSS. Il s'agit par exemple des méthodologies BEM, OOCSS, SMACSS, Cube CSS, SUIT CSS ou encore Systematic CSS dont vous avez probablement déjà entendu parler, du moins pour certaines d'entre elles. Pour ma part, j'utilise une autre méthode appelée CSS GPS qui est relativement confidentielle mais que j'apprécie pour sa simplicité. Elle s'applique bien pour la taille des projets sur lesquels je travaille habituellement.
Dans cet article je vais vous présenter la méthodologie CSS GPS que j'utilise dans mes projets Kirby CMS.
Principe
La "GPS CSS Methodology" est une approche pour organiser le CSS en le divisant en trois niveaux : global, spécifique à la page et spécifique à la section. D'où les trois lettres GPS : "G" pour Global, "P" pour Page et "S" pour Section.
- Global : Styles CSS s'appliquant à l'ensemble du site (typographie de base, reset CSS, etc.)
- Page-specific : Styles spécifiques à une page donnée (par exemple la page d'accueil, la page A propos, la page Blog, etc.).
- Section-specific : Styles spécifiques à des sections de pages.
Les objectifs principaux ce cette méthode sont :
- d'éviter les "fuites de portée" où des styles affectent involontairement d'autres éléments du site.
- de rester DRY en évitant des répétitions.
- de produire un code CSS propre et lisible sans être trop verbeux.
Revenons un peu plus en détail sur les trois niveaux d'organisation du CSS de la méthode GPS :
Global
Les styles globeaux sont ceux que vous utilisez à plusieurs endroits de votre site web. Par exemple sur plusieurs pages. Ces styles sont généralement les styles qui donnent une unité graphique a votre design web et caractérise votre charte graphique ou votre image de marque.
Il peut s'agir des balises d'en-tête H1, H2, H3 ... ou la façon dont vous stylez vos boutons. Il peut s'agir d'élément HTML de base comme UL, H ou P, dans ce cas pas besoin de définir des noms de classe. Pour d'autres éléments globaux, par exemple pour le style d'une card que vous utilisez sur plusieurs pages différentes, vous définirez un nom de classe qui commence par le prefixe g-
pour Global, par exemple class="g-card"
Les styles globeaux sont toujours designés à l'aide de Class et jamais à l'aide d'Id.
Page
Les styles de niveau Page se situent hiérarchiquement entre les niveaux de type Globaux et de type Section.
Les critères de base qui définissent une page sont les suivants :
- Il s'agit d'une vue importante, qui aurait sa propre page dans un site classique.
- Il n'est pas possible d'en trouver plus d'une dans la fenêtre du browser en même temps.
- Elle contient une ou plusieurs "Section"
Les styles spécifiques à une page sont des styles qui ne s'appliquent pas globalement au site, mais localement à tous les éléments d'une page spécifique. Par exemple si vous utilisez des cards dont le design est identique sur toute la page mais unique à cette page.
Toutes les pages doivent avoir un ID avec le nom de la page dans l'élément body, afin de permettre un repérage simple dans la page.
Tout style CSS que vous écrivez et qui n'est pas global doit toujours être placée sous une page.
Les Id de page sont préfixés par p-
Par exemple pour une page home
on mettra dans la balise body l'Id id="p-home"
Section
Une section est définie comme une partie d'une page. Par exemple, sur votre page « À propos », vous pourriez avoir une partie contenant un paragraphe d'introduction, puis une section présentant votre biographie, puis une section présentant les informations de contact. Chacune de ces sections est définie comme une section à part entière et, comme il ne peut y en avoir qu'une par page, elles sont également marquées par des identifiants.
Si vous écrivez un style CSS qui ne s'applique qu'à cette section spécifique, il doit être imbriqué sous au moins deux niveaux d'identifiants, l'identifiant de la page et l'identifiant de la section. Même si vous avez une section qui porte le même nom par coïncidence sur une autre page, il n'y aura pas de fuite parce qu'elle est couverte par l'identifiant de la page également.
Si vous remarquez plus tard que le même style CSS est utilisé ailleurs sur la même page, vous pouvez le faire remonter à un style spécifique à la page. Et si vous remarquez qu'il est utilisé sur d'autres pages, vous pouvez l'élever au niveau global.
Dès que vous constatez la nécessité d'utiliser un bloc de CSS en dehors d'une section, faites-en un style au niveau de la page. Et si vous en avez à nouveau besoin en dehors de la page, faites-le passer au niveau global.
Exemple de code
Il est tant d'illustrer tout cela avec un peu de code, j'ai mis des commentaires dans les snippets de code pour les explications :
global.css
h1 {...}
p {...}
.g-full-width {...}
.g-half-width {...}
Une page Index
<!-- Page Index -->
<body id='p-index'> <!-- On ajoute un ID dans le body de la page "p-nompage" -->
<div id='banner'> <!-- Section spécifique "banner" -->
<h1>Welcome to the Example Page!</h1> <!-- Style global sur les balises h1 -->
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.</p>
</div>
<div id='photos'> <!-- Section spécifique "photos" -->
<img class='g-full-width' src='example.jpg' /> <!-- Style global prefixé g- -->
<img class='g-half-width left' src=example2.jpg />
<img class='g-half-width right' src=example3.jpg />
</div>
</body>
index.css
#p-index .left { ... } /* Styles niveau page, n'est utilisé que dans la page index */
#p-index .right { ... } /* Styles niveau page, n'est utilisé que dans la page index */
#p-index #banner h1 { ... } /* Styles niveau section, n'est utilisé que dans la section banner de la page index */
#p-index #photos img { ... } /* Styles niveau section, n'est utilisé que dans la section photos de la page index */
Une page About
<!-- Page About -->
<body id='p-about'> <!-- On ajoute un ID dans le body de la page "p-nompage" -->
<h1>About Us</h1> <!-- Style global sur les balises h1 -->
<div id='intro'> <!-- Section spécifique "intro" -->
<img class='g-full-width' src="us.jpg" /> <!-- Style global prefixé g- -->
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Etiam porta sem malesuada magna mollis euismod.</p>
</div>
<div id='staff'> <!-- Section spécifique "staff" -->
<img src="staff/john.jpg" />
<img src="staff/kate.jpg" />
<img src="staff/adam.jpg" />
</div>
</body>
about.css
#p-about h1 { ... } /* Styles niveau page, n'est utilisé que dans la page about */
#p-about #intro p { ... } /* Styles niveau section, n'est utilisé que dans la section intro de la page about */
#p-about #staff img { ... } /* Styles niveau section, n'est utilisé que dans la page index de la page about */
Rappelez-vous qu'il n'est pas valide de mettre deux Id identiques dans la même page. Les Id permettront de visualiser plus facilement dans votre code CSS les grandes catégories de styles (page, section).
Media Queries
Pour l'écriture des media queries, l'approche de la méthodologie GPS est d'utiliser un preprocesseur (SCSS, Stylus ...) qui supporte les règles imbriquées pour regrouper sous un même selecteur toutes les règles qui s'y appliquent.
Par exemple :
.foo {
color: red;
@media (min-width: 30em) {
color: blue;
}
}
Personnellement, je ne suis pas fan des préprocesseurs car ils rajoutent une couche de technologie dans notre stack technique et donc de la compléxité pour la maintenance. A vous de voir en fonction du coût/bénéfice que vous en retirez.
Maintenant, on peut se poser la question : faut-il écrire les règles de media queries à part dans un fichier externe par exemple et de manière globale ou de façon plus spécifique tout de suite après le selecteur concerné ? Une fois de plus c'est une histoire de préférence mais j'aurais tendance à penser que c'est plus facile à lire lorsque la media queries est définie pour chaque élément au même endroit.
Les points de rupture
L'approche de la méthodologie GPS conseille de créer des requêtes média en fonction du contenu plutôt que de la taille de l'appareil ou de l'écran. En règle générale, vous allez donc réduire la taille de la fenêtre du navigateur et, juste avant que quelque chose ne commence à sembler bizarre, vous allez ajouter une requête de média à ce moment-là pour y remédier. Peu importe que le nombre ne corresponde pas à une taille d'écran spécifique, de nos jours, il y a tellement de taille d'écran différent que cela n'a plus beaucoup de sens. Continuez ensuite à le faire pour tous les autres éléments de la page.
Aujourd'huie avec les Container Queries, on peut styliser un élément en fonction de la taille de son conteneur parent, plutôt que de la taille de la fenêtre d'affichage comme avec les media queries.
Organiser les fichiers CSS
Ce sujet n'est pas abordé dans la méthodologie GPS mais voici, à titre d'information, comment j'organise mes fichers CSS dans un projet Kirby CMS.
J'aime bien ne pas mettre mes oeufs dans le même panier pour mieux m'y retrouver. Je répartie donc mon code CSS dans plusieurs fichiers CSS que je merge et minifie ensuite lors de la mise en production pour produir un fichier optimisé styles.min.css
.
Le fichier de développement central est nommé styles.css
il importe tous les autres fichiers CSS, cela pourrait ressembler à :
/* Divers */
@import 'reset.css';
@import 'fonts.css';
@import 'variables.css';
@import 'global.css';
/* Snippets */
@import 'snippet/header.css';
@import 'snippet/footer.css';
@import 'snippet/sidebar.css';
/* Pages */
@import 'pages/home.css';
@import 'pages/about.css';
/* Utilities */
@import 'utilities/grid.css';
@import 'utilities/font-size.css';
A vous de choisir la façon dont vous souhaitez regrouper votre code css pour définir les thématiques de chaque fichier css.
Si vous utilisez des frameworks CSS à base de classes utilitaires comme Tailwind CSS, vous aurez toujours, à un moment donné dans votre projet, des cas spécifiques de code css qui ne seront pas couvert par les classes utilitaires du framework. Dans ce cas, il faudra prévoir un ou plusieurs fichiers css à part pour traiter ces cas spécifiques.
Lorsque je suis dans ce cas, je distingue le nom des classes utilitaires du framework des noms des classes custom que j'ai créé en les balisant avec des crochets.
Ce qui pourrait donner par exemple :
<div class="[activation card-container] mr-4 p-6 flex">Lorem ipsum ...</diV>
Conclusion
La méthode CSS GPS est celle qui me permet aujourd'huie d'organiser et de nommer mes css dans mes nouveaux projets Kirby CMS. J'ai beaucoup tatoné avant de trouver une méthode qui me convienne. Peut-être que d'autres méthodes vous conviendront mieux mais comme on parle peu ce celle-ci, il me paraissait intéressant de vous la présenter.