Flexbox

Le mode de mise en page « Flexible Box » ou « Flexbox » offre une alternative aux flotteurs pour définir l’apparence globale d’une page Web. Alors que les flotteurs ne nous permettent que de positionner horizontalement nos boîtes, Flexbox nous donne un contrôle total sur l’alignement, la direction, l’ordre et la taille de nos boîtes.

Le web est en train de vivre une très grande transformation, de sorte qu’une petite discussion autour de l’état de l’industrie est justifiée. Au cours de la dernière décennie, les flotteurs étaient la seule option pour disposer d’une page Web complexe. En conséquence, ils sont bien pris en charge, même dans les navigateurs anciens, et les développeurs les ont utilisés pour créer des millions de pages Web.

Cependant, les flotteurs étaient initialement destinés aux mises en page de style magazine que nous avons abordées dans Flotteur et contenu . Malgré ce que nous avons vu dans ce chapitre, les types de mises en page que vous pouvez créer avec des flotteurs sont en quelque sorte un peu limité. Même une simple disposition de la barre latérale est, techniquement parlant, du bidouillage. Flexbox a été inventé pour sortir de ces limitations.

Nous sommes finalement à un point où la majeure partie des navigateurs récents supportent Flexbox et donc les développeurs peuvent commencer à créer des sites Web complets grâce à cette technologie. Notre recommandation est d’utiliser Flexbox pour la mise en page de vos pages Web, en réservant les flotteurs lorsque vous avez besoin de placer du texte autour d’une boîte (c.-à-d. Une mise en page de style magazine) ou lorsque vous devez prendre en charge des navigateurs Web très anciens.

Dans ce chapitre, nous allons explorer l’ensemble du modèle de mise en page Flexbox étape par étape.

Mise en place

L’exemple de ce chapitre est relativement simple, mais il démontre clairement toutes les propriétés flexbox importantes. Nous aboutirons à quelque chose qui ressemble à ceci:

Pour commencer, nous avons besoin d’un document HTML vide qui ne contient qu’une barre de menu. Créez un nouveau projet appelé flexbox pour héberger tous les exemples de ce chapitre. Ensuite, créez flexbox.html et ajoutez le balisage suivant:

<!DOCTYPE html>
<html lang='fr'>
  <head>
    <meta charset='UTF-8'/>
    <title>Une page Web</title>
    <link rel='stylesheet' href='styles.css'/>
  </head>
  <body>
    <div class='menu-container'>
      <div class='menu'>
        <div class='date'>14 Octobre 2017</div>
        <div class='signup'>S'inscrire</div>
        <div class='login'>Connexion</div>
      </div>
    </div>
  </body>
</html>
HTML

Ensuite, nous devons créer la feuille de style styles.css correspondante. Juste une barre de menu bleue pleine largeur avec une boîte à bord blanc. Notez que nous utiliserons Flexbox au lieu de notre technique traditionnelle de marge automatique pour centrer le menu.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  color: #fff;
  background-color: #5995DA;  /* Bleu */
  padding: 20px 0;
}

.menu {
  border: 1px solid #fff;  /* Pour debbugage */
  width: 900px;
}
CSS

Enfin, téléchargez les images à utiliser dans notre exemple de page Web. Décompressez-les dans le projet flexbox , en gardant le répertoire parent images. Votre projet devrait ressembler à ceci avant de passer à l’étape suivante:

Présentation de flexbox

Flexbox utilise deux types de boîtes que nous n’avons jamais vues auparavant: les “flex containers” (contenants flexibles) et les “flex items” (éléments flexibles). Le travail d’un conteneur flexible consiste à regrouper un ensemble d’éléments flex et à définir comment ils sont positionnés.

Chaque élément HTML qui est un enfant direct d’un conteneur flexible est un « item » (élément). Les éléments Flex peuvent être manipulés individuellement, mais pour la plupart, il appartient au conteneur de déterminer leur mise en page. Le but principal des items flexibles est de faire savoir à leur conteneur combien de chose il doit positionner.

Comme pour les mises en page basées sur les flotteurs, le but c’est de « ranger » des boîtes . Vous alignez un tas d’éléments flexibles à l’intérieur d’un conteneur et, à leur tour, ces articles peuvent servir de conteneurs flex pour leurs propres éléments. Au fur et à mesure que vous travaillerez dans les exemples de ce chapitre, n’oubliez pas que la tâche fondamentale pour mettre en page n’a pas changé: nous continuons à déplacer un tas de boîtes imbriquées.

Conteneurs flexible

La première étape de l’utilisation de Flexbox consiste à transformer l’un de nos éléments HTML en un conteneur flexible. Nous faisons cela avec la propriété display, ce qui devrait vous être familier après le chapitre sur les modèles de boîte CSS. En lui donnant une valeur de flex, nous disons au navigateur que tout dans la boîte devrait être rendu avec Flexbox au lieu du modèle de boîte par défaut.

Ajoutez la ligne suivante à notre selecteur .menu-container pour la transformer en un conteneur flexible:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  display: flex;
  color: #fff;
  background-color: #5995DA;  /* Bleu */
  padding: 20px 0;
}

.menu {
  border: 1px solid #fff;  /* Pour debbugage */
  width: 900px;
}
CSS

Cela active le mode de mise en page de Flexbox – sans lui, le navigateur ignorerait toutes les propriétés de Flexbox que nous allons présenter. La définition explicite des contenants flexibles signifie que vous pouvez mélanger et faire correspondre flexbox avec d’autres modèles de mise en page (p. Ex., Flotteurs et tout ce que nous allons apprendre dans le chapitre sur le positionnement avancé ).

