Techniques Flexbox, 4: conception d'une page produits

Levin Mejia, adepte de l’apprentissage par la pratique, nous propose de créer un layout flexible et responsif avec Flexbox. On s’amuse à apprendre ses concepts et propriétés fondamentales.

Par

Intro de Chris Coyier sur CSS-Tricks : L’article qui suit est de Levin Mejia, designer chez Shopify. Shopify utilise Flexbox dans un nouveau thème qu’ils ont développé récemment et ils souhaitaient partager certaines de leurs techniques ici. À une offre pareille, on ne peut que répondre : oui, avec plaisir.
Chris Coyier

Tous les jours à Shopify, je discute avec des partenaires qui essaient constamment de repousser les limites de ce qu’il est possible de faire dans l’e-commerce en termes de design. J’ai remarqué dernièrement que de nombreux designers expérimentaient Flexbox sur les boutiques en ligne. L’un de nos premiers objectifs, en tant que designer ou développeur, est d’attirer l’attention sur le contenu et de faciliter la navigation de nos visiteurs à travers ce contenu. Pour y parvenir, nous avons besoin d’un layout qui fonctionne, et dans lequel la technologie cède le pas au contenu.

Flexbox peut nous aider à créer des layouts flexibles, optimisés pour le web et les terminaux mobiles. Mais l’utilisons-nous ? Nous sommes nombreux à encore utiliser les floats et les inline-blocks. Bien sûr, vous connaissez mieux que quiconque votre audience, donc si vous avez encore beaucoup d’utilisateurs sur, par exemple, IE9 et en-deçà, et que vous n’êtes pas prêt à créer les fallbacks nécessaires, vous risquez d’être coincé dans float-land pour un moment. Cependant, beaucoup d’indicateurs (de compatibilité) sont au vert dans flexbox-land de nos jours.

Je crois beaucoup dans l’apprentissage par la pratique. Cet article nous fera parcourir les étapes de la création d’un thème gratuit Shopify appelé Venture, utilisant Flexbox.

Si vous voulez suivre les exemples de cet article, vous pouvez vous reporter au CodePen complet.

Dans cette petite introduction, je vais montrer comment créer un layout responsive et flexible avec Flexbox qui focalisera l’attention sur les produits d’une manière unique, selon les viewport utilisés. Nous le ferons en moins de 100 lignes de CSS.

Le thème Venture

Les designers de Shopify ont récemment créé un template assez joli, appelé Venture. Le layout est optimisé pour la meilleure expérience de shopping et met fortement l’accent sur les produits. Le layout a été développé pour répondre à de nombreux cas d’usage, mais pour ce tutoriel nous nous concentrerons sur les aspects les plus importants et nous les recréerons avec flexbox. Dans les étapes qui suivent, nous allons apprendre comment centrer les éléments, créer des footers parfaitement fixés en bas de page, donner la priorité à tel ou tel produit selon le viewport et le terminal, cibler les éléments flexbox avec les media queries, et nous apprendrons les bases de flexbox — de telle sorte que vous pourrez mettre en oeuvre flexbox dans votre prochain projet.

Si vous voulez utiliser les exemples de code de cet article sur un Store Shopify avec de vrais produits, enregistrez-vous en tant que Shopify Partner et créez un development store gratuit. Un development store vous offre accès à toutes les fonctionnalités payantes d’un store Shopify, de sorte que vous pouvez l’utiliser comme un environnement d’expérimentation ou travailler sur un thème pour un client.

Le layout du header

La première chose que nous allons faire, c’est mettre en place notre filtre de navigation qui contient notre titre principal et deux filtres (avec menu déroulant) avec une étiquette (label).

Commençons par créer un container flexbox et son contenu :

//HTML
<nav class="product-filter">

  <h1>Jackets</h1>

  <div class="sort">

    <div class="collection-sort">
      <label>Filter by:</label>
      <select>
        <option value="/">All Jackets</option>
      </select>
    </div>

    <div class="collection-sort">
      <label>Sort by:</label>
      <select>
        <option value="/">Featured</option>
      </select>
    </div>

  </div>

</nav>  

Notre .product-filter sera notre container flex, qui nous permettra d’aligner les éléments enfants flex items comme il faut. Nous déclarons le flex container de cette façon :

//CSS
.product-filter {
  display: flex;
}

Nous donnons à notre élément <h1> une valeur de flex-grow égale à 1, ce qui a pour effet à la fois d’étendre le flex container dans toute la largeur et de s’étendre lui-même dans l’espace restant (ce qui aligne à droite les menus déroulants).

//CSS
.product-filter h1 {
  flex-grow: 1;
}

Pour aligner horizontalement les éléments enfants de notre .sort container, nous allons en faire un container flex à son tour. On peut imbriquer autant de containers flex qu’on veut !

//CSS
.sort {
  display: flex;
}

Les containers de filtres sont empilés l’un sur l’autre, par défaut :

