Le langage SASS permet de créer des feuilles de style CSS. On va voir ce qu'il apporte de plus que le langage CSS classique et voir comment l'intégrer à notre projet pour améliorer et faciliter le développement du style CSS.

Regarder la vidéo sur YouTube

Cet article est la 5e partie d'une série qui explique comment réaliser un site Internet de A à Z. Vous n'avez pas besoin d'avoir lu ou vu les parties précédentes pour comprendre cette partie. Les autres épisodes sont disponibles ici.

Si vous ne pouvez pas regarder la vidéo, un compte rendu est proposé plus bas.

Résumé de la vidéo

Le langage HTML et CSS sont les seuls langages standardisés et reconnus par les navigateurs. Nous n'avons donc pas d'autre choix que de les utiliser pour créer nos pages Web.

Si on choisit de développer nos pages dans un autre langage, comme SASS, nous devons donc convertir notre code dans un langage standisé, comme CSS, avant de le publier et de l'envoyer à nos utilisateurs.

Si on décide d'utiliser un langage non standardisé et s'imposer une conversion, c'est parce que le langage SASS apporte des fonctionnalités qui permettent de créer nos pages plus facilement et de les maintenir plus facilement.

Je vais vous présenter trois fonctionnalités de SASS qui sont, à mon sens, les plus importantes et qui justifie l'utilisation de SASS par rapport au CSS.

Le langage SASS offre la possibilité :

  • D'inclure le contenu d'une feuille de style dans une autre feuille, comme ce que propose d'autres langages de programmation, comme PHP avec la fonction include. La fonction s'appelle import et permet de fusionner plusieurs feuilles de style.
  • De créer des règles CSS @media plus facilement, en incluant par exemple les règles spécifiques aux mobiles dans la même déclaration.
  • D'hériter les valeurs d'une classe, c'est-à-dire réutiliser facilement le contenu d'une classe dans une autre classe, comme on peut le faire dans la programmation orientée objet.

SASS a aussi deux inconvénients majeurs :

  • Il faut apprendre un nouveau langage. L'apprentissage est cependant facilité par le fait que SASS utilise des concepts repris d'autres langages de programmation, et par le fait que l'ensemble des fonctionnalités de CSS sont fonctionnelles dans SASS ;
  • Il faut compiler le code SASS en CSS (le fait de passer de transformer du code d'un langage à un autre peut aussi s'appeler transpiler).

On va installer un compilateur et réaliser quelques exemples pour illustrer les fonctionnalités qu'on vient d'évoquer, et apprendre à utiliser le langage.

Installer le compilateur SASS vers CSS

On peut utiliser l'environnement Node.js pour transformer notre code SASS en CSS.

Node.js permet d'exécuter des programmes JavaScript à l'instar de ce que font les navigateurs. Il dispose aussi d'un gestionnaire de paquets appelé npm, qui permet de télécharger et d'utiliser facilement des programmes que la communauté de développeurs réalisent et publient sur Internet.

En utilisant npm, on peut importer le compilateur dart-sass, qui permet de transpiler notre code SASS en CSS.

Il y a deux façons d'installer un paquet :

  • De façon globale npm install -g sass : pour pouvoir l'utiliser en tant que commande depuis le terminal.
  • De façon spécifique npm install sass : pour l'installer dans un projet précis.

Lorsqu'on l'installe de façon globale, on peut utiliser la commande sass file.scss pour compiler un fichier SASS et afficher le résultat à l'écran.

Lorsqu'on l'installe dans un projet spéficique, on peut importer le paquet (require('sass')) dans notre code Node.js et l'utiliser.

Avant de pouvoir installer ce paquet, nous devons cependant initialiser un projet : npm init -y. Cela a pour conséquence de créer un fichier package.json qui contient des informations comme le nom de votre projet et le nom et versions des paquets installés dans le projet.

Lorsqu'on installe un paquet dans un projet, un dossier nommé node_modules est créé dans le reportoire. Il contient le code source des paquets installés.

On peut utiliser le compilateur que l'on vient installer pour illustrer les fonctionnalités présentées en introduction.

Importer une feuille dans une autre en SASS

Le langage SASS permet d'inclure le contenu d'une feuille de style dans une autre en utilisant: import '/chemin/vers/feuille-sass.scss';

Cette fonctionnalité permet de fusionner plusieurs feuilles de style, et ainsi optimiser le chargement de la page.

La page que nous avons créée dans les épisodes précédents comporte, par exemple, cinq feuilles de style : Une pour réinitialiser les styles par défaut des navigateurs reset.css, une feuille de style générale style.css, une qui contient les styles de la page d'accueil home.css, une qui contient les styles du flux de posts timeline.css et enfin une qui contient les styles de notre pied de page footer.css.

<link rel="stylesheet" href="styles/reset.css">
<link rel="stylesheet" href="styles/style.css">
<link rel="stylesheet" href="styles/home.css">
<link rel="stylesheet" href="styles/timeline.css">
<link rel="stylesheet" href="styles/footer.css">

On peut créer une feuille de style unique global.css et faire en sorte qu'elle contienne toutes les autres. Cela permettra d'optimiser le chargement de la page, car l'utilisateur n'aura plus qu'une seule feuille de style à télécharger plutôt que cinq.

Notre document HTML contiendra ainsi une référence unique :

<link rel="stylesheet" href="styles/global.css">

Cette feuille global.css peut être générée à partir d'un fichier global.scss qui contiendra toutes les autres feuilles de style :

@import 'styles/reset.scss';
@import 'styles/style.scss';
@import 'styles/home.scss';
@import 'styles/timeline.scss';
@import 'styles/footer.scss';