Génial! Nous avons un conteneur flexible avec un élément flexible à l’intérieur. Cependant, notre page n’aura pas changé, car nous n’avons pas dit au conteneur comment afficher son « item ».

Alignement d’un élément flex

Après avoir un conteneur flexible, votre prochain travail consiste à définir l’alignement horizontal de ses éléments. C’est à cela que sert la propriété justify-content. Nous pouvons l’utiliser pour centrer notre .menu , ainsi:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  display: flex;
  justify-content: center;
  color: #fff;
  background-color: #5995DA;  /* Bleu */
  padding: 20px 0;
}

.menu {
  border: 1px solid #fff;  /* Pour debbugage */
  width: 900px;
}
CSS

Cela a le même effet que l’ajout d’une déclaration margin: 0 auto à l’élément .menu. Mais, notez comment nous l’avons fait en ajoutant une propriété à l’élément parent (le conteneur flexible) au lieu de directement à l’élément que nous voulions centrer (l’élément flexible). Manipuler les objets à travers leurs conteneurs comme celui-ci est un thème commun dans Flexbox, et c’est un peu une divergence avec la façon dont nous positionnions les boîtes jusqu’ici.

Les autres valeurs possible pour justify-content sont présentées ci-dessous:

  • center
  • flex-start
  • flex-end
  • space-around
  • space-between

Essayez de modifier justify-content avec les valeurs flex-start et flex-end. Cela devrait aligner respectivement le menu vers le côté gauche et droit de la fenêtre du navigateur. Assurez-vous de remettre la valeur center avant de continuer. Les deux dernières options ne sont utiles que lorsque vous disposez de plusieurs éléments flexibles dans un conteneur.

Distribution de plusieurs éléments flex

« La belle affaire », vous pourriez dire: nous pouvons faire l’alignement à gauche et à droite avec les flotteurs et le centrage avec les marges automatiques. C’est Vrai. Flexbox ne montre sa force réelle que lorsque nous avons plus d’un élément dans un conteneur. La propriété justify-content vous permet également de distribuer des éléments dans un conteneur.

Modifiez notre selecteur .menu pour le faire correspondre à ce qui suit:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  display: flex;
  justify-content: center;
  color: #fff;
  background-color: #5995DA;  /* Bleu */
  padding: 20px 0;
}

.menu {
  border: 1px solid #fff;  /* Pour debbugage */
  width: 900px;
  display: flex;
  justify-content: space-around;
}
CSS

Cela transforme notre .menu en un conteneur flexible imbriqué, et la valeur de space-around diffuse ses éléments sur toute sa largeur. Vous devriez voir quelque chose comme ceci:

Le conteneur flexible distribue automatiquement un espace horizontal supplémentaire de chaque côté de chaque élément. La valeur space-between est similaire, mais cela n’ajoute que l’espace supplémentaire entre les éléments. C’est ce que nous voulons réellement pour notre page d’exemple, alors allez-y et mettez à jour la ligne justify-content :

justify-content: space-between;
CSS

Bien sûr, vous pouvez également utiliser les valeurs centerflex-start, ou flex-end si vous souhaitez pousser tous les éléments d’un côté ou de l’autre, mais pour le moment laissez-le sur la valeur space-between.

Groupement d’éléments flex

Les conteneurs Flex ne savent positionner que des éléments qui sont au niveau directement inférieur (c.-à-d. Leurs éléments enfants). Ils ne se soucient pas de ce qui se trouve au sein de leurs éléments flexibles. Cela signifie que le regroupement d’éléments flexibles est une autre arme dans votre arsenal de mise en page. Incorporer un tas d’éléments dans une balise <div> supplémentaire aboutira à une page Web totalement différente.

Par exemple, disons que vous voulez que les liens d’inscription et de connexion soient sur le côté droit de la page, comme dans la capture d’écran ci-dessous. Tout ce qu’il faut faire est de les coller dans un autre <div> :

<!DOCTYPE html>
<html lang='fr'>
  <head>
    <meta charset='UTF-8'/>
    <title>Une page Web</title>
    <link rel='stylesheet' href='styles.css'/>
  </head>
  <body>
    <div class='menu-container'>
      <div class='menu'>
        <div class='date'>14 Octobre 2017</div>
        <div class='links'>
          <div class='signup'>S'inscrire</div>
          <div class='login'>Connexion</div>
        </div>  
      </div>
    </div>
  </body>
</html>
HTML

Au lieu d’avoir trois éléments, notre conteneur de .menu en contient maintenant seulement deux ( .date et .links ). Les deux ayant le du comportement space-between, ils vont s’ajuster aux côtés gauche et droit de la page.

Mais, maintenant, nous devons styliser l’élément .links car il utilise le mode de mise en page par défaut. La solution: plus de contenants flexibles imbriqués! Ajoutez une nouvelle règle à notre fichier styles.css qui transforme l’élément .links en un conteneur flexible:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  display: flex;
  justify-content: center;
  color: #fff;
  background-color: #5995DA;  /* Bleu */
  padding: 20px 0;
}

.menu {
  border: 1px solid #fff;  /* Pour debbugage */
  width: 900px;
  display: flex;
  justify-content: space-around;
}

.links {
  border: 1px solid #fff;  /* For debugging */
  display: flex;
  justify-content: flex-end;
}

.login {
  margin-left: 20px;
}
CSS

Cela mettra nos liens directement là où nous les voulons. Notez que les marges fonctionnent toujours comme dans le modèle de boîte CSS. Et, comme avec le modèle de boîte normale, les marges automatiques ont une signification particulière dans flexbox (mais nous allons laisser cela pour la fin du chapitre).

Nous n’avons plus besoin de ces bordures blanches, vous pouvez les supprimer si vous le souhaitez.

