• 15 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 8/6/20

Structurez votre CSS

Log in or subscribe for free to enjoy all this course has to offer!

Découvrez pourquoi écrire du code bien structuré

Écrire du CSS désordonné, de nombreux développeurs l’ont fait ! On ne commence pas forcément à écrire du CSS désordonné de manière désordonnée. Il s’agit plutôt d’un processus progressif qui se met en place à mesure que l’on fait de nouveaux changements, comme commencer par écrire du CSS directement dans le HTML. Et, à moins d’être prévoyant et vigilant, vous allez finir avec une codebase CSS chaotique sans vraiment réaliser comment vous en êtes arrivé là.

Est-ce que c’est vraiment embêtant ? Tant que je finis mon projet, quel est le problème ? 🙄

Pour répondre à cette question, suivons ensemble le cours de la vie d’un site web de manière hypothétique.

Un client vous charge de créer un formulaire de contact comprenant quelques cases de texte et un bouton. Vous écrivez le HTML et le CSS, en assignant le nom de classe btn au bouton qui possède l’ensemble de règles, ou groupe d’instructions CSS, suivant :

.btn{
background-color: #001534;
color: #15DEA5;
border-radius: 3rem;
width: 100%;
padding: 1.5rem;
}

Tout cela a l’air plutôt pas mal et le client est content ! Tellement content qu’il vous demande de travailler sur le reste du site. Tout à coup, vous vous retrouvez à avoir besoin de toute une série de boutons de différentes tailles, couleurs et formes. Mais le problème, c’est que  .btn  est très spécifique : il a ses propres taille, couleur et dimension. Et malheureusement, cela ne convient pas aux nouveaux boutons. Vous allez donc devoir créer de nouveaux boutons avec leurs propres règles et vous retrouver avec des classes telles que  .btn-alt.btn-big et .btn-round. Plus tard, vous avez besoin encore d’autres boutons, et comme vos boutons sont eux aussi spécifiques, vous ajoutez .btn-small et .btn-alt-2. Vous commencez à voir le problème ? Plus vous allez avoir des boutons spécifiques, plus vous allez en créer, et ainsi de suite. Avec le temps, vous allez avoir un trop grand nombre de sélecteurs pour vous souvenir de l’utilité de chacun.

OK, mais je peux juste aller changer tous les noms manuellement si besoin, non ? Il n’y en a pas tant que ça pour le moment, et si le client est content, qu’est-ce que ça peut bien faire ?

OK, c’est vrai, le site a une bonne tête et le client est encore plus content... pour le moment !  Quelques mois passent et un beau jour votre client vous recontacte car il a besoin de modifier certains éléments précis, d’ajouter des choses, et vous devez vous replonger dans votre code. Et c’est alors que vous commencez à vous demander : à quoi ressemble  .btn-alt, déjà ? Et c’est quoi la différence avec  .btn-alt-2 ? Et quelle est réellement la taille de.btn-big ? Et pourquoi est-ce que j’ai fait ça ? 😭

Plutôt que d’effectuer vos changements rapidement et facilement, vous vous retrouvez à passer beaucoup trop de temps à démêler le plat de spaghettis qu’est devenu votre CSS. Mais alors, comment faire pour garder le fil entre vos différents éléments, et surtout dans un projet de grande envergure ? Comment gérer et se retrouver dans un CSS où vous faites sans cesse des ajouts et des modifications ?

C’est bien connu, le CSS est compliqué à maintenir en ordre. Il lui manque beaucoup de structure, structure que l’on retrouve dans la plupart des autres langages de programmation. Ça se voit rien qu’en comparant des extraits de code en HTML et en CSS : jetez un œil au code ci-dessous 👇🏼

HTML

<body>
<main class="container">
<form class="form">
<h1 class="form__heading">Contact me</h1>
<div class="form__field">
<label for="contact-name">name</label>
<input type="text" name="contact-name" id="contact-name">
</div>
<div class="form__field">
<label for="contact-email">email</label>
<input type="email" name="contact-email" id="contact-email">
</div>
<div class="form__field">
<label for="mssg">message</label>
<textarea name="mssg" id="mssg" cols="30" rows="10"></textarea>
</div>
<button class="btn btn--full-width">Submit</button>
</form>
</main>
</body>

 CSS

.container {
margin: 6rem;
padding: 1.5rem 1.5rem 0 1.5rem;
border: 0.1rem solid #D6FFF5; }
}
.form {
width: 100%;
padding-bottom: 1.5rem;
}
.form__field label {
color: #D6FFF5;
display: block;
font-size: 2rem;
line-height: 2rem;
padding-top: 1.5rem;
}
.form__field input {
width: 100%;
background: #001534;
border: 0.1rem solid #15DEA5;
padding: 1.5rem;
color: #D6FFF5;
}

