Compass, un framework CSS3

Nous l’avons vu en présentation, Compass est un framework CSS3. Il enrichi l’environnement Sass d’un ensemble de mixins qui suivent la feuille de route de CSS3. Nous retrouvons ainsi plusieurs mixins pour ajouter un border-radius à un élément, ou encore de quoi appliquer aisément une ombre portée via le mixin box-shadow.

Compass (et non Sass) se charge de générer les variantes propres aux différents navigateurs en ajoutant les divers préfixes propriétaires. Au besoin, il adapte la syntaxe de la propriété à la plateforme cible.
Économisez ainsi de nombreuses heures en arrêtant d’écrire au kilomètre une même propriété dans toutes les déclinaisons possibles !

Cerise sur le gâteau, la communauté de Compass étant réactive, si une spécification venait à évoluer — comme cela s’est déjà vu — vous pouvez être certain qu’elle sera répercutée dans le mixin adéquate. Des fallbacks sont généralement maintenus pour les anciens navigateurs le temps que leur taux de pénétration devienne marginale.

Dégradés

Rien ne vaut un exemple pour montrer pourquoi Compass en a séduit plus un.
Dans l’exemple qui suit, nous supportons une majorité de navigateurs dont IE 6 à 9 en seulement 3 lignes, pour en générer 10, dont un SVG pour IE 9. La notion de framework CSS3 commence à prendre son sens, n’est-ce pas ? :-)