Alignement vertical

Jusqu’à présent, nous avons manipulé l’alignement horizontal, mais les conteneurs flex peuvent également définir l’alignement vertical de leurs éléments. C’est quelque chose qui n’est tout simplement pas possible avec les flotteurs.

Pour explorer cela, nous devons ajouter un en-tête sous notre menu. Ajoutez le balisage suivant à flexbox.html après l’élément .menu-container:

<!DOCTYPE html>
<html lang='fr'>
  <head>
    <meta charset='UTF-8'/>
    <title>Une page Web</title>
    <link rel='stylesheet' href='styles.css'/>
  </head>
  <body>
    <div class='menu-container'>
      <div class='menu'>
        <div class='date'>14 Octobre 2017</div>
        <div class='links'>
          <div class='signup'>S'inscrire</div>
          <div class='login'>Connexion</div>
        </div>  
      </div>
    </div>
    <div class='header-container'>
      <div class='header'>
        <div class='subscribe'>Subscribe ▾</div>
        <div class='logo'><img src='images/awesome-logo.svg'/></div>
        <div class='social'><img src='images/social-icons.svg'/></div>
      </div>
    </div>
  </body>
</html>
HTML

Ensuite, ajoutez du CSS pour l’aligner sur notre élément .menu:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  display: flex;
  justify-content: center;
  color: #fff;
  background-color: #5995DA;  /* Bleu */
  padding: 20px 0;
}

.menu {
  border: 1px solid #fff;  /* Pour debbugage */
  width: 900px;
  display: flex;
  justify-content: space-around;
}

.links {
  border: 1px solid #fff;  /* For debugging */
  display: flex;
  justify-content: flex-end;
}

.login {
  margin-left: 20px;
}

.header-container {
  color: #5995DA;
  background-color: #D6E9FE;
  display: flex;
  justify-content: center;
}

.header {
  width: 900px;
  height: 300px;
  display: flex;
  justify-content: space-between;
}
CSS

Tout cela devrait vous être familier; cependant, le scénario est un peu différent que pour notre menu. Puisque .header a une hauteur explicite, les éléments peuvent être positionnés verticalement à l’intérieur de celui-ci. La spécification officielle appelle cet alignement « axe croisé » (nous verrons pourquoi dans un instant), mais pour nous, il pourrait aussi être appelé alignement « vertical ».

L’alignement vertical est défini en ajoutant une propriété align-items à un conteneur flexible. Faites en sorte que notre page d’exemple corresponde à la capture d’écran ci-dessus avec la ligne suivante:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  display: flex;
  justify-content: center;
  color: #fff;
  background-color: #5995DA;  /* Bleu */
  padding: 20px 0;
}

.menu {
  border: 1px solid #fff;  /* Pour debbugage */
  width: 900px;
  display: flex;
  justify-content: space-around;
}

.links {
  border: 1px solid #fff;  /* For debugging */
  display: flex;
  justify-content: flex-end;
}

.login {
  margin-left: 20px;
}

.header-container {
  color: #5995DA;
  background-color: #D6E9FE;
  display: flex;
  justify-content: center;
}

.header {
  width: 900px;
  height: 300px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
CSS

Les options disponibles pour align-items sont similaires à justify-content:

  • center
  • flex-start   (top)
  • flex-end      (bottom)
  • stretch
  • baseline

La plupart d’entre eux sont très simples à comprendre. L’option stretch vaut la peine de prendre une minute pour la tester, car elle vous permet d’afficher l’arrière-plan de chaque élément. Regardons ça brièvement en ajoutant ce qui suit à styles.css :

.header {
  /* ... */
  align-items: stretch;    /* Changer cette ligne */
}

.social,
.logo,
.subscribe {
  border: 1px solid #5995DA;
}
CSS

La boîte pour chaque élément prend toute la hauteur du conteneur flexible, quel que soit le contenu qu’il contient. Un cas d’utilisation courant pour ce comportement consiste à créer des colonnes d’hauteur égale avec une quantité variable de contenu dans chacun d’eux, ce qui est très difficile à réaliser avec les flotteurs.

Assurez-vous de supprimer les dernières modifications avant de continuer

Envelopper des éléments flex

Flexbox est une alternative plus puissante aux grilles basées sur les flotteurs. Non seulement il peut rendre les éléments sous forme de grille, mais aussi changer leur alignement, leur direction, leur ordre et leur taille. Pour créer une grille, nous avons besoin de la propriété flex-wrap.

Ajoutez une ligne de photos à notre fichier flexbox.html afin que nous ayons quelque chose sur quoi travailler. Ce bout de code doit être placé dans <body>, sous l’élément .header-container:

<!DOCTYPE html>
<html lang='fr'>
  <head>
    <meta charset='UTF-8'/>
    <title>Une page Web</title>
    <link rel='stylesheet' href='styles.css'/>
  </head>
  <body>
    <div class='menu-container'>
      <div class='menu'>
        <div class='date'>14 Octobre 2017</div>
        <div class='links'>
          <div class='signup'>S'inscrire</div>
          <div class='login'>Connexion</div>
        </div>  
      </div>
    </div>
    <div class='header-container'>
      <div class='header'>
        <div class='subscribe'>Subscribe ▾</div>
        <div class='logo'><img src='images/awesome-logo.svg'/></div>
        <div class='social'><img src='images/social-icons.svg'/></div>
      </div>
    </div>
    <div class='photo-grid-container'>
      <div class='photo-grid'>
        <div class='photo-grid-item first-item'>
          <img src='images/one.svg'/>
        </div>
        <div class='photo-grid-item'>
          <img src='images/two.svg'/>
        </div>
        <div class='photo-grid-item'>
          <img src='images/three.svg'/>
        </div>
      </div>
    </div>
  </body>
</html>
HTML

Le CSS ci-dessous devrait vous paraître familier:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  display: flex;
  justify-content: center;
  color: #fff;
  background-color: #5995DA;  /* Bleu */
  padding: 20px 0;
}