Avez-vous remarqué la façon dont on voit tout de suite que les éléments HTML sont reliés entre eux par leur structure ? Alors que le CSS, lui, ressemble plutôt à une longue liste qui énumère un tas de règles les unes après les autres, sans aucun lien logique visible. Il n’y a pas grand-chose pour indiquer les relations entre les sélecteurs, ni leur spécificité. Maintenir de l’ordre quand il n’y a pas beaucoup de structure visible, c’est encore plus compliqué. Mais pas de souci, nous allons remédier à cela. 💪

Dans ce cours, vous allez apprendre comment écrire du CSS qui est à la fois mieux organisé et surtout maintenable, en :

  • appliquant des structures de fichiers clairement définies ;

  • travaillant avec un préprocesseur CSS appelé Sass, une technologie qui améliore votre codebase et vous simplifie la vie.

Votre vous du futur vous dit “merci !” 😉

Appliquez le principe du DRY

Mais alors, comment procéder pour vous assurer que le CSS que vous écrivez est propre et maintenable ? La première étape est de trouver des points communs. Pour cela, reprenons l’exemple de code CSS donné ci-dessus :

.container {
margin: 6rem;
padding: 1.5rem 1.5rem 0 1.5rem;
border: 0.1rem solid #D6FFF5; }
}
.form {
width: 100%;
padding-bottom: 1.5rem;
}
.form__field label {
color: #D6FFF5;
display: block;
font-size: 2rem;
line-height: 2rem;
padding-top: 1.5rem;
}
.form__field input {
width: 100%;
background: #001534;
border: 0.1rem solid #15DEA5;
padding: 1.5rem;
color: #D6FFF5;
}

Regardez :  on voit quelques règles qui se répètent.

Image montrant les endroits où le code se répète.
Le code se répète à certains endroits

Par exemple, vous avez plusieurs boutons que vous utilisez dans votre codebase. Tous vos boutons utilisent le même padding et la même couleur de texte, et quasiment tous ont la même couleur de fond. Cela signifie que vous avez dupliqué votre code.

Il existe un concept dans la programmation appelé le principe DRY, qui est une abréviation en anglais signifiant “Don’t repeat yourself”.

Et en français, s’il vous plaît ? 🤔

“Ne vous répétez pas !”

Toutes ces couches de règles CSS répétitives dans votre code, comme les copier-coller de couleur, de taille et autre, vous empêchent de créer une codebase DRY, la rendent encore plus difficile à maintenir et compliquent sa modification. 

Bon, mais je fais quoi du coup, concrètement ? 🤔

La première étape clé consiste à faire un refactoring ; en d’autres termes, effectuez un grand ménage dans votre code pour éviter les répétitions. Rappelez-vous : “Ne vous répétez pas !”. Commençons par passer en revue tous vos sélecteurs pour trouver des points communs. Prenons l’exemple d’un bouton. Il faut regarder tous les boutons décrits dans le code et noter quelles règles sont identiques. Disons que vous remarquez que tous vos boutons ont la même couleur de fond, la même couleur et le même padding. Au lieu de placer tous ces attributs dans chacun de vos boutons, vous allez les réunir au même endroit et éviter de vous répéter. Vous obtiendrez quelque chose qui ressemble à :

.btn {
background-color: #001534;
color: #15DEA5;
padding: 1.5rem;
}

Avec ce code, sans règles supplémentaires, le bouton aura la largeur de son contenu, plus le padding. Et les coins seront carrés ! Vous avez donc un bouton générique que vous pouvez utiliser autant de fois que vous le voulez sans ajout de code et surtout sans répétition. Parfait, non ?

Et si j’ai un bouton qui doit être plus large ou plus arrondi, je fais quoi ? 🤔

Pas de panique, vous pouvez créer des règles additionnelles au  .btn  original, qui seront réparties dans de nouveaux sélecteurs plus spécifiques :

.btn-wide {
width: 100%;
}
/* And... */
.btn-rounded {
border-radius: 3rem;
}

Donc en HTML, au lieu de ressembler à ça :

< button class="btn" >...</button>

votre markup ressemble à ça :

< button class="btn btn-rounded btn-wide" >...</button>

Ce que vous venons de faire s’appelle separation of concerns (ou séparation des préoccupations). L’idée est que votre HTML ne contienne que les informations nécessaires à son contenu. Ainsi, toutes vos règles de style sont définies dans votre fichier CSS et  sont réutilisables. Fini le CSS en dur dans le HTML ! Dans notre exemple de bouton .btn, nous avons défini l’apparence de nos boutons et rien de plus.