.linear-gradient {
  @include filter-gradient(#a9e4f7, #0fb4e7); // IE6-8
  $experimental-support-for-svg: true;
  @include background-image(linear-gradient(#a9e4f7, #0fb4e7));
}

Les 3 lignes précédentes génèrent le CSS qui suit :

.linear-gradient {
  *zoom: 1;
  filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#FFA9E4F7', endColorstr='#FF0FB4E7');
  background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2E5ZTRmNyIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzBmYjRlNyIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');
  background-size: 100%;
  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #a9e4f7), color-stop(100%, #0fb4e7));
  background-image: -webkit-linear-gradient(#a9e4f7, #0fb4e7);
  background-image: -moz-linear-gradient(#a9e4f7, #0fb4e7);
  background-image: -o-linear-gradient(#a9e4f7, #0fb4e7);
  background-image: -ms-linear-gradient(#a9e4f7, #0fb4e7);
  background-image: linear-gradient(#a9e4f7, #0fb4e7);
}

Des dégradés linéaires plus complexes sont évidemment supportés :

@include filter-gradient(#b8e1fc, #bdf3fd, vertical); // IE6-8
@include background-image(linear-gradient(top,
  #b8e1fc  0%, #a9d2f3 10%, #90bae4 25%, #90bcea 37%,
  #90bff0 50%, #6ba8e5 51%, #a2daf5 83%, #bdf3fd
));

Pour finir, un petit dégradé radial :

@include filter-gradient(#2ac363, #9c4cc2, horizontal); // IE6-8 fallback en gradient horizontal
@include background-image(radial-gradient(center, ellipse cover,
                                          #2ac363 0%, #cd8c14 50%, #9c4cc2));

Cumul de mixins CSS3

Cela va de soit, Compass permet de cumuler les appels aux mixins dédiés au support de CSS3. C’est d’ailleurs dans ces situations que l’on réalise le temps gagné grâce à lui.

Prenons pour exemple un simple bouton légèrement stylisé mais qui requiert tout de même :

Avec Compass, cela se fait en un tour de main :

$base-font-size: 16px !default;
@function x-pxem($pxval, $context: $base-font-size) {
  @return ($pxval / $context) * 1em;
}

a.btn {
  $start: #87bf17;
  $end:   #6c9912;
  @include filter-gradient($start, $end);
  @include background(linear-gradient($start, $end));
  @include border-radius(5px);
  @include inline-block;
  color: #fff;
  font: { weight: bold; size: x-pxem(18px); }
  text-decoration: none;
  border: 1px solid $end;
  padding: x-pxem(10px);
  &:hover {
    @include filter-gradient($end, $start);
    @include background(linear-gradient($end, $start));
    border-color: $start;
  }
}

L’exercice aurait été bien moins rapide en écrivant directement la CSS :

a.btn {
  *zoom: 1;
  filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#FF87BF17', endColorstr='#FF6C9912');
  background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzg3YmYxNyIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzZjOTkxMiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');
  background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #87bf17), color-stop(100%, #6c9912));
  background: -webkit-linear-gradient(#87bf17, #6c9912);
  background: -moz-linear-gradient(#87bf17, #6c9912);
  background: -o-linear-gradient(#87bf17, #6c9912);
  background: -ms-linear-gradient(#87bf17, #6c9912);
  background: linear-gradient(#87bf17, #6c9912);
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  -ms-border-radius: 5px;
  -o-border-radius: 5px;
  border-radius: 5px;
  display: -moz-inline-stack;
  display: inline-block;
  vertical-align: middle;
  *vertical-align: auto;
  zoom: 1;
  *display: inline;
  color: #fff;
  font-weight: bold;
  font-size: 1.125em;
  text-decoration: none;
  border: 1px solid #6c9912;
  padding: 0.625em;
}
a.btn:hover {
    *zoom: 1;
    filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#FF6C9912', endColorstr='#FF87BF17');
    background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzZjOTkxMiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzg3YmYxNyIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');
    background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #6c9912), color-stop(100%, #87bf17));
    background: -webkit-linear-gradient(#6c9912, #87bf17);
    background: -moz-linear-gradient(#6c9912, #87bf17);
    background: -o-linear-gradient(#6c9912, #87bf17);
    background: -ms-linear-gradient(#6c9912, #87bf17);
    background: linear-gradient(#6c9912, #87bf17);
    border-color: #87bf17;
}

Typographie

Compass simplifie la gestion des @font-face. Précisez le répertoire contenant vos fichiers de polices d’écriture à l’aide du paramètre fonts_dir dans le fichier de configuration du projet Compass. Par défaut, Compass les cherchera dans le répertoire fonts enfant du répertoire dans lequel seront générés les feuilles de styles (exemple : css/fonts).

Portez ce vieux whisky au juge blond qui fume

@include font-face(
  'MuseoSlab500Regular',
  font-files('Museo_Slab_500.woff', woff,
             'Museo_Slab_500.ttf' , truetype,
             'Museo_Slab_500.svg#MuseoSlab500Regular', svg),
  $eot: 'Museo_Slab_500.eot'
);
.my-font {
  font-family: 'MuseoSlab500Regular', "Comic Sans MS", sans-serif;
  font-size: 3em;
}

Ou de manière raccourcie, à condition de respecter l’ordre de définition des types de polices :

@include font-face(
  'MuseoSlab500Regularb',
  font-files('Museo_Slab_500.woff',
             'Museo_Slab_500.ttf',
             'Museo_Slab_500.svg#MuseoSlab500Regular'),
  'Museo_Slab_500.eot'
);

Parmi les divers mixins de manipulation typographiques de Compass, le mixin replace-text-with-dimensions s’avère être pratique pour remplacer de manière accessible un texte par une image (tiens, j’entends parler de logo au fond de la salle) :

<a id="logo" href="http://www.clever-age.com" title="Clever Garden, Clever Age, Clever Presence">
  Clever Age — 100% Digital
</a>

Sera masqué en 2 lignes utiles :

@import "compass/typography/text/replacement";
#logo {
  @include replace-text-with-dimensions('clever-age-digital.png');
  display: block;
}

DRY grâce aux plugins

La communauté de Compass est active et publie de nombreux plugins qui permettent d’étendre les fonctionnalité ou le catalogue de mixins disponibles depuis Compass.

Les plugins ont l’avantage d’éviter de réinventer la roue. Prenons pour exemple le plugin Compass Recipes qui regroupe une multitude de mixins rébarbatifs ou complexes à écrire comme, par exemple, la création des patterns CSS3 de Lea Verou.

L’installation d’un plugin est généralement simple :

$ gem install compass-recipes

Cela étant fait, il suffit de charger le plugin dans le fichier de configuration du projet Compass :

require 'compass-recipes'

Finalement, il ne vous reste plus qu’à importer le mixin désiré et à l’utiliser dans votre fichier Sass :

@import "recipes/background/carbon-fiber";
.carbon-gradient {
  @include background-carbon-fiber;
}