.menu {
  border: 1px solid #fff;  /* Pour debbugage */
  width: 900px;
  display: flex;
  justify-content: space-around;
}

.links {
  border: 1px solid #fff;  /* For debugging */
  display: flex;
  justify-content: flex-end;
}

.login {
  margin-left: 20px;
}

.header-container {
  color: #5995DA;
  background-color: #D6E9FE;
  display: flex;
  justify-content: center;
}

.header {
  width: 900px;
  height: 300px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.photo-grid-container {
  display: flex;
  justify-content: center;
}

.photo-grid {
  width: 900px;
  display: flex;
  justify-content: flex-start;
}

.photo-grid-item {
  border: 1px solid #fff;
  width: 300px;
  height: 300px;
}
CSS

Cela fonctionne comme prévu, mais regardez ce qui se passe lorsque nous ajoutons plus d’éléments que ne peuvent être contenu dans le conteneur flexible. Insérez deux photos supplémentaires dans la .photo-grid

<!DOCTYPE html>
<html lang='fr'>
  <head>
    <meta charset='UTF-8'/>
    <title>Une page Web</title>
    <link rel='stylesheet' href='styles.css'/>
  </head>
  <body>
    <div class='menu-container'>
      <div class='menu'>
        <div class='date'>14 Octobre 2017</div>
        <div class='links'>
          <div class='signup'>S'inscrire</div>
          <div class='login'>Connexion</div>
        </div>  
      </div>
    </div>
    <div class='header-container'>
      <div class='header'>
        <div class='subscribe'>Subscribe ▾</div>
        <div class='logo'><img src='images/awesome-logo.svg'/></div>
        <div class='social'><img src='images/social-icons.svg'/></div>
      </div>
    </div>
    <div class='photo-grid-container'>
      <div class='photo-grid'>
        <div class='photo-grid-item first-item'>
          <img src='images/one.svg'/>
        </div>
        <div class='photo-grid-item'>
          <img src='images/two.svg'/>
        </div>
        <div class='photo-grid-item'>
          <img src='images/three.svg'/>
        </div>
        <div class='photo-grid-item'>
          <img src='images/four.svg'/>
        </div>
        <div class='photo-grid-item last-item'>
          <img src='images/five.svg'/>
        </div>
      </div>
    </div>
  </body>
</html>
HTML

Par défaut, ils dépassent du bord de la page:

Si vous essayez de créer une bannière qui permet à l’utilisateur de parcourir horizontalement un groupe de photos, il se peut que ce soit le comportement souhaité, mais ce n’est pas ce que nous voulons dans notre exemple. L’ajout de la propriété flex-wrap oblige les éléments qui ne tiennent pas dans la largeur du conteneur a passer à la ligne suivante:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  display: flex;
  justify-content: center;
  color: #fff;
  background-color: #5995DA;  /* Bleu */
  padding: 20px 0;
}

.menu {
  border: 1px solid #fff;  /* Pour debbugage */
  width: 900px;
  display: flex;
  justify-content: space-around;
}

.links {
  border: 1px solid #fff;  /* For debugging */
  display: flex;
  justify-content: flex-end;
}

.login {
  margin-left: 20px;
}

.header-container {
  color: #5995DA;
  background-color: #D6E9FE;
  display: flex;
  justify-content: center;
}

.header {
  width: 900px;
  height: 300px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.photo-grid-container {
  display: flex;
  justify-content: center;
}

.photo-grid {
  width: 900px;
  display: flex;
  justify-content: flex-start;
  flex-wrap: wrap;
}

.photo-grid-item {
  border: 1px solid #fff;
  width: 300px;
  height: 300px;
}
CSS

Maintenant, nos éléments flex se comportent comme des boîtes flottantes, sauf que Flexbox nous donne plus de contrôle sur la façon dont les éléments « supplémentaires » sont alignés dans la dernière ligne via la propriété justify-content. Par exemple, la dernière ligne est actuellement alignée à gauche. Essayez de la centrer en mettant à jour notre règle .photo-grid, de la manière suivante:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  display: flex;
  justify-content: center;
  color: #fff;
  background-color: #5995DA;  /* Bleu */
  padding: 20px 0;
}

.menu {
  border: 1px solid #fff;  /* Pour debbugage */
  width: 900px;
  display: flex;
  justify-content: space-around;
}

.links {
  border: 1px solid #fff;  /* For debugging */
  display: flex;
  justify-content: flex-end;
}

.login {
  margin-left: 20px;
}

.header-container {
  color: #5995DA;
  background-color: #D6E9FE;
  display: flex;
  justify-content: center;
}

.header {
  width: 900px;
  height: 300px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.photo-grid-container {
  display: flex;
  justify-content: center;
}

.photo-grid {
  width: 900px;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
}

.photo-grid-item {
  border: 1px solid #fff;
  width: 300px;
  height: 300px;
}
CSS

Obtenir ce résultat avec des dispositions basées sur les « float » est terriblement compliqué.

Direction du conteneur flex

Le terme « Direction » se réfère à savoir si un conteneur rend ses objets horizontalement ou verticalement. Jusqu’à présent, tous les conteneurs que nous avons vus utilisent la direction horizontale par défaut, ce qui signifie que les éléments sont dessinés l’un après l’autre dans la même rangée avant de passer à la colonne suivante lorsqu’ils manquent d’espace.

L’une des caractéristiques les plus interessantes de Flexbox est sa capacité à transformer des lignes en colonnes en utilisant une seule ligne de CSS. Essayez d’ajouter la propriété de flex-direction suivante à notre règle .photo-grid :

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  display: flex;
  justify-content: center;
  color: #fff;
  background-color: #5995DA;  /* Bleu */
  padding: 20px 0;
}

