Flexbox: 4 articles par ligne

j'utilise une boîte flex pour afficher 8 éléments qui seront redimensionnés dynamiquement avec ma page. Comment puis-je le forcer à diviser les éléments en deux lignes? (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>
104
demandé sur Michael_B 2015-04-09 21:47:34

7 réponses

ajouter une largeur aux éléments .child . Personnellement, j'utiliserais des pourcentages sur le margin-left si vous voulez avoir toujours 4 par rangée.

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);
}
88
répondu dowomenfart 2018-09-14 18:03:39

vous avez flex-wrap: wrap sur le container. C'est bien, parce qu'il l'emporte sur la valeur par défaut, qui est nowrap ( source ). C'est la raison pour laquelle les articles ne s'emballent pas pour former une grille dans certains cas .

dans ce cas, le problème principal est flex-grow: 1 sur les articles flex.

la propriété flex-grow ne Taille pas réellement les éléments flex. Sa mission est de distribuer gratuitement de l'espace dans le conteneur ( source ). Donc, peu importe comment petit la taille de l'écran, chaque élément de recevoir une partie proportionnelle de l'espace libre sur la ligne.

plus précisément, il y a huit articles flex dans votre conteneur. Avec flex-grow: 1 , chacun reçoit 1/8 de l'espace libre sur la ligne. Comme il n'y a pas de contenu dans vos articles, ils peuvent rétrécir à la largeur zéro et ne jamais envelopper.

La solution est de définir une largeur sur les éléments. Essayez ceci:

.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 de 25%, ce qui donnerait en fait trois articles par rangée en raison des marges.

puisque flex-grow consommera de l'espace libre sur la rangée, flex-basis doit seulement être assez grand pour appliquer un enveloppement. Dans ce cas, avec flex-basis: 21% , il y a beaucoup d'espace pour le les marges, mais jamais assez d'espace pour un cinquième élément.

99
répondu Michael_B 2018-09-01 18:51:29

voici une autre répartition.

vous pouvez l'accomplir de cette façon aussi:

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

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

échantillon: https://codepen.io/capynet/pen/WOPBBm

et un échantillon plus complet: https://codepen.io/capynet/pen/JyYaba

27
répondu Capy 2017-07-28 14:54:08
<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 aidera. pour plus de détails, vous pouvez suivre ce lien

8
répondu Muddasir Abbas 2017-08-16 10:40:38

je crois que cet exemple est plus barebones et plus facile à comprendre puis @dowomenfart.

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

cela permet d'effectuer les mêmes calculs de largeur tout en coupant directement sur la viande. Le calcul est beaucoup plus facile et em est la nouvelle norme en raison de son évolutivité et mobile-friendliness.

1
répondu Joseph Cho 2017-10-10 01:42:04

.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>

;)

0
répondu Mateus Manosso Barszcz 2018-03-31 19:33:12

Voici une autre façon sans utiliser calc() .

// 4 PER ROW
// 100 divided by 4 is 25. Let's use 21% for width, and the remainder 4% for left & right margins...
.child {
  margin: 0 2% 0 2%;
  width: 21%;
}

// 3 PER ROW
// 100 divided by 3 is 33.3333... Let's use 30% for width, and remaining 3.3333% for sides (hint: 3.3333 / 2 = 1.66666)
.child {
  margin: 0 1.66666% 0 1.66666%;
  width: 30%;
}

// and so on!

C'est tout. Vous pouvez obtenir la fantaisie avec les dimensions pour obtenir un plus esthétique tailles, mais c'est l'idée.

-12
répondu williamle8300 2017-07-03 15:39:20