default-background
29 mars 2013

Pourquoi Sass et Compass

Damian Le Nouaille est développeur Freelance (Frontend et Ruby). Actuellement, il travaille sur Mayathebuzz et essaie d’utiliser les meilleures pratiques frontend pour rendre son métier plus agréable. Il propose également une formation Sass et Compass pour Human Coders Formations. Vous pouvez le suivre sur Twitter (@damln) et en savoir plus sur son site http://www.damln.com.

Après avoir compris qu’un préprocesseur fait parti des outils indispensables d’un développeur frontend, voyons pourquoi Sass et Compass sont des choix judicieux.

Séparation des responsabilités

On me demande souvent quelle est la différence entre Sass et Compass. La réponse est simple, je voudrais commencer par ça :

  • Sass est un langage. C’est dans Sass que la syntaxe est interprétée, puis compilée. Sass fournit les variables, les mixins, les fonctions et toute l’API basique permettant de coder. Sass est le préprocesseur, au même titre que Less.
  • Compass est un framework, pour Sass. Par défaut, Sass ne fournit aucune aide cross-browser comme les vendor-prefix, ou les aides à la compatibilité sur les float. C’est Compass qui s’en charge. Sass et Compass sont deux projets distincts qui évoluent à leur rythme. Compass est juste un ensemble de mixins réutilisables dans vos projets. Pour éviter d’écrire votre mixin border-radius dans chaque projet, @import "compass"; dans vos fichiers .scss et paf ! Vous y avez accès.

Avoir un projet dédié au langage et un autre dédié au framework est signe de stabilité et de flexibilité. Ça en dit long sur l’état d’esprit des créateurs de Sass. Si les mixins Compass ne vous suffisent pas, écrivez les vôtres.

Sass est à Compass ce que Ruby est à Ruby On Rails, le moteur.

Installation

Concrètement, il suffit d’avoir Ruby pour utiliser Sass et Compass. Après avoir installé Ruby (UNIX ou Windows), ouvrez votre terminal, et tapez :

gem install compass

C’est plutôt simple. Vous avez maintenant accès à l’exécutable compass pour compiler vos *.scss et “watcher” vos répertoires.

Ou vous pouvez utiliser des applications desktop comme :

Migration

Sass a deux syntaxes : la nouvelle (SCSS) et “l’ancienne” (SASS). Concrètement, les deux sont interchangeables à tout moment, mais SCSS est compatible CSS. Vous pouvez renommer vos *.css actuels en *.scss, lancer la compilation, et vous n’aurez aucune erreur. La syntaxe SCSS est 100% compatible avec CSS. Vous pouvez dès aujourd’hui utiliser Sass pour refactorer votre code existant, sans réécriture complète.
Vous en avez marre de Sass ? Ok, supprimez vos fichiers *.scss et utilisez maintenant les *.css générés à la compilation.

Sass ne viendra pas désorganiser votre travail. À aucun moment non plus vous serez “bloqué” par Sass, car si quelque chose ne vous va pas, récupérez les fichiers générés et utilisez un autre outil. La priorité dans un outil, c’est sa capacité à s’ajouter et s’enlever d’un projet sans effet irréversible. Sass et Compass rentrent dans cette catégorie.

Organisation

La puissance des @import Sass vous permettra de créer plusieurs fichiers (modules) qui contiendront des déclarations spécifiques à un problème. Fini les fichiers CSS de 4 000 lignes avec des grands bandeaux de commentaires :

    //=============== [ BUTTONS ]================
    //===========================================

    //=============== [ LAYOUT ]=================
    //===========================================

Les scrolls infinis pour savoir où est notre module : c’est du passé.
Organisez vos styles en fichiers, par exemple:

/_config.scss
/_shared.scss
/_buttons.scss
/_forms.scss
/main.scss

et main.scss contiendra :

@import "config";
@import "shared";
@import "buttons";
@import "forms";

Les underscore _ devant les fichiers Sass sont une convention Sass pour faire en sorte de ne pas compiler ces fichiers en .css, mais uniquement les rendre accessibles par des @import.

Lisibilité et Compréhension

Votre refactor se traduira par la suppression de beaucoup de code, pour le remplacer par des mixins, des fonctions, et par l’utilisation de variables. Ce qui allègera votre CSS actuel et aura pour effet une meilleure compréhension et lisibilité du code. Par exemple, l’utilisation des mixins Compass CSS3 est simple :

@import "compass/css3";

.btn {
    @include border-radius(10px);
}

Sans Compass:

.btn {
    border-radius: 10px 10px 10px 10px;
    -moz-border-radius: 10px 10px 10px 10px;
    -webkit-border-radius: 10px 10px 10px 10px;
}