Par défaut, display: flex; aligne les éléments enfants horizontalement. Nous allons nous en servir pour aligner les containers côte à côte. Chacun sera un container flex (un troisième container flex imbriqué !) et nous utiliserons aussi flex-direction: column pour les filtres, de façon à ce qu’ils soient alignés verticalement :

//CSS
.collection-sort {
  display: flex;
  flex-direction: column;
}

Avec juste quelques lignes de CSS, notre titre et nos filtres sont alignés comme nous le souhaitons. Nous allons maintenant travailler sur notre grille de layout pour les produits.

Le layout des produits

Nous allons utiliser le HTML suivant pour notre layout flexbox :

//HTML
<section class="products">

  <div class="product-card">
    <div class="product-image">
      <img src="assets/img/coat-01.jpeg">
    </div>
    <div class="product-info">
      <h5>Winter Jacket</h5>
      <h6>$99.99</h6>
    </div>
  </div>

  <!-- d’autres produits -->

</section>  

Comme tout à l’heure, nous avons besoin d’un container flex. Dans ce scénario, nous allons utiliser .products comme flex container. Nous allons ajouter deux propriétés qui permettront aux enfants flex d’une part de s’aligner horizontalement et d’autre part de s’aligner sur une nouvelle rangée à mesure que la largeur du viewport s’étend ou se réduit :

//CSS
.products {
  display: flex;
  flex-wrap: wrap;
}

Par défaut, display: flex; dispose les enfants horizontalement en commençant à gauche, mais nous avons ajouté flex-wrap: wrap; pour que ces enfants s’alignent sur une nouvelle rangée lorsqu’il n’y a pas assez d’espace pour placer tous les éléments sur la même rangée.

Pour commencer à contrôler la largeur de nos items flex, nous allons ajouter flex: 1; afin que tous nos items flex occupent le même espace dans la rangée. Dans notre exemple, nous avons 10 blousons et l’ajout de flex: 1; les aligne tous sur une rangée.

Mais pour notre design, nous voulons 5 items par rangée, le reste se redéployant sur de nouvelles rangées. Pour en avoir 5 par rangée, chaque item devra avoir une largeur de 20% (5 × 20 = 100). En donnant une valeur de 20% à flex-basis, ça devrait le faire — mais lorsque nous ajoutons le padding, nous dépassons les 100% et nous n’avons que 4 items par rangée. Avec un padding de 2% de chaque côté et une flex-basis de 16%, nous obtenons l’effet recherché.

//CSS
.products {
  display: flex;
  flex-wrap: wrap;
}

.product-card {
  padding: 2%;
  flex-grow: 1;
  flex-basis: 16%;
}

Nous pouvons aussi l’écrire en raccourci de cette façon :

//CSS
.product-card {
  flex: 1 16%;
}

Avec une valeur de flex-grow égale à 1 pour les produits, nous sommes sûrs que la rangée de produits occupera toujours tout l’espace.

Pour nous assurer que les images seront bien adaptées à leur espace, nous ajoutons :

//CSS
.product-image img {
  max-width: 100%;
}

Aligner les footers par le bas

Il est parfois compliqué de fixer un footer ou un contenu au bas d’un container. Là encore, flexbox nous est d’un grand secours.Si vous avez suivi le code pas à pas, vous avez remarqué que les labels de nos blousons ne sont pas parfaitement alignés sous l’image.

La taille variable des images entraîne un effet d’escalier pour nos labels

Ce genre de scénario est très fréquent : nous ne pouvons pas contrôler la hauteur ni la longueur du contenu, mais nous voudrions avoir un autre élément parfaitement aligné au bas du container. Flexbox nous aide déjà à avoir une même taille pour les containers à l’intérieur de chaque rangée, mais les images ont des tailles variables.

Les méthodes habituelles d’alignement en bas font appel au positionnement absolu ou même à JavaScript. Heureusement, avec flexbox cette tâche relativement complexe est accomplie en ajoutant simplement le CSS suivant à notre container .product-info :

//CSS
.product-info {
  margin-top: auto;
}

Et voilà, c’est tout ! Flexbox est suffisamment malin pour placer l’élément en bas du container flex. Avec quelques lignes de styles, nous avons donc obtenu ceci :

Des titres bien alignés en bas

Flexbox responsif

Lorsque nous avons moins d’espace disponible, nous souhaitons réduire le nombre de produits par rangée. Par exemple, si la largeur maximale du viewport est de 920px, nous voulons limiter le nombre d’items par rangée à quatre, ce que nous pouvons obtenir avec ceci :

//CSS
@media (max-width: 920px) {
  .product-card {
    flex: 1 21%;
  }
}

(rappel : ce n’est pas 25% parce que nous devons tenir compte du padding. On pourrait compenser via box-sizing: border-box, mais c’est vous qui choisissez).

Les lignes de CSS précédentes nous donnent presque le résultat souhaité puisque nous voulons quatre items par rangée, mais la dernière rangée laisse à désirer.

