web-dev-qa-db-fra.com

Flexbox: 4 éléments par ligne

J'utilise une boîte souple pour afficher 8 éléments qui seront redimensionnés de manière dynamique avec ma page. Comment puis-je le forcer à diviser les éléments en deux rangées? (4 par rangée)?

Voici un extrait pertinent:

(Ou si vous préférez jsfiddle - http://jsfiddle.net/vivmaha/oq6prk1p/2/ )

.parent-wrapper {
  height: 100%;
  width: 100%;
  border: 1px solid black;
}
.parent {
  display: flex;
  font-size: 0;
  flex-wrap: wrap;
  margin: -10px 0 0 -10px;
}
.child {
  display: inline-block;
  background: blue;
  margin: 10px 0 0 10px;
  flex-grow: 1;
  height: 100px;
}
<body>
  <div class="parent-wrapper">
    <div class="parent">
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
    </div>
  </div>
</body>
183
Vivek Maharajh

Vous avez flex-wrap: wrap sur le conteneur. C'est bien, car elle remplace la valeur par défaut, qui est nowrap ( source ). C’est la raison pour laquelle les éléments ne s’emballent pas pour former une grille dans certains cas .

Dans ce cas, le problème principal est flex-grow: 1 sur les éléments flex.

La propriété flex-grow ne redimensionne pas les éléments flex. Sa tâche est de distribuer de l’espace libre dans le conteneur ( source ). Ainsi, peu importe la taille de l'écran, chaque élément recevra une partie proportionnelle de l'espace libre sur la ligne.

Plus précisément, votre conteneur contient huit éléments flexibles. Avec flex-grow: 1, chacun reçoit 1/8 de l'espace libre sur la ligne. Puisqu'il n'y a pas de contenu dans vos articles, ils peuvent être réduits à zéro et ne seront jamais emballés.

La solution consiste à définir une largeur sur les éléments. Essaye ça:

.parent {
  display: flex;
  flex-wrap: wrap;
}

.child {
  flex: 1 0 21%; /* explanation below */
  margin: 5px;
  height: 100px;
  background-color: blue;
}
<div class="parent">
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>

Avec flex-grow: 1 défini dans le raccourci flex, il n'est pas nécessaire que flex-basis soit égal à 25%, ce qui donnerait en réalité trois éléments par ligne en raison des marges.

Puisque flex-grow utilisera de l'espace libre sur la ligne, il ne faut que flex-basis suffisamment grand pour appliquer un retour à la ligne. Dans ce cas, avec flex-basis: 21%, il y a beaucoup d'espace pour les marges, mais jamais assez pour un cinquième élément.

257
Michael_B

Ajoutez une largeur aux éléments .child. Personnellement, je voudrais utiliser des pourcentages sur le margin-left si vous voulez l'avoir toujours 4 par ligne.

DÉMO

.child {
    display: inline-block;
    background: blue;
    margin: 10px 0 0 2%;
    flex-grow: 1;
    height: 100px;
    width: calc(100% * (1/4) - 10px - 1px);
}
94
dowomenfart

Voici une autre approche.

Vous pouvez le faire de cette façon aussi:

.parent{
  display: flex;
  flex-wrap: wrap;
}

.child{
  width: 25%;
  box-sizing: border-box;
}

Exemple: https://codepen.io/capynet/pen/WOPBBm

Et un exemple plus complet: https://codepen.io/capynet/pen/JyYaba

36
Capy
<style type="text/css">
.parent{
    display: flex;
    flex-wrap: wrap;
}
.parent .child{
    flex: 1 1 25%;
}
</style>    
<div class="parent">
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
    </div>

J'espère que ça aide. pour plus de détails, vous pouvez suivre ceci lien

11
Muddasir Abbas

Je le ferais comme ceci en utilisant des marges négatives et calc pour les gouttières:

.parent {
  display: flex;
  flex-wrap: wrap;
  margin-top: -10px;
  margin-left: -10px;
}

.child {
  width: calc(25% - 10px);
  margin-left: 10px;
  margin-top: 10px;
}

Démo: https://jsfiddle.net/9j2rvom4/


Méthode de grille CSS alternative:

.parent {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}

Démo: https://jsfiddle.net/jc2utfs3/

9
shanomurphy
.parent-wrapper {
        height: 100%;
        width: 100%;
        border: 1px solid black;
}
        .parent {
        display: flex;
        font-size: 0;
        flex-wrap: wrap;
        margin-right: -10px;
        margin-bottom: -10px;
}
        .child {
        background: blue;
        height: 100px;
        flex-grow: 1;
        flex-shrink: 0;
        flex-basis: calc(25% - 10px);
}
        .child:nth-child(even) {
        margin: 0 10px 10px 10px;
        background-color: Lime;
}
        .child:nth-child(odd) {
        background-color: orange; 
}
<!DOCTYPE html>
<html lang="en">
<head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style type="text/css">

        </style>
</head>
<body>
  <div class="parent-wrapper">
    <div class="parent">
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
    </div>
  </div>
</body>
</html>

;)

2

Je crois que cet exemple est plus simple et plus facile à comprendre puis @dowomenfart.

.child {
    display: inline-block;
    margin: 0 1em;
    flex-grow: 1;
    width: calc(25% - 2em);
}

Ceci effectue les mêmes calculs de largeur en coupant directement à la viande. Le calcul est beaucoup plus facile et em est le nouvelle norme en raison de son évolutivité et de sa convivialité pour les mobiles.

1
Joseph Cho

Flexibles + marge négative

Pourquoi flex contre display: inline-block?

Pourquoi une marge négative?

Soit vous utilisez SCSS ou CSS-in-JS pour les cas Edge (c’est-à-dire le premier élément de la colonne), soit vous définissez une marge par défaut et vous en débarrassez plus tard.

La mise en oeuvre

https://codepen.io/zurfyx/pen/BaBWpja

<div class="outerContainer">
    <div class="container">
        <div class="elementContainer">
            <div class="element">
            </div>
        </div>
        ...
    </div>
</div>
:root {
  --columns: 2;
  --betweenColumns: 20px; /* This value is doubled when no margin collapsing */
}

.outerContainer {
    overflow: hidden; /* Hide the negative margin */
}

.container {
    background-color: grey;
    display: flex;
    flex-wrap: wrap;
    margin: calc(-1 * var(--betweenColumns));
}

.elementContainer {
    display: flex; /* To prevent margin collapsing */
    width: calc(1/var(--columns) * 100% - 2 * var(--betweenColumns));
    margin: var(--betweenColumns);
}

.element {
    display: flex;
    border: 1px solid red;
    background-color: yellow;
    width: 100%;
    height: 42px;
}
0
zurfyx