3 lignes remplacées par une seule, ce résultat multiplié par le nombre de déclarations border-radius. Ça fait du bien aux yeux, et ça nous permet de rester concentré sur la big picture de .btn, pas les détails d’implémentation. Je crois que là aussi, c’est une question d’expérience. Un développeur essaie de factoriser du code, pour comprendre les grands enjeux du programme : les classes, les méthodes et les dépendances. Pour comprendre et maintenir un programme, il faut que les interfaces soient les plus claires possible. Utiliser Compass pour générer du code, c’est une forme de factorisation naturelle. Elle nous dégage de l’implémentation. Nous savons très bien que derrière, Compass va produire les vendor-prefix. C’est un détail d’implémentation, pas un enjeu majeur dans vos styles.

Réutilisabilité

Grâce aux variables, mixins, fonctions, import, et autres outils de Sass, vous apprendrez à découpler les responsabilités dans vos styles. Cela permettra une meilleure réutilisabilité tout au long de vos projets.

De plus, n’oubliez pas de bien lire la documentation Compass pour utiliser ce qui existe déjà. Enfin du ~~Canada~~ DRY dans vos CSS.

Bonus

Optimisation

Aujourd’hui, vos styles sont susceptibles d’être utilisés dans des mobiles, tablettes et autres appareils. La bande passante et la qualité de vos assets (CSS, JavaScript, et images) sont une priorité. Sass et Compass permettent de faire quatre choses importantes :

  • De vrais @import : la capacité à utiliser @import mais de manière “brute”. C’est-à-dire une inclusion des fichiers, pas le @import CSS standard qui fera une requête supplémentaire pour chercher la feuille de style (déconseillé). Dans Sass, @import est interprété à la compilation, le résultat est un seul fichier concaténé.
  • Compression : Sass permet de compresser le résultat de la compilation avec une méthode de minification. C’est à dire supprimer les espaces dans tout le fichier pour gagner quelques octets sur le résultat final. Ainsi, le développeur travaille avec des fichiers .scss propres (bien nommés, bien indentés, etc…) et compile tout dans un fichier distribuable : concaténé + minifié.
  • Sprites : Sass est en Ruby, Ruby permet de faire plein de choses. Compass intègre un système pour autogénérer un sprite à partir de plusieurs images. Je n’expliquerai pas cette technique en détails, vous comprendrez rapidement l’importance d’une telle optimisation. L’usage est expliqué ici.

Un exemple simple :

@import "my-icons/*.png";

.actions {
    .new    { @include my-icons-sprite(new);    }
    .edit   { @include my-icons-sprite(edit);   }
    .save   { @include my-icons-sprite(save);   }
    .delete { @include my-icons-sprite(delete); }
}

Compass va prendre les toutes les images de votre dossier my-icons/, utiliser Ruby pour générer une seule image (une seule requête HTTP) puis générer le style correspondant. Vous remarquerez que Sass utilise la convention de nom pour les mixins. Encore un héritage de Ruby (et Ruby On Rails) qui fait du bien : @include MON-DOSSIER-sprite(NOM_IMAGE);

Sortie du compilateur pour le code précédent :

.my-icons-sprite, .actions .new, .actions .edit, .actions .save, .actions .delete { 
    background: url('/images/my-icons-sda4fcee85a.png') no-repeat; 
}

.actions .new { background-position: 0 -62px; }

.actions .edit { background-position: 0 -31px; }

.actions .save { background-position: 0 -93px; }

.actions .delete { background-position: 0 0; }
  • Images en base64 : Il est aussi possible de convertir une image en base64. Quel intérêt ? Au lieu de faire une mini requête vers votre backgound.png (de 1ko) qui sera en repeat, autant inclure directement sa représentation base64 dans le CSS. De même que sprite, je vous laisse comprendre l’intérêt de cette fonction puissante. Exemple et documentation

Code Sass :

body {
    background: inline-image("background.gif") repeat;
}

Résultat CSS :

body {
    background: url('data:image/gif;base64,R0lGODlhAQBQAIAAANxROMhGMSwAAAAAAQBQAAACCoSPqcvtD4KcdBYAOw==') repeat;
}

Compatibilité

Compass intègre un très grand nombre de fonctions et de mixins. Des développeurs plus expérimentés que nous ont déjà résolu les problèmes de compatibilités navigateurs sur divers points. Typographie, float, box modèle, et autres. Grâce à Compass, vous n’avez plus à vous occuper de cela. Attention, aucune magie, tous les navigateurs ont leurs défauts, mais utiliser des mixins existantes permet de gagner un temps fou.

Lorsqu’on étudie le code source de Compass, on remarque des constantes dans le code qui nous permettent d’adapter au mieux notre niveau de compatibilité. Voilà celles qui m’intéressent:

// Usually compass hacks apply to both ie6 & 7 -- set this to false to disable support for both.
$legacy-support-for-ie: true !default;