À noter aussi que l'extension des fichiers est désormais .scss pour pouvoir faire la distinction plus facilement entre un fichier CSS et un fichier SASS. Les documents CSS peuvent être transformés en SCSS/SASS sans modification du code, car le langage SASS comprend toutes les fonctionnalités de CSS.

La feuille global.scss que l'on vient de créer peut ensuite être compilé (sass global.scss global.css) et transformé en une feuille de style CSS classique, qui contiendra le contenu de tous les fichiers importés, et qui sera envoyé aux utilisateurs.

Cela nous donne la liberté de pouvoir organiser notre code CSS comme on le souhaite, en autant de documents que l'on souhaite, sans que le chargement de la page ne soit impacté.

Créer des règles CSS media en SASS

En CSS, créer des règles responsives, c'est-à-dire spécifiques à un @media particulié (comme des petits écrans), est un peu laborieux.

On a le choix entre deux approches : lister les déclarations classiques d'abord, puis celles spécifiques à un media ensuite, ou définir les règles spécifiques aux médias juste après la règle classique.

Dans le premier cas, on se trouve avec un fichier qui ressemble à ça :

.class1 {
  /* règles CSS pour écran larges */
}

.class2 {
  /* règles CSS pour écran larges */
}

/* ... plein d'autres classes pour écrans larges */

@media screen and (max-width: 700px) {
  .class1 {
    /* règles CSS pour écrans mobiles */
  }
  
  .class2 {
    /* règles CSS pour écrans mobiles */
  }
}

Ce qui rend la tâche compliquée pour le développeur, c'est que le contenu des classes est situé dans deux endroits différents. Il faut donc faire des va-et-vient entre ces deux blocs chaque fois que l'on souhaite apporter une modification à une classe.

On pourrait rapprocher le contenu responsive de la classe du contenu standard :

.class1 {
  /* règles CSS pour écran larges */
}

@media screen and (max-width: 700px) {
  .class1 {
    /* règles CSS pour écrans mobiles */
  }
}

.class2 {
  /* règles CSS pour écran larges */
}

@media screen and (max-width: 700px) {
  .class2 {
    /* règles CSS pour écrans mobiles */
  }
}

/* ... plein d'autres classes pour écrans larges */

Cette solution demande cependant de recopier pour chaque classe la même déclaration @media, ce qui rend le fichier CSS très long, et peu lisible.

Le langage SASS propose une solution alternative en utilisant des @mixin, c'est-à-dire une fonction qui répète facilement une partie de code :

@mixin mobile {
  @media screen and (max-width: 700px) { @content; }
}

En déclarant au préalable ce mixin, que l'on a nommé mobile, et qui reprend notre déclaration @media précédente, on peut ensuite facilement déclarer une classe qui comporte des règles classiques et des règles CSS responsives :

.class1 {
  /* règles CSS pour écran larges */

  @include mobile {
    /* règles CSS pour écrans mobiles */
  }
}

.class2 {
  /* règles CSS pour écran larges */

  @include mobile {
    /* règles CSS pour écrans mobiles */
  }
}

Une fois compilé, ce code SASS est transformé en un code CSS utilisant des @media classique, similaire au code CSS que l'on aurait créé manuellement.

Hériter des valeurs en SASS

En CSS, plusieurs classes peuvent partager les mêmes règles CSS. Dans cet exemple, trois classes class1, class2 et class2 partagent les deux mêmes règles, et en plus, chaque classe possède une caractéristique supplémentaire :

.class1,
.class2,
.class3 {
  max-width: 800px;
  margin: 0 auto;
}

.class1 {
  margin: 1em;
}

.class2 {
  color: red;
}

.class3 {
  padding: 1em;
}

Le problème est similaire à celui des règles responsives précédentes, c'est-à-dire que le contenu d'une classe est situé à deux endroits dans le code : dans les règles communes, et dans la règle spécifique.

Le langage SASS permet d'écrire un code similaire en utilisant la fonctionnalité @extend :

.text {
  max-width: 800px;
  margin: 0 auto;
}

.class1 {
  @extend .text;

  margin: 1em;
}

.class2 {
  @extend .text;

  color: red;
}

.class3 {
  @extend .text;

  padding: 1em;
}

On peut désormais consulter l'ensemble du contenu d'une classe dans un même endroit, sans devoir chercher plus loin dans la feuille de style si d'autres propriétés sont définies, et une fois compilé, notre code ressemblerait à celui qu'on aurait écrit manuellement si on avait utilisé du CSS classique.

Compiler le code SASS

Pour compiler le code SASS et obtenir du CSS, on peut utiliser le compilateur à partir de la ligne de commande (sass entree.scss sortie.css), ou créer un programme JavaScript sous Node.js en important le compilateur (require('sass')).

Un exemple de programme serait par exemple :

'use strict'

const sass = require('sass')

const { writeFile } = require('fs')

const creerFichier = async(chemin, contenu) =>
  new Promise((resolve, reject) => {
    writeFile(chemin, contenu, { encoding: 'utf8' }, err => {
      if (err) {
        reject(err)
        return
      }

      resolve()
    })
  })

const compilerSASS = chemin =>
  new Promise((resolve, reject) =>
    sass.render({ file: chemin }, (err, result) => {
      if (err) {
        reject(err)
        return
      }

      resolve(result.css.toString())
    }))

;(async() => {
  const css = await compilerSASS('c:\\dev\\styles\\global.scss')
  await creerFichier('c:\\dev\\styles\\global.css', css)
  console.log('Compilation réussie!!')
})()

Note: Le prochain épisode est disponible ici et le précédent ici.