.menu {
  border: 1px solid #fff;  /* Pour debbugage */
  width: 900px;
  display: flex;
  justify-content: space-around;
}

.links {
  border: 1px solid #fff;  /* For debugging */
  display: flex;
  justify-content: flex-end;
}

.login {
  margin-left: 20px;
}

.header-container {
  color: #5995DA;
  background-color: #D6E9FE;
  display: flex;
  justify-content: center;
}

.header {
  width: 900px;
  height: 300px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.photo-grid-container {
  display: flex;
  justify-content: center;
}

.photo-grid {
  width: 900px;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  flex-direction: column;
}

.photo-grid-item {
  border: 1px solid #fff;
  width: 300px;
  height: 300px;
}
CSS

Cela modifie la valeur par défaut (row) de la direction du conteneur. Au lieu d’une grille, notre page dispose maintenant d’une seule colonne verticale:

Une des idées clés du Responsive Design est de présenter le même balisage HTML aux utilisateurs mobiles et de bureau. Cela présente un problème, car la plupart des mises en page mobiles sont sur une seule colonne, tandis que la plupart des mises en page de bureau empilent les éléments horizontalement. Vous pouvez imaginer comment de la propriété flex-direction est efficace lorsque nous voulons fabriqué une mise en page responsive.

considérations relatives à l’alignement

Notez que la colonne est aligné sur le côté gauche de son conteneur flexible malgré notre propriété justify-content: center;. Lorsque vous faites pivoter le sens d’un conteneur, vous faites également pivoter la direction de la propriété justify-content. Elle se réfère maintenant à l’alignement vertical du conteneur, et non à son alignement horizontal.

Pour centrer horizontalement notre colonne, nous devons définir une propriété align-items à notre selecteur .photo-grid :

.photo-grid { /* … */ flex-direction: column; align-items: center; /* Ajouter ceci */ }

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  display: flex;
  justify-content: center;
  color: #fff;
  background-color: #5995DA;  /* Bleu */
  padding: 20px 0;
}

.menu {
  border: 1px solid #fff;  /* Pour debbugage */
  width: 900px;
  display: flex;
  justify-content: space-around;
}

.links {
  border: 1px solid #fff;  /* For debugging */
  display: flex;
  justify-content: flex-end;
}

.login {
  margin-left: 20px;
}

.header-container {
  color: #5995DA;
  background-color: #D6E9FE;
  display: flex;
  justify-content: center;
}

.header {
  width: 900px;
  height: 300px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.photo-grid-container {
  display: flex;
  justify-content: center;
}

.photo-grid {
  width: 900px;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  flex-direction: column;
  align-items: center; 
}

.photo-grid-item {
  border: 1px solid #fff;
  width: 300px;
  height: 300px;
}
CSS

Ordre dans un conteneur flex

Jusqu’à présent, il y avait une corrélation étroite entre l’ordre de nos éléments HTML et la façon dont les boîtes sont rendues dans une page Web. Avec les flotteurs ou les techniques de flexbox que nous avons vues jusqu’à présent, la seule façon de faire apparaître une boîte avant ou après une autre consiste à changer le balisage HTML sous-jacent. C’est sur le point de changer.

La propriété de flex-direction vous offre également le contrôle de l’ordre dans lequel les éléments apparaissent via les valeurs column-reverse et row-reverse. Pour voir cela en action, transformons notre colonne en une grille, mais cette fois-ci, nous inversons l’ordre des éléments:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  display: flex;
  justify-content: center;
  color: #fff;
  background-color: #5995DA;  /* Bleu */
  padding: 20px 0;
}

.menu {
  border: 1px solid #fff;  /* Pour debbugage */
  width: 900px;
  display: flex;
  justify-content: space-around;
}

.links {
  border: 1px solid #fff;  /* For debugging */
  display: flex;
  justify-content: flex-end;
}

.login {
  margin-left: 20px;
}

.header-container {
  color: #5995DA;
  background-color: #D6E9FE;
  display: flex;
  justify-content: center;
}

.header {
  width: 900px;
  height: 300px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.photo-grid-container {
  display: flex;
  justify-content: center;
}

.photo-grid {
  width: 900px;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  flex-direction: row-reverse;  /* <--- C'est cool non ? */
}

.photo-grid-item {
  border: 1px solid #fff;
  width: 300px;
  height: 300px;
}
CSS

Les deux lignes sont maintenant rendues de droite à gauche plutôt que de gauche à droite. Mais, notez que ça ne change l’ordre des élément qu’au sein d’une ligne: la première ligne ne démarre pas à 5, elle commence à 3. Ceci est un comportement utile pour beaucoup de « Design Pattern » La valeur column-reverse en particulier s’ouvre beaucoup d’option pour les mises en page mobiles). Nous allons apprendre à être encore plus « flexible » dans la section suivante.

Réorganiser les éléments depuis une feuille de style est une avancée importante. Avant Flexbox, les développeurs web ont dû recourir à des hacks JavaScript pour accomplir ce genre de chose. Cependant, n’abusez pas de ces nouvelles capacités. Comme nous avons discuté dans le tout premier chapitre de ce tutoriel, vous devez toujours séparer le contenu de la présentation. Changer l’ordre des éléments comme on le fait ici est purement présentatif: votre HTML devrait avoir du sens sans que ces styles ne soient appliqués.

