web-dev-qa-db-fra.com

Créer une grille de maçonnerie avec flexbox (ou autre CSS)

J'aimerais obtenir un effet de grille en CSS avec des éléments qui ont tous la même largeur mais pas la hauteur. Je voudrais que l'élément en dessous soit toujours à 50px de celui du bas, peu importe ce qui va suivre.

J'ai essayé avec des flotteurs, mais ce bug. J'ai donc essayé avec Flex, mais cela ne fait toujours pas ce que je veux.

.container
  display: flex
  flex-wrap wrap
  align-content flex-start
  align-items flex-start

Ce que je voudrais:

 enter image description here

Ce que j'ai:

 enter image description here

6
Jeremy

Essayez le nouveau CSS Grid Layout :

grid-container {
  display: grid;                                                /* 1 */
  grid-auto-rows: 50px;                                         /* 2 */
  grid-gap: 10px;                                               /* 3 */
  grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));   /* 4 */
}

[short] {
  grid-row: span 1;                                             /* 5 */
  background-color: green;
}

[tall] {
  grid-row: span 2;
  background-color: crimson;
}

[taller] {
  grid-row: span 3;
  background-color: blue;
}

[tallest] {
  grid-row: span 4;
  background-color: gray;
}
<grid-container>
  <grid-item short></grid-item>
  <grid-item short></grid-item>
  <grid-item tall></grid-item>
  <grid-item tall></grid-item>
  <grid-item short></grid-item>
  <grid-item taller></grid-item>
  <grid-item short></grid-item>
  <grid-item tallest></grid-item>
  <grid-item tall></grid-item>
  <grid-item short></grid-item>
  <grid-item tallest></grid-item>
  <grid-item tall></grid-item>
  <grid-item taller></grid-item>
  <grid-item short></grid-item>
  <grid-item short></grid-item>
  <grid-item short></grid-item>
  <grid-item short></grid-item>
  <grid-item tall></grid-item>
  <grid-item short></grid-item>
  <grid-item taller></grid-item>
  <grid-item short></grid-item>
  <grid-item tall></grid-item>
  <grid-item short></grid-item>
  <grid-item tall></grid-item>
  <grid-item short></grid-item>
  <grid-item short></grid-item>
  <grid-item tallest></grid-item>
  <grid-item taller></grid-item>
  <grid-item short></grid-item>
  <grid-item tallest></grid-item>
  <grid-item tall></grid-item>
  <grid-item short></grid-item>
</grid-container>

jsFiddle demo


Comment ça marche:

  1. Établissez un conteneur de grille au niveau du bloc.
  2. La propriété grid-auto-rows définit la hauteur des lignes générées automatiquement. Dans cette grille, chaque rangée mesure 50 pixels de haut.
  3. La propriété grid-gap est un raccourci pour grid-column-gap et grid-row-gap. Cette règle définit un écart de 10 pixels entre éléments de la grille. (Cela ne s'applique pas à la zone située entre les articles et le conteneur.)
  4. La propriété grid-template-columns définit la largeur des colonnes explicitement définies.

    La notation repeat définit un modèle de répétition de colonnes (ou de lignes).

    La fonction auto-fill indique à la grille d'aligner autant de colonnes (ou de lignes) que possible sans dépasser le conteneur. (Cela peut créer un comportement similaire à celui utilisé pour modifier le flex-wrap: wrap de la présentation.)

    La fonction minmax() définit une plage de tailles minimale et maximale pour chaque colonne (ou ligne). Dans le code ci-dessus, la largeur de chaque colonne sera au minimum de 30% du conteneur et au maximum de l’espace libre disponible.

    Le frunit représente une fraction de l'espace libre dans le conteneur de la grille. C'est comparable à la propriété flex-grow de flexbox.

  5. Avec grid-row et span nous indiquons aux éléments de la grille le nombre de lignes qu'ils doivent couvrir.


Prise en charge du navigateur pour CSS Grid

  • Chrome - Prise en charge complète à compter du 8 mars 2017 (version 57)
  • Firefox - Prise en charge complète à compter du 6 mars 2017 (version 52)
  • Safari - prise en charge complète à compter du 26 mars 2017 (version 10.1)
  • Edge - prise en charge complète à compter du 16 octobre 2017 (version 16)
  • IE11 - pas de support pour les spécifications actuelles; supporte la version obsolète

Voici l'image complète: http://caniuse.com/#search=grid


fonctionnalité de superposition de grille dans Firefox:} _ Dans les outils de développement de Firefox, lorsque vous inspectez le conteneur de grille, la déclaration CSS contient une petite icône de grille. Au clic, il affiche un aperçu de votre grille sur la page.

 enter image description here

Plus de détails ici: https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Examine_grid_layouts

10
Michael_B

Je suggérerais une disposition de colonne. Il peut être facilement rendu sensible à votre goût en déclarant à la fois column-width et column-count. L'avantage par rapport à la solution d'Emonadeo (aucune infraction) est qu'il reste réactif, sans majoration supplémentaire. L'inconvénient est que les éléments sont d'abord triés en colonnes et non en lignes.

.container {
   /* min width of a single column */
   column-width: 140px;
   /* maximum amount of columns */
   column-count: 4;
   /* gap between the columns */
   column-gap: 16px;
}


.container div {
  /* important so a single div never gets distributed between columns */
  break-inside: avoid-column;

  background-color: #2C2F33;
  margin-bottom: 16px;
  color:white;
}
<div class="container">
    <div style="height: 200px">a</div>
    <div style="height: 100px">b</div>
    <div style="height: 200px">c</div>
    <div style="height: 150px">d</div>
    <div style="height: 250px">e</div>
    <div style="height: 200px">f</div>
    <div style="height: 300px">g</div>
    <div style="height: 150px">h</div>
    <div style="height: 100px">i</div>
</div>

3
Christoph

Je vous suggère de mettre chaque colonne dans un div séparé. De cette façon, flexbox ne le force pas dans une mise en page semblable à une table.

Même si j'ai utilisé des hauteurs fixes dans l'extrait de code, il devrait fonctionner de manière dynamique sans aucun problème

.container {
  display: flex;
}

.col {
  flex: 1;
}

.col div {
  background-color: #2C2F33;
  margin: 16px 8px;
}
<div class="container">
  <div class="col">
    <div style="height: 200px"></div>
    <div style="height: 100px"></div>
    <div style="height: 200px"></div>
  </div>
  <div class="col">
    <div style="height: 150px"></div>
    <div style="height: 250px"></div>
    <div style="height: 200px"></div>
  </div>
  <div class="col">
    <div style="height: 300px"></div>
    <div style="height: 150px"></div>
    <div style="height: 100px"></div>
  </div>
</div>

2
Emonadeo