Chaque bouton dans votre code aura les qualités définies dans le sélecteur. Ensuite, pour ajouter des règles supplémentaires, nous créons les sélecteurs dans  .btn-wide  et  .btn-rounded  qui modifieront notre bouton de base  .btn.

.btn {
background-color: #001534;
color: #15DEA5;
padding: 1.5rem;
}
.btn-wide {
width: 100%;
}
/* And... */
.btn-rounded {
border-radius: 3rem;
}

Ensuite, lorsqu’on les ajoute les uns après les autres dans notre markup, nous disons que l’on utilise  .btn  puis que l’on applique .btn-rounded  et enfin  .btn-wide.

< button class="btn btn-rounded btn-wide" >...</button>

Ainsi, en regroupant vos classes et en les séparant par leur fonction, votre codebase devient instantanément plus facile à maintenir. Plutôt que de recourir à Ctrl+F et Chercher-remplacer pour modifier le padding de vos boutons, il vous suffit de changer la valeur d’un seul ensemble de règles, ici  .btn, et la modification se répercutera dans tous les  .btn  de votre site.

.btn {
background-color: #001534;
color: #15DEA5;
padding: 1.5rem;
}

Une fois de plus, votre futur moi vous fait part de toute sa gratitude.  🙌

Essayez par vous-même !

Dans cet exercice, vous allez vous entraîner en créant une nouvelle classe et séparer les propriétés typographiques pour les appliquer indépendamment sur la div de votre choix.

Coding application
Houston... ?
It seems you're not connected to the internet.
You are not signed in

Sign in to access coding exercises and test your new skills.

Make sure to practice in this chapter before moving on.

L’impact de la spécificité sur la structure de votre code

Vous savez maintenant pourquoi il est important de structurer votre code, mais pour le faire efficacement, vous devez comprendre un concept fondamental, la spécificité.

Qu’est-ce que la spécificité ?

Si on prend la définition de la documentation MDN, on obtient : 

La spécificité est la manière dont le navigateur décide quelle règle s’applique si plusieurs règles ont des sélecteurs différents, mais peuvent quand même s’appliquer au même élément.

En d’autres termes, la spécificité permet d’attribuer un score à un sélecteur afin de déterminer lequel a le plus de valeur par rapport à un autre au sein du HTML, et permet donc de déterminer la priorité d’un sélecteur par rapport à un autre. C’est comme un système de scores : celui qui a le plus de points gagne ! 👩‍🏭

Euh... au secours ? 😶

Pas de panique, on va y aller ensemble étape par étape ! Prenons un exemple pour illustrer. Disons que vous avez un élément bouton dont l’id est  submit-button  et la classe est  .button  :

HTML

Nous avons trois sélecteurs : une div, un id  #submit-button  et une classe  .button

<div id="submit-button" class="button">Click Here!</div>

Travaillons avec  #submit-button  et  .button. Dans votre fichier CSS,  #submit-button et  .button  ont une couleur de fond différente car vous utilisez la classe .button autre part dans votre code :

 CSS
#submit-button {
background-color: #15DEA5;
}
.button {
background-color: #DB464B;
}

Du coup dans ce cas là, quand vous voyez votre bouton dans un navigateur, de quelle couleur sera-t-il ? 🤔

La réponse se trouve dans la spécificité de chaque sélecteur. Quand des règles contradictoires s’appliquent à un élément, comme dans notre exemple avec plusieurs couleurs de fond en même temps, le navigateur appliquera la règle émanant du sélecteur le plus spécifique.

Mais comment un navigateur détermine-t-il la spécificité d’un sélecteur ?

Regardons cela de plus près !

Découvrez les quatre piliers de la spécificité

Un navigateur distingue quatre catégories de règles CSS.

1) Le style inline, défini directement dans le HTML

Lorsque vous écrivez du CSS dans du HTML, c’est ce qu’on appelle du style inline.

<div style="background-color:#15DEA5;">Click Here!</div>
2) Les id

Les id sont uniques et s’appliquent à un object unique. Vous ne pouvez pas utiliser plusieurs fois un id dans votre HTML.

<style> #submit-button { background-color: #15DEA5; } </style>
<div id="submit-button">Click Here!</div>
3) Les classes, pseudoclasses et attributs

Une pseudoclasse est un mot clé ajouté à un sélecteur qui permet de spécifier un état comme  :hover, par exemple, qui indique que l’on passe la souris au-dessus du sélecteur. Les attributs permettent de sélectionner un sélecteur précis.

