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>
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.
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.
.child {
display: inline-block;
background: blue;
margin: 10px 0 0 2%;
flex-grow: 1;
height: 100px;
width: calc(100% * (1/4) - 10px - 1px);
}
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
<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
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/
.parent {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-column-gap: 10px;
grid-row-gap: 10px;
}
.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>
;)
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.
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.
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;
}