Sass VS LESS : quel est le meilleur préprocesseur CSS ?

On ne va pas se voiler la face, le CSS, c’est super chiant.
Je ne saurais pas dire ce qui est le pire avec ce langage. Je suis partagé entre :

  • La syntaxe beaucoup trop simple qui pousse inévitablement à écrire du code bordélique.
  • Le résultat qui n’est jamais celui auquel on s’attend (notamment ces */-_”# d’alignements)
  • Le manque cruel de fonctionnalités pourtant évidentes, comme les variables ou l’héritage.
  • Le débuggage absolument infernal à partir du moment où des règles commencent à s’entrecroiser (c’est-à-dire tout le temps).
Ce mug a tout dit.

Tous ces problèmes étaient des détails à l’époque du web 2.0, quand les pages ne contenaient que très peu de mise en forme. Vous savez, l’époque de Flash, d’ActiveX et des Applets Java (j’en ai des frissons…).

Mais aujourd’hui, ce sont des (dizaines de) milliers de lignes de CSS qui se trouvent derrière les sites web. Et ces “petits problèmes” finissent par générer beaucoup de friction lors des développements, ce qui augmente considérablement la dette technique sur un projet.

Et je ne parle même pas du taux de frustration, toi-même tu connais les vertical-align.

Heureusement, il est possible d’éliminer ces 4 points noirs en utilisant un préprocesseur. Il s’agit d’un outil qui permet de transformer un fichier contenant une syntaxe particulière en un fichier CSS pur, compatible avec tous les navigateurs.

L’intérêt est bien sûr de pouvoir programmer dans un langage plus avancé que le CSS afin de gagner en temps, en qualité et en productivité. C’est tout bénef !


Dans un précédent article, j’avais parlé du préprocesseur CSS le plus connu : Sass. J’avais expliqué le principe, ce qu’il apportait à l’expérience CSS, ses fonctionnalités et comment l’installer. Je vous invite grandement à aller lire l’article si vous ne connaissez pas encore l’univers des préprocesseurs CSS.

Mais Sass est loin d’être le seul du marché, et aujourd’hui, on va le comparer d’égal à égal avec son plus gros concurrent : LESS.

Donc si vous hésitez entre les deux, ou que vous n’en connaissez qu’un seul, cela vous permettra d’avoir l’esprit plus éclairé pour déceler les subtilités, les avantages, les inconvénients et les cas d’utilisation de chacun, et ainsi de pouvoir faire votre noble choix.

Et si vous ne connaissez pas du tout LESS et que vous voulez l’apprendre en moins de 10m montre en main, je vous ai mis un tutoriel rapide dans le bonus de cet article.


Points communs

Déjà, l’installation et l’utilisation sont les mêmes pour les deux.

  1. Installer un paquet avec NPM : sass pour Sass, less pour LESS (ça va, vous suivez ? 😊).
  2. Lancer une commande qui prends en paramètre le fichier d’entrée (code source) et le fichier de sortie (résultat en CSS).
sass style.scss style.css
lessc style.less style.less

De plus, les deux sont utilisables directement aux travers d’environnements d’exécution comme NodeJS.

Concernant les fonctionnalités des langages, le principe d’encapsulation des règles, qui permet de simplifier et mieux organiser le code, est exactement le même, absolument aucune différence.

// Encapsulation
.baguette {
    width: 475px;
    background-color: #8B4A0F;

    .croute {
        font-weight: 800;
    }

    .farine {
        color: #f0f0f0;
    }

    &:hover {
        background-color: #75230F;
    }
}
.baguette {
    width: 475px;
    background-color: #8B4A0F;
}
.baguette .croute {
    font-weight: 800;
}
.baguette .farine {
    color: #f0f0f0; 
}
.baguette:hover {
    background-color: #75230F;
}

Les commentaires aussi sont conservés, notamment le fameux // totalement absent en CSS, mais bien réel chez Sass et LESS.

Ensuite, beaucoup de concepts sont similaires entre les deux, avec une syntaxe légèrement différente. C’est le cas pour les variables, ou pour certains mots-clés différents, mais qui font la même chose.

// Modules
@use 'module';

// Variables
$cuisson: #8B4A0F;
$imageFolder: "./img";

.baguette {
    color: $cuisson;
    background-image: url("#{$imageFolder}/cuisson.png");
}
// Modules
@import "module";

// Variables
@cuisson: #8B4A0F;
@imageFolder: "./img";

.baguette {
    color: @cuisson;
    background-image: url("@{image}/cuisson.png");
}
.baguette {
    color: #8B4A0F;
    background-image: url("./img/cuisson.png");
}
Pour ce coup, je me range plutôt du côté de Sass, qui fait l’effort d’avoir deux symboles différents pour ses variables de ses mots-clés.

D’autres grands concepts se retrouvent aussi dans les deux, comme les extensions (héritage) ou les mixins. Cependant, bien que le résultat soit plus ou moins le même, la différence se fait vraiment ressentir à l’utilisation, ce qui me donne une parfaite transition pour passer aux différences.


Différences

La grosse différence qui explique toutes les autres vient en fait de l’état d’esprit derrière ces deux préprocesseurs.

  • Sass utilise des mots-clés partout, et une fonctionnalité = un mot-clé. Donc pour maîtriser totalement Sass, il suffit d’apprendre tous les mots-clés (@use, @mixin, @include, @extends…), et quelques symboles particuliers ($, %…).
  • LESS se repose sur une syntaxe plus naturelle, qui ressemble plus à du CSS et qui essaye d’inclure le moins de mots-clés et de symboles possibles. Et pour les comportements un peu plus spécifiques, cela se passe en dehors du fichier de style, ce qui épure grandement la syntaxe.

Extensions et mixin

Cette différence se voit notamment avec les extensions, ou Sass introduit un mot-clé tandis que LESS utilise une syntaxe similaire à celle des pseudo-classes en CSS pur.

// Extensions
.nourriture {
    display: block;
}

.pain {
    @extend .nourriture;
    font-weight: 800;
    text-decoration: wavy;
}

.baguette {
    @extend .pain;
    background-color: #8B4A0F;
    width: 475px;
}
// Extensions
.nourriture {
    display: block;
}

.pain:extend(.nourriture) {
    font-weight: 800;
    text-decoration: wavy;
}

.baguette:extend(.pain) {
    background-color: #8B4A0F;
    width: 475px;
}
.nourriture, .pain, .baguette {
    display: block;
}
  
.pain, .baguette {
    font-weight: 800;
    text-decoration: wavy;
}
  
.baguette {
    background-color: #8B4A0F;
    width: 475px;
}

On retrouve aussi cette différence avec les mixin : des blocs de propriétés réutilisables à plusieurs endroits.

Deux mots-clés pour Sass alors que LESS altère légèrement la syntaxe du CSS pour arriver au même résultat.

// Mixin
@mixin presentation-vitrine($taille) {
    margin: auto;
    padding-left: $taille; 
    padding-right: $taille; 
    padding-bottom: $taille * 2; 
    padding-top: $taille * 0.5; 
}

.baguette {
    @include presentation-vitrine(10px);
    background-color: #8B4A0F;
    width: 475px;
}
// Mixin
.presentation-vitrine(@taille) {
    margin: auto;
    padding-left: @taille; 
    padding-right: @taille; 
    padding-bottom: @taille * 2; 
    padding-top: @taille * 0.5; 
}

.baguette {
    .presentation-vitrine(10px);
    background-color: #8B4A0F;
    width: 475px;
}
.baguette {
    margin: auto;
    padding-left: 10px;
    padding-right: 10px;
    padding-bottom: 20px;
    padding-top: 5px;
    background-color: #8B4A0F;
    width: 475px;
}

Petite note sympathique, c’est que LESS considère toutes ses règles comme étant des mixin, ce qui permet de faire des choses comme ça :

.pain {
    font-weight: 800;
    text-decoration: wavy;
}

.baguette {
    .pain();
    background-color: #8B4A0F;
    width: 475px;
}
.pain {
    font-weight: 800;
    text-decoration: wavy;
}
.baguette {
    font-weight: 800;
    text-decoration: wavy;
    background-color: #8B4A0F;
    width: 475px;
}
Notez qu'il ne s'agit pas d'une extension.

Il permet aussi de passer toutes les propriétés d’un mixin en !important, ce qui n’est tout simplement pas possible avec Sass sans utiliser 2 mixins différents. Très pratique !

.pain {
    font-weight: 800;
    text-decoration: wavy;
}

.baguette {
    .pain() !important;
    background-color: #8B4A0F;
    width: 475px;
}
.pain {
    font-weight: 800;
    text-decoration: wavy;
}
.baguette {
    font-weight: 800 !important;
    text-decoration: wavy !important;
    background-color: #8B4A0F;
    width: 475px;
}
Même si !important, ça reste un peu un truc de flemmard 😛

Fausses règles

Les fausses règles sont définies dans le code source, mais n’apparaissent pas sur le CSS final. Elles permettent essentiellement de pouvoir stocker des propriétés pour pouvoir les utiliser autre part avec des extensions et des mixins.

Pour faire cela, Sass introduit un nouveau symbole (%) pour définir une fausse règle, comme le “.” pour une classe ou le “#” pour un ID.

Alors que LESS recycle son principe de mixin pour faire ses fausses règles. Il ne s’agit ni plus ni moins que des mixins, mais sans paramètres.

// Fausse règle
%nourriture {
    display: block;
}
// Fausse règle
.nourriture() {
    display: block;
}

Variables et maps

Un autre point à accorder à LESS est qu’il possède un système de structures appelées maps.

Le principe est le même qu’en programmation : une variable qui contient plusieurs propriétés qui permet de regrouper les données similaires.

@cuisson: {
    frais: #EDD49E;
    cuit: #8B4A0F;
    brule: #390100
}

.baguette {
    background-color: @cuisson[frais];
}
.baguette {
    background-color: #EDD49E;
}

Il est possible d’en faire sur Sass, mais cela nécessite d’inclure une extension au langage, et la syntaxe donne de sérieuses envies d’évasion à mon 4H.

@use "sass:map";

$cuisson: ("frais": #EDD49E, "cuit": #8B4A0F, "brule": #390100);

.baguette {
    background-color: map.get($cuisson, "frais");
}
Sans déconner, c’est super moche non ?

Pour le coup, je me range du côté de LESS, qui a une syntaxe est bien plus naturelle et similaire à ce que l’on pourrait retrouver dans de la POO.

Fonctions

Sass et LESS possèdent tout deux un système de fonctions logiques et mathématiques assez avancé. Cependant, il y a certains points qui font pencher la balance d’un côté comme de l’autre.

Déjà, LESS possède énormément de fonctions intégrées au préprocesseur, bien plus que Sass. Les développeurs en sont même tellement fiers qu’ils ont fait une section entière de leur documentation juste pour ça, qui passe devant la section dédiée à l’apprentissage de la syntaxe. Ça rigole zéro !

C’est assez pratique pour ne pas avoir à réinventer la roue, surtout quand il s’agit d’algorithmes un peu chiants, notamment tout ce qui touche au traitement des couleurs.

Pour ce qui est de la création de fonctions, Sass intègre son propre langage de programmation, le SassScript. Ça casse pas 14 pattes à un canard, mais c’est simple, propre et fonctionnel.

@function mino($value1, $value2) {
    @if ($value1 < $value2) {
        @return $value1;
    } @else {
        @return $value2;
    }
}

.baguette {
    width: mino(100px, 140px); // 100px
}

LESS, quant à lui, utilise JavaScript pour la création de ses fonctions. Dit comme ça, ça à l’air génial, mais il y a juste un petit problème : ça marche pas bien.

Je ne sais pas exactement ce qui ne tourne pas rond, mais 3/4 de mes algorithmes, mêmes de très simples, ne fonctionnent tout simplement pas. Ils retournent un résultat vide ou faux. Quelques exemples :

// Retoure null
functions.add('mino', function(value1, value2) {
    return Math.min(value1, value2);
});

// Retoure toujours value2
functions.add('mino', function(value1, value2) {
    return value1 < value2 ? value1 : value2;
});

// Idem, retoure toujours value2
functions.add('mino', function(value1, value2) {
    if (value1 < value2)
        return value1;
    else
        return value2;
});

// Fonctionne correctement...
functions.add('mino', function(value1, value2) {
    return value1 <= value2 ? value1 : value2;
});

Je me disais déjà que quelque chose sentait le gaz quand je faisais mes recherches pour cet article, car si vous allez regarder la documentation, leurs exemples sont presque tous des algorithmes ridiculement simples, qui ne font que retourner des constantes…

functions.add('pi', function() {
    return Math.PI;
});

functions.add('foo', function() {
    return "foo";
});
3/4 des exemples sont comme ça. Merci captain obvious !

Franchement LESS, ça mérite un gros 0/20…

Confort

Comme je l’ai dit plus haut, les deux s’utilisent de la même manière. Mais il y a un GROS argument qui rend Sass 1000 fois plus pratique si vous compilez depuis une invite de commande : son watch mode, qui permet de générer le CSS à chaque sauvegarde du code source.

Il est théoriquement possible d’avoir un watch mode avec LESS en introduisant des paquets tiers, mais merde, c’est tellement la base que ça devrait être inclus par défaut. Franchement LESS, faites quelque chose !

CSS Dynamique

Un aspect intéressant des préprocesseurs est que la plupart permettent de faire de la génération dynamique de CSS, c’est-à-dire de sortir des versions différentes d’un fichier CSS grâce au même code source, mais en utilisant des paramètres extérieurs différents, exactement comme une fonction.

Et je dis bien la plupart car sur certains, ce n’est pas vraiment possible sans passer par des moyens compliqués ou détournés. Et malheureusement, c’est le cas de Sass (je mets le lien d’un post sur SO qui explique comment faire, mais on sent bien que ça n’a pas été étudié pour).

LESS, quant à lui, permet de faire ça extrêmement facilement grâce à son principe de variables globales. Voilà ce que ça donne avec NodeJS :

var input = fs.readFileSync(__dirname + '/../private/css/main.less', 'utf8');

var options = {
  modifyVars: {
    'var-name': '#000000'
  }
};


less.render(input, options, function (err, result) {
  // send response to end-user here
});
Voir sur stackoverflow.com

Conclusion

Voilà, j’ai fait le tour des différences entre Sass et LESS. Vous vous doutez bien qu’il y en a des plus subtiles, mais je me suis concentré uniquement sur l’essentiel.

Si vous voulez en apprendre plus sur Sass, je vous renvoie vers l’article que j’ai écrit à ce sujet.

Si vous êtes intéressé pour apprendre LESS en moins de 10m, allez jeter un œil au bonus de cet article.

Et pour conclure le débat Sass VS LESS :

  1. La syntaxe dépend uniquement de vos goûts, et malheureusement, il n’y a pas d’entre deux :
    • Si vous êtes plutôt syntaxe propre et cohérente avec plein de mots-clés, choisissez Sass.
    • Si vous êtes plutôt syntaxe astucieuse, intelligente et proche du CSS, choisissez LESS.
  2. Si votre but est de faire du CSS dynamique, choisissez LESS. Sass n’est tout simplement pas fait pour ça.
  3. Si comme moi, vous utilisez un préprocesseur uniquement pour pouvoir compiler votre CSS à la main, choisissez Sass. Son watch mode est un must à absolument avoir si vous voulez gagner énormément du temps et éviter les oublis (qui arrivent bien trop souvent !).
  4. Si vous voulez des fonctionnalités puissantes, les deux sont kif-kif, mais elles seront plus mises à profit avec LESS vu qu’il est adapté pour faire du CSS dynamique.

Enfin, petit point de détail, mais n’oubliez jamais de vous fier à votre instinct lorsque vous choisissez une technologie.

Que vous préfériez Sass, LESS, PostCSS, le CSS pur ou tout styliser avec du JavaScript (oui, c’est stupide, mais ça existe), le monde du développement est assez grand pour accueillir tout le monde 😉


Voilà pour cet article, en espérant qu’il vous a donné envie de vous intéresser à une de ces deux technologies.

Si ce genre d’article type “confrontation” vous plaît ou que vous avez une quelconque remarque, laissez moi un petit commentaire en dessous pour savoir si j’en fais d’autres dans ce style.

En attendant, je vous laisse, il faut que j’aille nourrir mon tricératops. Je vous donne rendez-vous la semaine prochaine pour un nouvel article où l’on va parler d’un sujet tendance, mais loin d’être inintéressant !


Accéder au bonus : LESS en 10 minutes.