Ordre des éléments flex

Tout ce chapitre portait sur le positionnement des éléments flexibles à travers leurs conteneurs parent , mais il est également possible de manipuler les éléments individuels. Le reste de ce chapitre va changer de point du vu des conteneurs flex vers les éléments qu’ils contiennent.

L’ajout d’une propriété de order à un élément flexible définit son ordre dans le conteneur sans affecter les éléments environnants. Sa valeur par défaut est 0, et l’augmentation ou la diminution de celle-ci déplace l’élément vers la droite ou la gauche, respectivement.

Cela peut être utilisé, par exemple, pour échanger l’ordre des éléments .first-item et .last-item dans notre grille. Nous devrions également modifier la valeur row-reverse de la section précédente en row pour pouvoir voir nos modifications:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  display: flex;
  justify-content: center;
  color: #fff;
  background-color: #5995DA;  /* Bleu */
  padding: 20px 0;
}

.menu {
  border: 1px solid #fff;  /* Pour debbugage */
  width: 900px;
  display: flex;
  justify-content: space-around;
}

.links {
  border: 1px solid #fff;  /* For debugging */
  display: flex;
  justify-content: flex-end;
}

.login {
  margin-left: 20px;
}

.header-container {
  color: #5995DA;
  background-color: #D6E9FE;
  display: flex;
  justify-content: center;
}

.header {
  width: 900px;
  height: 300px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.photo-grid-container {
  display: flex;
  justify-content: center;
}

.photo-grid {
  width: 900px;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  flex-direction: row;
  align-items: center;
}

.photo-grid-item {
  border: 1px solid #fff;
  width: 300px;
  height: 300px;
}

.first-item {
  order: 1;
}

.last-item {
  order: -1;
}
CSS

Contrairement au valeur row-reverse et column-reverse sur un conteneur flexible, order fonctionne au travers des frontières lignes / colonnes. Le code ci-dessus va changer nos premier et dernier éléments, même s’ils apparaissent sur des lignes différentes.

Alignement des éléments flex

Nous pouvons faire de même avec l’alignement vertical. Et si nous voulions que ce lien d’inscription et ces icônes sociales apparaissent au bas de l’en-tête au lieu du centre? Npus pouvons les aligner individuellement! C’est là que la propriété align-self rentre en jeux. En l’ajoutant à un élément flexible, elle remplace la valeur d’align-items de son conteneur:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  display: flex;
  justify-content: center;
  color: #fff;
  background-color: #5995DA;  /* Bleu */
  padding: 20px 0;
}

.menu {
  border: 1px solid #fff;  /* Pour debbugage */
  width: 900px;
  display: flex;
  justify-content: space-around;
}

.links {
  border: 1px solid #fff;  /* For debugging */
  display: flex;
  justify-content: flex-end;
}

.login {
  margin-left: 20px;
}

.header-container {
  color: #5995DA;
  background-color: #D6E9FE;
  display: flex;
  justify-content: center;
}

.header {
  width: 900px;
  height: 300px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.photo-grid-container {
  display: flex;
  justify-content: center;
}

.photo-grid {
  width: 900px;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  flex-direction: row;
  align-items: center;
}

.photo-grid-item {
  border: 1px solid #fff;
  width: 300px;
  height: 300px;
}

.first-item {
  order: 1;
}

.last-item {
  order: -1;
}

.social,
.subscribe {
  align-self: flex-end;
  margin-bottom: 20px;
}
CSS

Cela devrait envoyer ces éléments au bas du .header comme sur l’image ci-dessous.

Vous pouvez aligner les éléments de différente manière en utilisant les mêmes valeurs que la propriété align-items:

baseline

center

flex-start   (top)

flex-end      (bottom)

stretch

Élément flexible

Tous nos exemples ont tourné autour d’éléments avec des largeurs définies. Cela nous a permis de nous concentrer sur les aspects de positionnement de flexbox, mais cela signifie aussi que nous ignorons sa nature éponyme de «boîte souple». Les éléments Flex sont flexibles : ils peuvent se rétrécir et s’étirer pour correspondre à la largeur de leurs conteneurs.

La propriété flex définit la largeur des éléments individuels dans un conteneur flexible. Ou, plus précisément, il leur permet d’avoir des largeurs flexibles. Il fonctionne comme un coefficient qui indique au conteneur flexible comment distribuer de l’espace supplémentaire à chaque élément. Par exemple, un élément avec une valeur flex de 2 augmentera deux fois plus vite que les éléments avec la valeur par défaut de 1 .

Tout d’abord, nous avons besoin d’un pied de page en HTML pour pouvoir expérimenter cette technique. Placer ce code après .photo-grid-container :

<!DOCTYPE html>
<html lang='fr'>
  <head>
    <meta charset='UTF-8'/>
    <title>Une page Web</title>
    <link rel='stylesheet' href='styles.css'/>
  </head>
  <body>
    <div class='menu-container'>
      <div class='menu'>
        <div class='date'>14 Octobre 2017</div>
        <div class='links'>
          <div class='signup'>S'inscrire</div>
          <div class='login'>Connexion</div>
        </div>  
      </div>
    </div>
    <div class='header-container'>
      <div class='header'>
        <div class='subscribe'>Subscribe ▾</div>
        <div class='logo'><img src='images/awesome-logo.svg'/></div>
        <div class='social'><img src='images/social-icons.svg'/></div>
      </div>
    </div>
    <div class='photo-grid-container'>
      <div class='photo-grid'>
        <div class='photo-grid-item first-item'>
          <img src='images/one.svg'/>
        </div>
        <div class='photo-grid-item'>
          <img src='images/two.svg'/>
        </div>
        <div class='photo-grid-item'>
          <img src='images/three.svg'/>
        </div>
        <div class='photo-grid-item'>
          <img src='images/four.svg'/>
        </div>
        <div class='photo-grid-item last-item'>
          <img src='images/five.svg'/>
        </div>
      </div>
    </div>
    <div class='footer'>
      <div class='footer-item footer-one'></div>
      <div class='footer-item footer-two'></div>
      <div class='footer-item footer-three'></div>
    </div>
  </body>
</html>
HTML

Puis, un peu de CSS:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  display: flex;
  justify-content: center;
  color: #fff;
  background-color: #5995DA;  /* Bleu */
  padding: 20px 0;
}