// Setting this to false will result in smaller output, but no support for ie6 hacks
$legacy-support-for-ie6: $legacy-support-for-ie !default;

// Setting this to false will result in smaller output, but no support for ie7 hacks
$legacy-support-for-ie7: $legacy-support-for-ie !default;

// Setting this to false will result in smaller output, but no support for legacy ie8 hacks
$legacy-support-for-ie8: $legacy-support-for-ie !default;

Ainsi, chaque mixin peut se baser sur ces constantes pour générer ou pas du code compatible IE6, 7 ou 8. Compass est très bien pensé, je n’ai vu ça nul par ailleurs (dans d’autres préprocesseurs).

Centralisation

Compass permet enfin d’avoir un dépôt central qui contient toutes les meilleures pratiques du CSS. Des années d’expérience condensées dans des mixins claires. Fini les codes redondants, non organisés, pour combler des problèmes navigateurs.

Compass est accessible sur Github évidemment, je regarde souvent le code source directement. Il est très lisible et permet de bien comprendre les mixins.

Cette approche nous encourage à résoudre des problèmes communs. J’ajouterai que l’apparition d’une multitude de framework CSS n’est pas forcément la “bonne guerre”. Choisir un framework CSS à plus d’impact sur votre projet que le choix du préprocesseur. Utiliser Compass permet soit de créer notre framework interne plus rapidement, soit d’utiliser des fragments de framework existant (comme un portage Sass de Bootstrap) dans nos projets.

Server-side

Sass et Compass sont construits sur la ligne de commande. C’est-à-dire qu’il faut lancer une commande pour compiler des fichiers Sass en CSS. C’est une bonne pratique, très simple à scripter ou à adapter. Mais surtout, celà vous force à être proche de votre environnement de production. Il faut que l’impact de l’utilisation d’un préprocesseur soit transparente pour le navigateur. Par exemple, Less encourage l’usage de less.js directement dans le navigateur. Mettre en avant le côté “client-side et server-side” de Less est une erreur magistrale de la part de la communauté Less. Un préprocesseur doit travailler server-side uniquement. Et encore, dans le cas d’un préprocesseur CSS, il travaille “développeur-side” : en phase de développement.

Modularité

Compass est basé sur un système de plugins permettant à la fois de choisir quelle “partie” de Compass nous souhaitons utiliser, mais aussi de créer nous-mêmes nos extensions Compass, les distribuer, et les réutiliser.

Pour n’utiliser que les mixins CSS3 de Compass:

@import "compass/css3";

Pour utiliser un plugin externe :

@import "monplugin";

Ecosystème

Les outils pour utiliser Sass et Compass sont stables et production-ready. Pour ma part, j’utilise exclusivement la ligne de commande, avec le plugin grunt-contrib-compass (et grunt.js). Mais pour les personnes rétissentes, n’hésitez pas à utiliser les applications desktops citées plus haut.

L’écosystème autour de Sass grandit de jour en jour. Par exemple, Addy Osmani a présenté le “source map” intégré dans Chrome Canary. C’est un outil permettant de débugger vos sources *.scss directement dans Chrome. Lorsqu’une telle avancée est faite au coeur de Chrome, on peut se dire que l’écosystème devient mature.

Pourquoi pas Less ?

La plupart des arguments ci-dessus fonctionnent aussi bien pour Less. Mais je trouve l’écosystème Less moins avancé, notamment la partie framework et centralisation. A-t-on besoin de préprocesseur compliqué ? Certainement pas, Sass et Less sont très, très proches. Si vous regardez un comparatif rapide (slides) vous verrez qu’il y a très peu de différences. Cependant, l’approche client-side et server-side de Less est une erreur non négociable. Less fournit less.js, qui permet de compiler directement du Less dans le navigateur. Il va sans dire l’impact sur les performances d’un tel usage. En reprenant des termes très précis (que j’approuve complètement):

“La qualité d’une intégration se mesure sur trois objectifs (dans l’ordre) : l’internaute, le projet et moi.”

A cause de less.js, c’est directement l’internaute qui est sanctionné.

PS :
Less est aussi utilisable server-side avec NodeJS. Cette méthode devrait être mis en avant, et obligatoire. Less.js doit disparaître au plus vite.

Le mot de la fin

Cet article n’avait pas pour but d’expliquer en profondeur le fonctionnement de Sass ou de montrer des exemples de codes très longs. Cependant, j’ai essayé d’être clair sur les enjeux d’un tel choix et sur les motivations qui m’ont poussé à migrer vers Sass et Compass il y a maintenant deux ans. Je ne regrette toujours pas mon choix. N’hésitez pas à partager vos expériences et vos retours.

Cet article vous a donné envie d’apprendre Sass ? La formation Sass et Compass de Damian est faite pour vous !


Liens ces dernières semaines :