<style> .button { background-color: #DB464B; } </style>
<div class="button">Click Here!</div>
4) Les éléments et pseudoéléments
<style> div { background-color: #DB464B; } </style>
<div>Click Here!</div>

Quand le navigateur détermine quelle règle appliquer parmi celles contradictoires comme dans notre cas, il fait le compte du nombre de catégories qui sont implémentées par un sélecteur. Nous allons représenter la spécificité avec un tableau qui répertorie les types de sélecteurs sous forme de tableau de scores, afin que vous compreniez comment le navigateur procède.

Dans notre exemple, nos trois sélecteurs seraient donc pris en compte comme suit.

Sélecteur 1

#submit-button {...} :

Inline

ID

Class

Element

0

1

0

0

Sélecteur 2

.button {...}:

Inline

ID

Class

Element

0

0

1

0

Sélecteur 3

div {...}:

Inline

ID

Class

Element

0

0

0

1

Une fois cette comptabilisation effectuée, le navigateur commence par regarder les scores des sélecteurs dans la colonne de gauche, parce que le CSS local (dans le HTML) est plus spécifique. S’il y trouve un sélecteur avec un score plus élevé que les autres dans la première colonne, le navigateur appliquera son style en priorité. En cas d’égalité, il passe à la colonne suivante et effectue la même opération.

Dans le cas de nos trois sélecteurs, la première colonne est à 0 pour les 3 sélecteurs. Aucun d’entre eux n’a de CSS implémenté localement dans le HTML. C’est pour cette raison qu’ils ont tous un score de zéro. Le navigateur passe donc à la colonne suivante, la colonne ID, où un gagnant se dégage clairement : #submit-button a un score égal à 1, alors que les autres ont zéro. Le navigateur appliquera l’ensemble de règles de  #submit-button  pour la couleur de fond.

Mais alors, que se passerait-il si on ajoutait une deuxième classe au sélecteur bouton ?

HTML & CSS
<style>
.button.submit-button { background-color: #DB464B; }
</style>
<div class="button submit-button">Click Here!</div>

Cela modifierait sa spécificité, qui deviendrait :

Inline

ID

Class

Element

0

0

2

0

Bien qu’il pourrait sembler que le nouveau sélecteur à double classe  .button.submit-button soit plus spécifique, il n’est toujours pas au niveau de  #submit-button. Souvenez-vous, le navigateur travaille de gauche à droite, et puisque  #submit-button  a un score plus élevé dans la colonne ID, le navigateur n’ira pas plus loin. Peu importe qu’un sélecteur ait deux classes ou 200, un sélecteur id sera toujours plus spécifique qu’une classe.

Un résumé s’il vous plaît ! C’est trop long ! 😱 

Si vous ajoutiez un espace entre les classes dans le CSS, le sélecteur jouerait le rôle d’un combinateur descendant. Cela voudrait dire que l’ensemble de règles ne s’appliquerait qu’aux éléments auxquels a été assignée la deuxième classe, qui seraient les enfants d’un élément auquel a été assigné la première classe. Puisque nous essayons de créer un sélecteur pour un div qui contient les deux sélecteurs, nous devons faire attention qu’il n’y ait pas d’espaces. 😎

Et si on veut vraiment utiliser la couleur de la classe  .submit-button ?

Au lieu d’une deuxième classe, vous pourriez aussi y ajouter l’id :

HTML & CSS
<style>
#submit-button {background-color: #15DEA5;}
#submit-button.button { background-color: #DB464B;}
</style>
<div id="submit-button" class="button">
Click Here!
</div>

Ce qui vous donne :

#submit-button {...}  

Inline

ID 

Class

Element

0

1

0

0

#submit-button.button {...} 

Inline

ID

Class

Element

0

1

1

0

Maintenant il y a égalité dans la colonne ID, le navigateur passe donc à la colonne classe, où  .button  l’emporte 1-0. Le navigateur applique donc sa couleur de fond au bouton.

Les id sont difficiles à outrepasser puisqu’ils ont une spécificité plus importante. Sauf que vous voulez écrire du code propre et maintenable, alors comment faire ? Eh bien, en vous focalisant principalement sur les sélecteurs de classe, vous ferez en sorte qu’ils aient une spécificité plus basse, ce qui les rendra plus aisés à contourner proprement.

Comme vous allez le voir dans le prochain chapitre, vous aurez souvent besoin d’outrepasser certains attributs à l’aide d’un autre sélecteur, plutôt que d’écrire une longue liste de sélecteurs spécifiques. Cela contribuera à rendre votre code plus modulaire et réutilisable.

Du coup, que se passe-t-il si le navigateur passe en revue toutes les colonnes et arrive à un match nul ?

Battle royale : la spécificité en cas d’égalité

Changez l’id #submit-button par la classe .submit et le CSS comme suit : 👇🏼

HTML & CSS
<style>
.submit {background-color: #15DEA5;}
.button { background-color: #DB464B;}
</style>
<div class="button submit">
Cliquez ici!
</div>

.submit  et  .button  ont tous deux le même score.

.button {...} 

Inline

ID

Class

Element

0

0

1

0

.submit {...}  

Inline

ID

Class

Element

0

0

1

0

Alors, quel sélecteur l’emporte ?

En cas d’égalité, le navigateur sélectionne le dernier sélecteur à avoir été déclaré, dans notre cas   .button 

Image représentant un bouton cliquez ici rouge
La couleur Rouge l'emporte

 .button  l’emporte sur  .submit, car il est le dernier à avoir été déclaré.

Donc, si vous les échangez pour que  .submit  soit déclaré en dernier :

<style>
.button { background-color: #DB464B;}
.submit {background-color: #15DEA5;}
</style>
<div class="button submit">
Cliquez ici !
</div>

le navigateur utilisera la couleur de fond de  .submit  :

Image représentant un bouton cliquez ici vert
La couleur Vert l'emporte

Maintenant que .submit  est déclaré en dernier, c’est sa couleur de fond qui apparaît.

En vous restreignant aux classes pour créer vos sélecteurs CSS, vous ferez en sorte qu’ils aient une spécificité basse mais constante. Cela rend les règles contradictoires plus faciles à prévoir et surtout à gérer !

Essayez par vous-même !

Pratiquez en analysant la spécificité entre deux sélecteurs de classe avec deux boutons et leur couleurs. 👌

Coding application
Houston... ?
It seems you're not connected to the internet.
You are not signed in

Sign in to access coding exercises and test your new skills.

Make sure to practice in this chapter before moving on.

Adoptez de bonnes pratiques

Vous avez vu ce que sont le principe DRY et la spécificité. Mais existe-t-il des règles à suivre ? 🤔

Il n’existe pas de règles absolues pour créer l’architecture de votre CSS, seulement des recommandations très variées... Une rapide recherche Google vous livrera des flopées d’articles medium.com sur le sujet. Certains sont d’accord avec l’idée que chaque développeur fait comme il l’entend, d’autres vous diront que non, il faut suivre une nomenclature commune, tandis que d’autres encore émettent certaines réserves sur quelques principes. Au sein de toute cette bataille de “c’est moi qui ai raison !!!", j’ai choisi de vous présenter des solutions pratiques. Les méthodes présentées dans ce cours sont des pratiques testées et largement adoptées par les développeurs. Ces bases vous seront d’un grand secours pour créer une codebase CSS maintenable et propre et ce, pour des projets de n’importe quelle taille.

La notion la plus importante lorsqu’on veut bâtir un code front-end robuste et maintenable est de s’asseoir, établir un plan et s’y tenir coûte que coûte. Au lieu de replonger la tête la première dans votre code existant comme nous l’avons fait dans l’exemple ci-dessus et vous lancer dans des modifications à la volée, vous devez réfléchir et anticiper la façon de structurer votre code, avant d’écrire la moindre première ligne de code. C’est très important, et cela vous fera gagner du temps par la suite.

En résumé

  • Lorsque vous codez, pensez à adopter le DRY : ne vous répétez pas !

  • Lorsque vous créez des sélecteurs, faites attention à ne pas y entasser trop de règles. Séparer les sélecteurs par leur fonction vous aidera à garder votre code compréhensible et maintenable.

  • La spécificité permet de mesurer le poids d’un sélecteur au sein du HTML parmi les autres.

  • Il existe quatre niveaux de spécificité : 

    • les feuilles de style locales (inline styles) ;

    • les id ;

    • les classes, pseudoclasses et attributs ;

    • les éléments et pseudoéléments.

  • Votre navigateur applique les éléments les plus spécifiques en premier.

  • Le CSS n’a pas de structure rigide, ce qui complique la tâche pour avoir une codebase propre et maintenable.

  • En créant et en appliquant votre propre structure, vous pouvez mettre de l’ordre dans un CSS brouillon...

Dans le chapitre suivant, vous irez plus loin en mettant en application vos nouvelles connaissances en matière de spécificité et de structure, en créant des sélecteurs modulables et structurés pour la mise en forme de votre site.

Example of certificate of achievement
Example of certificate of achievement