.menu {
  border: 1px solid #fff;  /* Pour debbugage */
  width: 900px;
  display: flex;
  justify-content: space-around;
}

.links {
  border: 1px solid #fff;  /* For debugging */
  display: flex;
  justify-content: flex-end;
}

.login {
  margin-left: 20px;
}

.header-container {
  color: #5995DA;
  background-color: #D6E9FE;
  display: flex;
  justify-content: center;
}

.header {
  width: 900px;
  height: 300px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.photo-grid-container {
  display: flex;
  justify-content: center;
}

.photo-grid {
  width: 900px;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  flex-direction: row;
  align-items: center;
}

.photo-grid-item {
  border: 1px solid #fff;
  width: 300px;
  height: 300px;
}

.first-item {
  order: 1;
}

.last-item {
  order: -1;
}

.social,
.subscribe {
  align-self: flex-end;
  margin-bottom: 20px;
}

.footer {
  display: flex;
  justify-content: space-between;
}

.footer-item {
  border: 1px solid #fff;
  background-color: #D6E9FE;
  height: 200px;
  flex: 1;
}
CSS

La ligne flex: 1; indique aux éléments de s’étirer pour correspondre à la largeur de .footer. Étant donné qu’ils ont tous le même « coefficient », ils s’élargiront de manière égale:

Accroitre le coefficeint de l’un des éléments le fait s’élargir de manière plus rapide que les autres. Par exemple, la règle suivante fait s’accroitre le troisième élément deux fois plus vite que les autres:

.footer-three {
  flex: 2;
}
CSS

Comparez cela avec la propriété justify-content, qui distribue un espace supplémentaire entre les éléments. C’est similaire, mais maintenant nous distribuons cet espace dans les éléments eux-mêmes. Le résultat est un contrôle total sur la façon dont les éléments flexibles s’insèrent dans leurs conteneurs.

Largeur d’un élément statique

Nous pouvons même mélanger et combiner des boîtes flexibles avec d’autres à largeur fixe. La propriété flex: initial respecte la largeur (width) initiale de l’objet. Cela nous permet de combiner des boîtes statiques et flexibles de manière complexe.

Nous allons faire en sorte que notre pied de page se comporte comme le schéma ci-dessus. L’élément central est flexible, mais ceux de chaque côté sont toujours de la même taille. Tout ce que nous devons faire est d’ajouter la règle suivante à notre feuille de style:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  display: flex;
  justify-content: center;
  color: #fff;
  background-color: #5995DA;  /* Bleu */
  padding: 20px 0;
}

.menu {
  border: 1px solid #fff;  /* Pour debbugage */
  width: 900px;
  display: flex;
  justify-content: space-around;
}

.links {
  border: 1px solid #fff;  /* For debugging */
  display: flex;
  justify-content: flex-end;
}

.login {
  margin-left: 20px;
}

.header-container {
  color: #5995DA;
  background-color: #D6E9FE;
  display: flex;
  justify-content: center;
}

.header {
  width: 900px;
  height: 300px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.photo-grid-container {
  display: flex;
  justify-content: center;
}

.photo-grid {
  width: 900px;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  flex-direction: row;
  align-items: center;
}

.photo-grid-item {
  border: 1px solid #fff;
  width: 300px;
  height: 300px;
}

.first-item {
  order: 1;
}

.last-item {
  order: -1;
}

.social,
.subscribe {
  align-self: flex-end;
  margin-bottom: 20px;
}

.footer {
  display: flex;
  justify-content: space-between;
}

.footer-item {
  border: 1px solid #fff;
  background-color: #D6E9FE;
  height: 200px;
  flex: 1;
}

.footer-one,
.footer-three {
  background-color: #5995DA;
  flex: initial;
  width: 300px;
}
CSS

Sans cette propriété flex: initial;, la déclaration serait héritée de la règle .footer-item, ce qui entraînerait la non-application de la propriété largeur de l’élément. La valeur initial répare cela, et nous obtenons une disposition flexible qui contient également des éléments à largeur fixe. Lorsque vous redimensionnez la fenêtre du navigateur, vous verrez que seule la boîte du milieu dans le pied de page est redimensionnée.

Il s’agit d’une disposition assez courante, et pas seulement dans les pieds de page, non plus. Par exemple, de nombreux sites Web ont une barre latérale à largeur fixe (ou plusieurs barres latérales) et un bloc de contenu flexible contenant le texte principal de la page. Il s’agit essentiellement d’une version plus grande du pied de page que nous venons de créer.

Les éléments flex et les marges automatiques

Les marges automatiques dans flexbox sont spéciales. Elles peuvent être utilisés comme alternative à une <div> supplémentaire lors de l’alignement d’un groupe d’éléments à gauche ou à droite d’un conteneur. Pensez aux marges automatiques en tant que «séparateur» pour les éléments flexibles dans un même conteneur.

Testons cela en réécrivant nos éléments Flex dans .menu pour que cela ressemble à ça:

<!DOCTYPE html>
<html lang='fr'>
  <head>
    <meta charset='UTF-8'/>
    <title>Une page Web</title>
    <link rel='stylesheet' href='styles.css'/>
  </head>
  <body>
    <div class='menu-container'>
      <div class='menu'>
        <div class='date'>Aug 14, 2016</div>
        <div class='signup'>Sign Up</div>
        <div class='login'>Login</div>
      </div>
    </div>
    <div class='header-container'>
      <div class='header'>
        <div class='subscribe'>Subscribe ▾</div>
        <div class='logo'><img src='images/awesome-logo.svg'/></div>
        <div class='social'><img src='images/social-icons.svg'/></div>
      </div>
    </div>
    <div class='photo-grid-container'>
      <div class='photo-grid'>
        <div class='photo-grid-item first-item'>
          <img src='images/one.svg'/>
        </div>
        <div class='photo-grid-item'>
          <img src='images/two.svg'/>
        </div>
        <div class='photo-grid-item'>
          <img src='images/three.svg'/>
        </div>
        <div class='photo-grid-item'>
          <img src='images/four.svg'/>
        </div>
        <div class='photo-grid-item last-item'>
          <img src='images/five.svg'/>
        </div>
      </div>
    </div>
    <div class='footer'>
      <div class='footer-item footer-one'></div>
      <div class='footer-item footer-two'></div>
      <div class='footer-item footer-three'></div>
    </div>
  </body>
</html>
HTML

En rechargeant la page vous devrait voir les éléments également répartis dans notre menu, tout comme au début du chapitre. Nous pouvons répliquer la disposition souhaitée en collant une marge automatique entre les éléments que nous voulons séparer, de la manière suivante:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  display: flex;
  justify-content: center;
  color: #fff;
  background-color: #5995DA;  /* Bleu */
  padding: 20px 0;
}

