Quantcast
Channel: Alsacreations.com - Apprendre
Viewing all articles
Browse latest Browse all 405

Tutoriel : Une grille responsive avec CSS3 Flexbox et LESS (ou Sass)

$
0
0

Ce tutoriel a pour but de présenter dans les détails une technique de conception de grille de mise en forme responsive à l’aide du positionnement CSS3 Flexbox Layout, actuellement parfaitement adapté à ce genre de fonctions en attendant une meilleure implémentation de Grid Layout.

En février 2016 est sorti mon livre entièrement dédié à Flexbox. Il se nomme "CSS3 Flexbox : plongez dans les CSS modernes" et je vous recommande bien évidemment sa lecture afin de comprendre tous les rouages de ce positionnement révolutionnaire, et d'en maîtriser tous les aspects.

Le concept de grille produite permettra de gérer les espaces inter-colonnes (gouttières), les décalages (“offsets”), les différentes tailles d’écran et d’être automatisable. Le tout en un minimum de code et un maximum de propreté HTML.

grille css

Voir le résultat final en ligne

Le fondement : Flexbox Layout

Notre grille sera construite grâce au module Flexbox, aujourd’hui compatible sur une bonne majorité des navigateurs (95% en France selon les stats Caniuse en fin 2014).

Si vous souhaitez assurer un maximum de compatibilité envers les anciens navigateurs, vous devrez vous rabattre sur les techniques float, table-cell ou inline-block avec tous les détails et exemples dans cet article consacré aux grilles de mise en forme.

Note : Flexbox nécessitant encore certaines précautions en terme de préfixes et de syntaxes, je vous conseille vivement de vous équiper de l’outil Autoprefixer afin de vous décharger de cette tâche fastidieuse une fois pour toutes.

Les bases de la grille

Mon souhait est que seul le conteneur sera affublé d’une classe, et ses enfants (directs) en bénéficieront automatiquement, sans avoir à les nommer spécifiquement.

Par exemple, le code imaginaire suivant pourrait générer une grille de 4 colonnes où tous les enfants directs occuperaient 1/4 de l’espace disponible s’il n’y a pas de gouttière :

.container-grid-4 {
    /* container's styles */
}
.container-grid-4 > * {
    /* direct children's styles */
}

Ébauche de grille en flexbox

Commençons par une grille de 4 éléments via flexbox et sans définir de gouttière :

/* moving to box-sizing (always) */
* { box-sizing: border-box; }

/* styles du conteneur */
/* hozizontal display and wrap enabled */
.container-grid-4 {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
}
/* direct children's styles */
/* width defined to 25% */
.container-grid-4 > * {
    flex: 0 0 auto;
    width: 25%;
}

Gérer la gouttière

À l’heure actuelle, gérer l’espace entre les éléments d’une grille n’est toujours pas aussi intuitif qu’il devrait l’être, nous sommes encore obligés de passer par des bidouilles pour cela.

L’une des astuce devenue un grand classique, le combo margin-left négatif sur le parent + padding-left sur chaque enfant, est certainement la plus prisée. Cependant, grâce au modèle particulier de Flexbox, nous allons pouvoir nous affranchir du padding et ne conserver comme critère que le margin.

Voici comment elle opère… Supposons que je souhaite créer trois colonnes espacées de 30px. Le principe de cette astuce est de :

  • conférer une largeur (width) de 33.33% à chacun des enfants moins la gouttière : width: calc(33.33% - 30px);
  • d’attribuer un box-sizing: border-box pour être sûr que les boîtes ne s’agrandiront pas en ajoutant du padding ou une bordure,
  • appliquer un margin-left de 30px sur chaque enfant,
  • appliquer une margin-left de valeur négative (-30px) sur le conteneur, ce qui aura pour effet d’étirer ses enfants et d’absorber le margin du premier enfant.
.container-grid-3 {
    margin-left: -30px;
}
.container-grid-3 > * {
    width: calc(33.33% - 30px);
    margin-left: 30px;
}

flex gouttières

Voir la grille avec gouttières

Automatiser avec un préprocesseur

Parvenu à ce stade, un nouveau pallier pourrait être franchi : celui d’automatiser la construction de la grille quel que soit le nombre de colonnes souhaitées et quelle qu’en soit la valeur de gouttière.

C’est à présent le boulot des préprocesseurs tels que LESS ou Sass. Pour ma part, j’ai choisi LESS pour ce tutoriel.

Créons un mixin .grid(x,y) que l’on pourrait appliquer à n’importe quel élément HTML conteneur, et donc les paramètres x et y représenteraient respectivement le nombre de colonnes et la largeur de la gouttière.

La largeur des enfants en pourcentage serait calculée selon le nombre de colonnes via la formule calc(100% * 1 / @{number} - @{gutter}); :


[class*="grid-"] {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	justify-content: space-between;
	margin-left: -@gutter;
}

[class*="grid-"] > * {
	flex: 0 0 auto;
	display: block; /* IE fix */
	width: ~'calc(100% * 1 / @{number} - @{gutter})';
	margin-left: @gutter;
}

 .grid(@number:@number, @gutter:@gutter) {
 & > * {
	  width: ~'calc(100% * 1 / @{number} - @{gutter})';
	}
}

