Rangées de hauteur égale dans un conteneur flexible
Comme vous pouvez le voir, le list-items
dans le premier row
ont même height
. Mais les éléments du second row
ont des heights
différents. Je veux que tous les éléments aient un uniforme height
.
Est-il un moyen d'atteindre cet objectif sans donner hauteur fixe et uniquement à l'aide de flexbox?
Voici mon code
.list {
display: flex;
flex-wrap: wrap;
max-width: 500px;
}
.list-item {
background-color: #ccc;
display: flex;
padding: 0.5em;
width: 25%;
margin-right: 1%;
margin-bottom: 20px;
}
.list-content {
width: 100%;
}
<ul class="list">
<li class="list-item">
<div class="list-content">
<h2>box 1</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
</div>
</li>
<li class="list-item">
<div class="list-content">
<h3>box 2</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
</div>
</li>
<li class="list-item">
<div class="list-content">
<h3>box 2</h3>
<p>Lorem ipsum dolor</p>
</div>
</li>
<li class="list-item">
<div class="list-content">
<h3>box 2</h3>
<p>Lorem ipsum dolor</p>
</div>
</li>
<li class="list-item">
<div class="list-content">
<h1>h1</h1>
</div>
</li>
</ul>
8 réponses
La réponse est non.
La raison est fournie dans la spécification flexbox:
6. Lignes Flexibles
Dans un conteneur flexible multiligne, la taille transversale de chaque ligne est la taille minimale nécessaire pour contenir les éléments flexibles sur la ligne.
En d'autres termes, lorsqu'il y a plusieurs lignes dans un conteneur flexible basé sur une ligne, la hauteur de chaque ligne (la "taille croisée") est la hauteur minimale nécessaire pour contenir les éléments flexibles sur le ligne.
Des lignes de hauteur égale, cependant, sont possibles dans la disposition de la grille CSS:
Sinon, envisagez une alternative JavaScript.
Vous pouvez l'obtenir maintenant avec display: grid
:
.list {
display: grid;
overflow: hidden;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 1fr;
grid-column-gap: 5px;
grid-row-gap: 5px;
max-width: 500px;
}
.list-item {
background-color: #ccc;
display: flex;
padding: 0.5em;
margin-bottom: 20px;
}
.list-content {
width: 100%;
}
<ul class="list">
<li class="list-item">
<div class="list-content">
<h2>box 1</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
</div>
</li>
<li class="list-item">
<div class="list-content">
<h3>box 2</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
</div>
</li>
<li class="list-item">
<div class="list-content">
<h3>box 2</h3>
<p>Lorem ipsum dolor</p>
</div>
</li>
<li class="list-item">
<div class="list-content">
<h3>box 2</h3>
<p>Lorem ipsum dolor</p>
</div>
</li>
<li class="list-item">
<div class="list-content">
<h1>h1</h1>
</div>
</li>
</ul>
Bien que la grille elle-même ne soit pas flexbox, elle se comporte très similaire à un conteneur flexbox, et les éléments à l'intérieur de la grille peuvent être flex.
La disposition de la grille est également très pratique dans le cas où vous voulez des grilles réactives. Autrement dit, si vous voulez que la grille ait un nombre différent de colonnes par ligne, vous pouvez simplement changer grid-template-columns
:
grid-template-columns: repeat(1, 1fr); // 1 column
grid-template-columns: repeat(2, 1fr); // 2 columns
grid-template-columns: repeat(3, 1fr); // 3 columns
Et ainsi de suite...
Vous pouvez mélangez-le avec les requêtes multimédia et modifiez-le en fonction de la taille de la page.
Malheureusement, il n'y a toujours pas de support pour les requêtes container / element queries dans les navigateurs (prêts à l'emploi) pour que cela fonctionne bien avec la modification du nombre de colonnes en fonction de la taille du conteneur, pas de la taille de la page (ce serait génial à utiliser avec des composants Web réutilisables).
Plus d'informations sur la grille mise en page:
Https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout
Prise en charge de la disposition de la grille dans les navigateurs:
Non, vous ne pouvez pas y parvenir sans définir une hauteur fixe (ou en utilisant un script).
Voici 2 réponses à moi, montrant comment utiliser un script pour réaliser quelque chose comme ça:
Si vous connaissez les éléments que vous mappez, Vous pouvez accomplir ceci en faisant une ligne à la fois . Je sais que c'est une solution de contournement, mais cela fonctionne.
Pour moi j'ai eu 4 éléments par ligne, donc je l'ai divisé en deux rangées de 4 à chaque ligne height: 50%
, se débarrasser de flex-grow
ont <RowOne />
et <RowTwo />
dans a <div>
avec flex-column
. Cela fera l'affaire
<div class='flexbox flex-column height-100-percent'>
<RowOne class='flex height-50-percent' />
<RowTwo class='flex height-50-percent' />
</div>
Cela semble fonctionner dans les cas avec une hauteur parent fixe (testé dans Chrome et Firefox):
.child {
height : 100%;
overflow : hidden;
}
.parent {
display: flex;
flex-direction: column;
height: 70vh; // ! won't work unless parent container height is set
position: relative;
}
S'il n'est pas possible d'utiliser des grilles pour quelque raison, c'est peut-être la solution.
Dans votre cas, la hauteur sera calculée automatiquement, vous devez donc fournir la hauteur
utilisez ceci
.list-content{
width: 100%;
height:150px;
}
Vous pouvez le faire en fixant la hauteur de la balise " P "ou en fixant la hauteur de "list-item".
J'ai fait en fixant la hauteur de " P "
Et le débordement doit être masqué.
.list{
display: flex;
flex-wrap: wrap;
max-width: 500px;
}
.list-item{
background-color: #ccc;
display: flex;
padding: 0.5em;
width: 25%;
margin-right: 1%;
margin-bottom: 20px;
}
.list-content{
width: 100%;
}
p{height:100px;overflow:hidden;}
<ul class="list">
<li class="list-item">
<div class="list-content">
<h2>box 1</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. </p>
</div>
</li>
<li class="list-item">
<div class="list-content">
<h3>box 2</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
</div>
</li>
<li class="list-item">
<div class="list-content">
<h3>box 2</h3>
<p>Lorem ipsum dolor</p>
</div>
</li>
<li class="list-item">
<div class="list-content">
<h3>box 2</h3>
<p>Lorem ipsum dolor</p>
</div>
</li>
<li class="list-item">
<div class="list-content">
<h1>h1</h1>
</div>
</li>
</ul>
Pour la même hauteur, vous devez chage vos propriétés CSS "display". Pour plus de détail, voir l'exemple donné.
.list{
display: table;
flex-wrap: wrap;
max-width: 500px;
}
.list-item{
background-color: #ccc;
display: table-cell;
padding: 0.5em;
width: 25%;
margin-right: 1%;
margin-bottom: 20px;
}
.list-content{
width: 100%;
}
<ul class="list">
<li class="list-item">
<div class="list-content">
<h2>box 1</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. </p>
</div>
</li>
<li class="list-item">
<div class="list-content">
<h3>box 2</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
</div>
</li>
<li class="list-item">
<div class="list-content">
<h3>box 2</h3>
<p>Lorem ipsum dolor</p>
</div>
</li>
<li class="list-item">
<div class="list-content">
<h3>box 2</h3>
<p>Lorem ipsum dolor</p>
</div>
</li>
<li class="list-item">
<div class="list-content">
<h1>h1</h1>
</div>
</li>