.menu {
  border: 1px solid #fff;  /* Pour debbugage */
  width: 900px;
  display: flex;
  justify-content: space-around;
}

.links {
  border: 1px solid #fff;  /* For debugging */
  display: flex;
  justify-content: flex-end;
}

.login {
  margin-left: 20px;
}

.header-container {
  color: #5995DA;
  background-color: #D6E9FE;
  display: flex;
  justify-content: center;
}

.header {
  width: 900px;
  height: 300px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.photo-grid-container {
  display: flex;
  justify-content: center;
}

.photo-grid {
  width: 900px;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  flex-direction: row;
  align-items: center;
}

.photo-grid-item {
  border: 1px solid #fff;
  width: 300px;
  height: 300px;
}

.first-item {
  order: 1;
}

.last-item {
  order: -1;
}

.social,
.subscribe {
  align-self: flex-end;
  margin-bottom: 20px;
}

.footer {
  display: flex;
  justify-content: space-between;
}

.footer-item {
  border: 1px solid #fff;
  background-color: #D6E9FE;
  height: 200px;
  flex: 1;
}

.footer-one,
.footer-three {
  background-color: #5995DA;
  flex: initial;
  width: 300px;
}

.signup {
  margin-left: auto;
}
CSS

Les marges automatiques « mangent » tout l’espace supplémentaire dans un conteneur flexible, donc, au lieu de distribuer des éléments de manière égale, cela déplace la .signup et les éléments suivants ( .login ) sur le côté droit du conteneur. Cela vous donnera exactement la même disposition que nous avions auparavant, mais sans la <div> supplémentaire. Parfois, il est agréable de garder votre HTML le plus simple possible.

Résumé

Flexbox gave us a ton of amazing new tools for laying out a web page. Compare these techniques to what we were able to do with floats, and it should be pretty clear that flexbox is a cleaner option for laying out modern websites: Flexbox nous a donné une tonne de nouveaux outils étonnants pour la mise en page d’une page Web. Comparez ces techniques à ce que nous avons pu faire avec les flotteurs, et il devrait être assez clair que flexbox est une bien meilleure option pour la mise en page de sites Web modernes:

  • Utilisez display: flex; pour créer un conteneur flexible.
  • Utilisez justify-content pour définir l’alignement horizontal des éléments.
  • Utilisez align-items pour définir l’alignement vertical des éléments.
  • Utilisez flex-direction si vous avez besoin de colonnes au lieu de lignes.
  • Utilisez row-reverse ou column-reverse pour changer le sens d’affichage des éléments.
  • Utilisez order pour personnaliser l’ordre des éléments individuels.
  • Utilisez align-self pour aligner verticalement les éléments individuels.
  • Utilisez flex pour créer des boîtes flexibles qui peuvent être étirées et rétrécis.

N’oubliez pas que ces propriétés flexbox ne sont qu’un moyen pour dire aux navigateurs comment organiser un tas d’éléments HTML. La partie difficile n’est pas d’écrire le code HTML et CSS, il s’agit de concevoir (sur un morceau de papier), le comportement de toutes les cases (ou boîtes) nécessaires pour créer une mise en page donnée.

Quand un concepteur vous apporte une modélisation à mettre en œuvre, votre première tâche consiste à dessiner un ensemble de boîtes et à déterminer comment elles sont censées s’empiler, s’étirer et ou rétrécir pour obtenir la mise en page souhaitée. Une fois que vous avez terminé, il devrait être assez facile de la coder en utilisant ces nouvelles techniques Flexbox.

Le mode de mise en page Flexbox devrait être utilisé pour la plupart de vos pages Web, mais il y a des choses dans lesquelles il n’est pas aussi bon, comme ajuster précisément la positions des éléments et les empêcher d’interagir avec le reste de la page. Après avoir traité ces techniques avancées de positionnement dans le prochain chapitre, vous serez un expert en positionnement HTML et CSS.

error: Content is protected !!