Flexbox est suffisamment malin pour remplir l’espace disponible, cependant pour améliorer la mise en page pour ce viewport nous préfèrerions avoir des images grand format en haut plutôt qu’en bas, afin de mieux mettre en valeur les produits.

Une des façons d’agrandir les deux premières images plutôt que les deux dernières et de les sélectionner et de changer leur dimension directement :

//CSS
/* Sélectionner les deux premiers */
.products .product-card:first-child, 
.products .product-card:nth-child(2) {
  flex: 2 46%;
}

Maintenant nous avons un layout intéressant, optimisé pour les viewports réduits, tels que les iPads en mode portrait.

Pour les viewports encore plus petits, nous préfèrerions un layout sur deux colonnes, ce qu’on peut obtenir ainsi :

//CSS
@media (max-width: 600px) {
  .product-card {
    flex: 1 46%;
  }
}

Cependant, si nous regardons maintenant notre page sur un viewport réduit, tel qu’un iPhone 6, nous constatons que notre barre de navigation et notre titre se chevauchent.

La raison en est que notre .product-filter est prévu pour contenir tous nos flex-items sur une seule ligne, quel que soit le nombre d’items (pas de wrapping). Avec le code suivant, nous pouvons facilement modifier ceci et aligner notre contenu verticalement :

//CSS
@media (max-width: 480px) {
  .product-filter {
    flex-direction: column;
  }
}

Notre titre et nos filtres ne se chevauchent plus mais nous pouvons encore améliorer la disposition en flottant nos filtres à gauche. Auparavant ils étaient flottés à droite grâce à la propriété align-self réglée sur align-self: flex-end;, maintenant nous allons utiliser align-self: flex-start;

//CSS
@media (max-width: 480px) {
  .product-filter {
    flex-direction: column;
  }
  .sort {
    align-self: flex-start;
  }
}

Ça y est, nous avons maintenant un layout flexible et responsif pour nos produits.

Compatibilité

Comme mentionné au début de cet article, la compatibilité est bonne de nos jours. Les versions d’IE qui ne supportent pas flexbox ne sont plus maintenues par Microsoft.

Comme pour tout projet, vous devriez tester les résultats de manière approfondie pour être sûr que l’expérience utilisateur est optimisée et que votre layout répond aux besoins de votre projet.

Conclusion

Dans ce tutoriel, nous avons construit un layout responsif efficace pour afficher un ensemble de produits en utilisant flexbox. Contrairement à d’autres méthodes CSS qui ne sont pas prévues pour construire des layouts, flexbox est un outil puissant prévu pour cet objectif et vous devriez en profiter. Les layouts flexbox peuvent rendre nos sites plus flexibles et plus résistants.

Il y a encore beaucoup de choses à apprendre sur flexbox, vous pouvez utiliser le guide complet de Flexbox comme une référence.


Intéressé par CSS ? Retrouvez une liste des meilleurs articles et ressources du web.

Tous les articles sur Flexbox parus dans la Cascade.

Vous pouvez également consulter le Dico-CSS sur chacune des propriétés de Flexbox, par exemple justify-content, align-content, align-items, flex-direction...


Ressources complémentaires en anglais

W3C, recommandation Flexbox
Flexbox, in Codrops CSS reference, long article détaillé de Sara Soueidan
Using Flexbox today, par Chris Wright
A designer’s guide to Flexbox, de Philip Walton
Solved by Flexbox, de Philip Walton, une démonstration par l’exemple de tout les problèmes que Flexbox peut résoudre.
Flexbox cheatsheet, l’antisèche de flexbox, un excellent complément à cet article, beaucoup d’exemples pratiques de positionnement.
Flexbox Cheatsheet Cheatsheet, par Joni Trythall, une superbe antisèche à télécharger, super pratique !
Flexbox, The next generation of CSS layout has arrived, par Nick Pettit (Treehouse)

Outils pour expérimenter Flexbox en ligne :

   Flexbox Froggy, un jeu absolument génial pour apprendre Flexbox !
Flexplorer
Flexbox adventures, par Chris Wright
CSS Flexbox Please!
Flexy Boxes
Un terrain de jeu pour comprendre Flexbox.

Ressources complémentaires en français

CSS3 Flexbox Layout module, par Raphaël Goetter
Jack in the Flexbox, un blog entièrement consacré à Flexbox, par Raphaël Goetter
Le petit flexbox illustré, excellente intro à flexbox par Vincent Valentin
Utiliser Flexbox, par Sean Fioritto (ici-même) : Sean répond ici à la question “quand pourrai-je utiliser Flexbox dans le monde réel ?”
Exercices Flexbox, excellent site pédagogique de Cyril Vernier


Article original paru le 15 janvier 2016 dans CSS-Tricks.

Sur l’auteur : est est web designer freelance, il travaille sous le nom de IV & III (Four and Three). on peut le suivre sur Twitter, sur son blog ou le contacter directement.

Traduit avec l’aimable autorisation de CSS-Tricks et de l’auteur.
Copyright CSS-Tricks © 2016.