Równe rzędy wysokości w elastycznym pojemniku


91

Jak widać, list-itemspierwsze rowmają takie same height. Ale przedmioty w drugiej rowmają różne heights. Chcę, żeby wszystkie przedmioty miały mundur height.

Czy jest jakiś sposób na osiągnięcie tego bez podawania stałej wysokości i tylko przy użyciu Flexbox ?

wprowadź opis obrazu tutaj

Tutaj jest mój 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>


Jednym ze sposobów jest ustawienie wysokości elementu, który może mieć różną wysokość
onmyway133

Odpowiedzi:


79

Odpowiedź brzmi nie.

Powód jest podany w specyfikacji flexbox:

6. Linie Flex

W wieloliniowym kontenerze elastycznym rozmiar krzyża każdej linii jest minimalnym rozmiarem niezbędnym do umieszczenia elementów elastycznych w linii.

Innymi słowy, gdy w kontenerze elastycznym opartym na wierszach znajduje się wiele wierszy, wysokość każdego wiersza („rozmiar krzyża”) jest minimalną wysokością niezbędną do umieszczenia elementów elastycznych w wierszu.

Jednak w układzie siatki CSS możliwe są wiersze o jednakowej wysokości:

W przeciwnym razie rozważ alternatywę JavaScript.


Czy obecnie korzystanie z siatki CSS jest bezpieczne?
Alexander Kim

40

Możesz to teraz osiągnąć dzięki 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>

Chociaż sama siatka nie jest flexboxem, zachowuje się bardzo podobnie do kontenera flexbox , a elementy wewnątrz siatki mogą być elastyczne .

Układ siatki jest również bardzo przydatny w przypadku, gdy potrzebujesz elastycznych siatek. Oznacza to, że jeśli chcesz, aby siatka miała inną liczbę kolumn w wierszu, możesz po prostu zmienić 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

i tak dalej...

Możesz łączyć to z zapytaniami o media i zmieniać w zależności od rozmiaru strony.

Niestety nadal nie ma obsługi zapytań kontenerów / zapytań o elementy w przeglądarkach (po wyjęciu z pudełka), aby działały dobrze przy zmianie liczby kolumn zgodnie z rozmiarem kontenera, a nie rozmiarem strony (byłoby to świetne w użyciu z komponentami sieciowymi wielokrotnego użytku).

Więcej informacji o układzie siatki:

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout

Obsługa układu siatki w różnych przeglądarkach:

https://caniuse.com/#feat=css-grid


To jest podejście typu „można zrobić”, które lubię! Dziękuję również za działający przykład
hananamar


0

Jeśli znasz elementy, przez które mapujesz, możesz to zrobić, wykonując jeden wiersz na raz . Wiem, że to obejście, ale działa.

Dla mnie miałem 4 elementy w rzędzie, więc podzieliłem to na dwa rzędy po 4 w każdym rzędzie height: 50%, pozbyłem się flex-grow, mam <RowOne />i <RowTwo />na <div>z flex-column. To wystarczy

<div class='flexbox flex-column height-100-percent'>
   <RowOne class='flex height-50-percent' />
   <RowTwo class='flex height-50-percent' />
</div>

0

Wygląda na to, że działa to w przypadkach ze stałą wysokością rodzica (testowane w Chrome i 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;
}

Jeśli z jakiegoś powodu nie można użyć siatek, być może jest to rozwiązanie.


0

Możesz z flexboxem:

ul.list {
    padding: 0;
    list-style: none;
    display: flex;
    align-items: stretch;
    justify-items: center;
    flex-wrap: wrap;
    justify-content: center;
}
li {
    width: 100px;
    padding: .5rem;
    border-radius: 1rem;
    background: yellow;
    margin: 0 5px;
}
<ul class="list">
  <li>title 1</li>
  <li>title 2<br>new line</li>
  <li>title 3<br>new<br>line</li>
</ul>


0

W odniesieniu do interaktywnego rozwiązania alternatywnego wspomnianego w pierwszej odpowiedzi ... Wymuszenie tego, aby kolumny flex miały tę samą wysokość we wszystkich wierszach, można wykonać za pomocą jQuery podczas ładowania:

$(function () {
    // Set the cards height to be the same in all lines
    $('.same-wrap-height').each(function () {
        let heighest = 0;

        $('.new-card', this).each(function () {
            if ($(this).height() > heighest) {
                heighest = $(this).height();
            }
        });

        $('.new-card', this).height(heighest);
    });
});

Mój układ Bootstrap:

<div class="row same-wrap-height">
    <div class="col-lg-6 ... new-card">
        <div class="card h-100">
            ...
        </div>
    </div>

    <div class="col-lg-6 ... new-card">
        <div class="card h-100">
            ...
        </div>
    </div>
</div>

-1

W twoim przypadku wysokość zostanie obliczona automatycznie, więc musisz podać wysokość,
użyj tego

.list-content{
  width: 100%;
  height:150px;
}

Przepraszam, wysokość może się różnić w zależności od zawartości. Więc nie można podać stałej wysokości.
Jinu Kurian

Wysokości są obliczane automatycznie, więc przy różnych treściach wysokości będą różne, więc musisz użyć stałej wysokości, w przeciwnym razie nie możesz uzyskać jednolitych wysokości.
Tom

-3

możesz to zrobić poprzez ustalenie wysokości znacznika "P" lub ustalenie wysokości "elementu listy".

Zrobiłem, ustalając wysokość „P”

a przepełnienie powinno być ukryte.

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


Wydaje się, że nie jest odpowiedzią, której szukam, jeśli zawartość stanie się większa, zostanie ukryta.
Jinu Kurian

@JinuKurian, gdzie dodam overflow: hidden, jeśli zmienisz to na overflow: auto to pojawi się scroll. wtedy możesz również zobaczyć pełną treść
Ajay Malhotra

-6

dla tej samej wysokości powinieneś zmienić właściwości "display" css. Więcej szczegółów w podanym przykładzie.

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


Dzięki, ale chcę wyświetlić listy w wielu wierszach.
Jinu Kurian
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.