Créer son propre système de grille flexible avec SASS

Dans la boîte à outils de l’intégrateur, il y a beaucoup de choses : des frameworks html et css, des générateurs de dégradés de couleur, un ou plusieurs préprocesseurs… et surtout il y a les grilles responsives. Quand on travaille avec un framework css, ces dernières sont souvent (voire systématiquement ) incluses. Impossible par ailleurs de dénombrer les systèmes de grille existants tant il y en a. Ce qui est sûr, c’est que nous avons le choix ! Mais parfois, il arrive que l’on soit amené à créer sois même un système de grille pour des besoins très spécifiques… C’est ce qui m’est arrivé récemment.

C’est pourquoi je vous propose une approche de création de grille reposant sur SASS. Il est entendu que c’est faisable en CSS, mais c’est beaucoup plus rapide en SASS, c’est la beauté de la chose 🙂

Le découpage du travail sera comme suit : D’abord on définira les différentes variables nécessaires ainsi que les points de rupture de notre grille responsive. Ensuite, on s’attardera sur la mécanique standard pour la génération de la grille “desktop”. Enfin on fera de même pour nos `media-queries`.

Définition de notre grille : Elle sera responsive bien sûr, on pourra choisir combien de colonnes on souhaite, la taille des gouttières, la largeur globale du conteneur, et les comportements des colonnes sur les différents appareils.

Voici les variables que je définis en premier lieu :

/* 1. valeurs de grille par défaut */

$cols: 12 !default;
$gutter-width: 1.2rem !default;
$max-width: 1180px !default;

On aura donc 12 colonnes, avec une gouttière de 1.2rem et une largeur maximum de 1200px. Ces valeurs sont suffisantes pour jeter les bases de la création de notre grille desktop. Ce que vous allons donc faire de ce pas :

/* 2. Définition de la grille */
.container {
  margin: 0 auto;
  width: 90%;
  max-width: $max-width;
}
.row {
  margin-left: 0;
  margin-right: 0;
  .row {
  	margin-left: -$gutter-width / 2;
  	margin-right: -$gutter-width / 2;
  }
  &:after {
    content: "";
    display: table;
    clear: both;
  }
  /* on divise la gouttière par 2 car on en retire une partie de chaque côté de la colonne */
  .col {
    float: left;
    box-sizing: border-box;
    padding: 0 $gutter-width / 2;
    margin-left: auto;
    left: auto;
    right: auto;

    /* On va boucler sur les colonnes et calculer automatiquement leur taille en pourcentage
     * un peu comme on pourrait le faire en javascript par exemple */
    $i: 1;
    @while $i <= $cols {
      $perc: unquote((100 / ($cols / $i)) + "%");
      &.small-#{$i} {
        width: $perc;
      }
      $i: $i + 1;
    }
  }
}

Dans ce système, ce sont les paddings qui définissent la taille de la gouttière. Ce qui fait que l’on n’a pas à se casser la tête avec le calcul de marges, d’autant que ces dernières ne sont pas prises en compte par `box-sizing: border-box`. Et ça c’est c’est déjà un pas vers plus de flexibilité : on peut ajouter autant de colonnes que l’on souhaite à notre ligne. Par ailleurs, plus de `row` ou `row-fluid` à la Bootstrap 2 : désormais toutes nos lignes sont fluides. Point. Seul le conteneur définira la largeur maximale de rendu. Et étant donné que nos tailles sont calculées en % on est tranquilles 🙂

A présent il ne reste plus qu’à générer cette grille pour les tailles d’écran choisies :

@media screen and (min-width:721px) {

      $i: 1;
      @while $i <= $cols {
        $perc: unquote((100 / ($cols / $i)) + "%");
        &.medium-#{$i} {
          width: $perc;
        }
        $i: $i + 1
      }
    }

    @media screen and (min-width:1025px) {

      $i: 1;
      @while $i <= $cols {
        $perc: unquote((100 / ($cols / $i)) + "%");
        &.large-#{$i} {
          width: $perc;
        }
        $i: $i + 1;
      }
    }

Et c’est tout ! Bon on pourrait aller beaucoup plus loin en définissant des comportements plus spécifiques, mais la base est là. Voici le résultat final :

/* 1. valeurs de grille par défaut */

$cols: 12 !default;
$gutter-width: 1.2rem !default;
$max-width: 1200px !default;
/* 2. Définition de la grille */
.container {
  margin: 0 auto;
  width: 90%;
  max-width: $max-width;
}
.row {
  margin-left: 0;
  margin-right: 0;
  .row {
  	margin-left: -$gutter-width / 2;
  	margin-right: -$gutter-width / 2;
  }
  &:after {
    content: "";
    display: table;
    clear: both;
  }
  /* on divise la gouttière par 2 car on en retire une partie de chaque côté de la */
  .col {
    float: left;
    box-sizing: border-box;
    padding: 0 $gutter-width / 2;
    margin-left: auto;
    left: auto;
    right: auto;

    /* On va boucler sur les colonnes et calculer automatiquement leur taille en pourcentage
     * un peu comme on pourrait le faire en javascript par exemple */
    $i: 1;
    @while $i <= $cols {
      $perc: unquote((100 / ($cols / $i)) + "%");
      &.small-#{$i} {
        width: $perc;
      }
      $i: $i + 1;
    }
    /* 3. Media Queries */
    @media screen and (min-width:721px) {

      $i: 1;
      @while $i <= $cols {
        $perc: unquote((100 / ($cols / $i)) + "%");
        &.medium-#{$i} {
          width: $perc;
        }
        $i: $i + 1
      }
    }

    @media screen and (min-width:1025px) {

      $i: 1;
      @while $i <= $cols {
        $perc: unquote((100 / ($cols / $i)) + "%");
        &.large-#{$i} {
          width: $perc;
        }
        $i: $i + 1;
      }
    }
  }
}

Il est entendu que la propriété flexbox tend à s’imposer pour ce qui est de la création de systèmes destinés à structurer le contenu. Je pense d’ailleurs qu’elle pourrait à terme remplacer nos systèmes de grille traditionnels. En revanche je pense que les systèmes comme celui que nous avons là on encore de beaux jours devant eux car ils restent à ce jour l’approche la plus stable car compatible avec n’importe quel navigateur / appareil.

Mais je me penche depuis quelques temps déjà sur flexbox, il n’est donc pas impossible que je fasse un article sur le sujet dans les semaines à venir 😉