Les mixins (1/2)

Si une variable est bien utile pour stocker une valeur, que faut-il utiliser pour stocker un bloc de code entier afin de faciliter sa réutilisation ? Un mixin, évidemment !

Les mixins sont un gros morceau de Sass, que j’ai divisé en deux chapitres. Dans celui-ci, nous allons voir à quoi ils servent, puis nous allons en créer un et l’utiliser, et nous verrons enfin comment lui ajouter des arguments.

Un mixin, pourquoi faire ?

Intéressons-nous à nos boutons. En soi, ils sont assez banals. Si banals que, à l’exception de la couleur et de la police, on devrait pouvoir les réutiliser sur beaucoup de projets. Il serait donc pas mal de pouvoir empaqueter le code de nos boutons, pour le réutiliser plus tard, tout en se laissant la possibilité de changer certaines options.

Ce paquet a un nom, c’est un mixin. On peut le comparer à une macro : une macro est un ensemble d’instructions à effectuer, un mixin est un ensemble de styles à appliquer à un élément. On reste dans l’idée Don’t repeat yourself.

Je vous propose de construire notre mixin button pas à pas, à l’intérieur de la feuille partielle _button.scss. La première étape consiste à mettre les styles communs à tous nos boutons dans un bloc précédé de la directive @mixin et du nom que l’on souhaite donner à notre mixin. Voici donc le code de notre mixin :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
@mixin button {
    font: {
        family: $head-font;
        size: 1.25rem;
    }
    text: {
        decoration: none;
        align: center;
    }
    padding: .5rem;
    width: 12.5rem;
    border: none;
    display: block;
    float: none;
    margin: .5rem auto 0;
    @media #{$large-screen}{
        display: inline-block;
        float: right;
    }
}

Si vous tentez de compiler maintenant, ce code ne devrait générer aucune règle. Pourquoi ? Parce qu’on n’a pas dit à Sass où il doit insérer le contenu de notre mixin. C’est un peu comme pour les variables : on doit d’abord les déclarer pour pouvoir ensuite les inclure dans notre code.

Inclure un mixin

Il nous reste donc à inclure notre mixin. Pour cela, on se sert de la directive @include suivie du nom du mixin, comme ceci :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#produits .more, #clients .more {
    @include button;
    background-color: $dark;
    color: $ultra-light;
    &:hover {
        background-color: $dark-hover;
    }
}
#production .more, #contact button {
    @include button;
    background-color: $color;
    color: $dark;
    &:hover {
        background-color: $color-hover;
    }
}

Maintenant Sass comprend qu’il faut inclure le contenu du mixin button avant la compilation vers CSS. On peut inclure autant de mixins que l’on veut dans un même bloc. Ainsi, le code suivant est tout à fait envisageable :

1
2
3
4
5
6
7
//Code bidon
h1{
  @include mandarine;
  @include clementine;
  @include citron;
  @include button;
}

Voilà, vous savez désormais inclure un mixin, reste à voir comment le paramétrer.

Vous noterez cependant que le code généré n’est pas exactement celui que l’on avait auparavant. En effet, le contenu du mixin a été inclus deux fois, d’abord pour #produits .more, #clients .more, et ensuite pour #production .more, #contact button. Cela crée une répétition dans notre code CSS. On pourrait croire que cela alourdit le fichier envoyé au client et rallonge donc le temps de chargement. Sauf que… pas vraiment.

En fait, il est fort probable que vous utilisiez gzip sur votre serveur pour réduire la taille des fichiers envoyés à vos visiteurs (si ce n’est pas le cas, vous devriez1). Or l’un des mécanismes principaux de gzip consiste à supprimer toutes les répétitions (en les remplaçant par des pointeurs vers la première occurrence). Le fichier CSS généré par Sass sera donc probablement plus lourd, mais ce ne sera pas le cas du fichier envoyé à votre visiteur.


  1. Pour vérifier que gzip est bien configuré, il y a ce test

Les arguments

Pour l’instant, les règles concernant les couleurs de nos boutons sont en-dehors de notre mixin, puisque ce sont elles qui changent selon l’utilisation. Pour les insérer dans le mixin button, on va devoir utiliser des arguments. Un argument, c’est une variable à l’intérieur d’un mixin, qui peut prendre une valeur différente à chaque directive @include. C’est un peu comme les options de commande sur une livraison.

Pour notre mixin, il nous faudrait donc trois arguments :

  • $color : la couleur du texte du bouton ;
  • $background-color : la couleur de l’arrière-plan du bouton ;
  • $hover-color : la couleur de l’arrière-plan au hover.

La première étape va donc consister à écrire les règles dans notre mixin, en leur passant pour valeur nos trois arguments, comme n’importe quelles variables :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
@mixin button {
    font-family: $head-font;
    font-size: 1.25rem;
    text-decoration: none;
    text-align: center;
    padding: .5rem;
    width: 12.5rem;
    border: none;
    display: block;
    float: none;
    margin: .5rem auto 0;
    background-color: $background-color;
    color: $color;
    &:hover {
        background-color: $hover-color;
    }
    @media #{$large-screen} {
        display: inline-block;
        float: right;
    }
}

Maintenant, il faut déclarer ces arguments, et pour cela, on va ajouter leurs noms entre parenthèses après le nom du mixin. Si vous avez déjà fait de la programmation, cette syntaxe devrait vous rappeler les arguments d’une fonction.

1
2
3
@mixin button ($color, $background-color, $hover-color) {
    ...
}

Pour finir, doit renseigner la valeur de ces arguments à chaque @include, en écrivant leurs valeurs entre parenthèses, dans le même ordre que précédemment :

1
2
3
4
5
6
#produits .more, #clients .more {
    @include button($ultra-light, $dark, $dark-hover);
}
#production .more, #contact button {
    @include button($dark, $color, $color-hover);
}

Voilà, ce code nous économise de recopier plusieurs fois les mêmes règles lorsque seules les valeurs changent. Avec le même mixin, on obtient deux boutons de même forme mais de couleurs différentes.


En résumé

  • Un mixin est un bout de code réutilisable.
  • Il se déclare ainsi :

    1
    2
    3
    @mixin nom-du-mixin {
        //Code à réutiliser
    }
    
  • A chaque fois qu’on veut l’utiliser, on se sert de la directive @include nom-du-mixin.

  • Les arguments sont les options du mixin. On s’en sert comme ceci :

    1
    2
    3
    4
    5
    6
    7
    8
    @mixin nom-du-mixin($arg1, $arg2) {
        color: $arg1;
        font-size: $arg2;
    }
    // Plus loin
    p {
        @include nom-du-mixin(red, 22px);
    }
    

Je vous donne rendez-vous dans le prochain chapitre pour parler… des mixins, parce qu’on n’a pas encore tout vu.