Bonus : meilleure “sémantique” HTML

L’apport d’un mixin LESS, outre le fait d’automatiser la création de grilles, est d’épurer le code HTML et CSS en développement.

Ainsi, il ne sera plus nécessaire d’ajouter des classes supplémentaires dans notre “markup” puisque ce genre de syntaxe sera rendu possible :

ici je veux une grille de 6 colonnes
// section crée une grille de 6 colonnes espacées de 1em (défaut) chacune
.grid-perso {
    .grid(6);
}

Bonus : éléments double ou triple taille

Certains éléments doivent être mis en exergue et occuper le double d’espace que leurs voisins ? Rien de plus simple avec flexbox : il suffit d'adapter la valeur de width voire de l’automatiser avec LESS pour que cette valeur s’adapte quel que soit le nombre de colonnes.

.flexitem-double {
		width: ~'calc(100% * 2 / @{number} - @{gutter})';
	}
.flexitem-triple {
		width: ~'calc(100% * 3 / @{number} - @{gutter})';
	}

Bonus : “à la Une”

À présent, pourquoi ne pas continuer avec les bonnes choses ? Grâce à la propriété order du positionnement flexbox, il est très simple d’intervertir l’ordre d’affichage des éléments et faire remonter un bloc avant les autres.

Il suffit pour cela de lui attribuer une valeur de order inférieure à la valeur par défaut qu’est 0 :

// will be displayed first
.flexitem-first {
    order: -1;
}
// will be displayed last
.flexitem-last {
    order: 2;
}

Des Media Queries pour toutes les surfaces

Enfin, n’oublions pas le bouquet final qu’est l’adaptation à toutes les surfaces.

Là encore il est possible d’automatiser un maximum de fonctionnalités à l’aide de variables et de mixins.

Par exemple, pour forcer une grille à s’afficher en deux colonnes lorsque l’écran est réduit, voilà ce qui est envisageable :

@media (min-width: (@tiny-screen + 1)) and (max-width: @small-screen) {
		& > * {
			width: ~'calc(100% * 1 / 2 - @{gutter})';
		}
		& > .flexitem-double {
			width: ~'calc(100% - @{gutter})';
		}

Résultat final

Nous voici donc arrivés à la fin de notre (agréable) périple. Notre grille est prête et fonctionnelle.

flexbox grid

Concrètement, voici le récapitulatif des codes HTML et CSS / LESS employés tout au long de ce tutoriel.

J’espère que le résultat (et sa simplicité) vous convaincront !

HTML

<div class="grid-4">
    <div>1.</div>
    <div>2.</div>
    <div>3.</div>
    <div>4.</div>
    <div class="flexitem-double flexitem-first">5.</div>
    <div>6.</div>
    <div>7.</div>
    <div>8.</div>
    <div>9.</div>
    <div style="margin-left: auto;">10.</div>
</div>

CSS / LESS (styles de travail)

C’est le fichier LESS qui nous servira de base de travail pour modifier les styles de notre projet.

Pour notre plus grand plaisir, il est réduit au strict minimum.

Exemple de grille de 6 colonnes espacées de 1em (défaut) chacune, appliquée sur l'élément de classe ".grid-container" :

.grid-container {
    .grid(6);
}

Exemple de grille de 12 colonnes espacées de 10px chacune, appliquée sur l'élément de classe ".grid-perso-douze" :

.grid-perso-douze {
    .grid(12, 10px);
}

CSS / LESS (mixins LESS)

Ces mixins sont définis une fois pour toute, il devrait être inutile d’y toucher ou de les modifier une fois qu’ils sont en place.

// grid styles for container wich has a .grid(n,g) class
// n = number of columns (default = 4)
// g = gutter value (default = 1em)
// example : .grid-container { .grid(12, 10px); }

[class*="grid-"] {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	justify-content: space-between;
	margin-left: -@gutter;
}

[class*="grid-"] > * {
	flex: 0 0 auto;
	display: block; /* IE fix */
	width: ~'calc(100% * 1 / @{number} - @{gutter})';
	margin-left: @gutter;
}

 .grid(@number:@number, @gutter:@gutter) {
 & > * {
	  width: ~'calc(100% * 1 / @{number} - @{gutter})';
	}
	& > .flexitem-double {
		width: ~'calc(100% * 2 / @{number} - @{gutter})';
	}
	& > .flexitem-first {
		order: -1;
	}
	@media (min-width: (@tiny-screen + 1)) and (max-width: @small-screen) {
		& > * {
			width: ~'calc(100% * 1 / 2 - @{gutter})';
		}
		& > .flexitem-double {
			width: ~'calc(100% - @{gutter})';
		}
	}
	@media (max-width: @tiny-screen) {
		& > * {
			width: ~'calc(100% - @{gutter})';
		}
		& > .flexitem-double {
			width: ~'calc(100% - @{gutter})';
		}
	}
}

Voir le résultat final en ligne

Retrouvez l'intégralité de ce tutoriel en ligne sur Alsacreations.com


Viewing all articles
Browse latest Browse all 405

Trending Articles