Flex-box: Wyrównaj ostatni rząd do siatki

378

Mam prosty układ flex-box z pojemnikiem takim jak:

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

Teraz chcę, aby elementy w ostatnim rzędzie były wyrównane z innymi. justify-content: space-between;należy stosować, ponieważ szerokość i wysokość siatki można regulować.

Obecnie tak wygląda

Element w prawym dolnym rogu powinien znajdować się na środku

Tutaj chcę, aby element w prawym dolnym rogu znajdował się w „środkowej kolumnie”. Jaki jest najprostszy sposób na osiągnięcie tego? Oto mały jsfiddle, który pokazuje to zachowanie.

.exposegrid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.exposetab {
  width: 100px;
  height: 66px;
  background-color: rgba(255, 255, 255, 0.2);
  border: 1px solid rgba(0, 0, 0, 0.4);
  border-radius: 5px;
  box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
  margin-bottom: 10px;
}
<div class="exposegrid">
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
</div>

Thorben Croisé
źródło
Sprawdź moje rozwiązanie tutaj Myślę, że działa dobrze bez włamania, tylko matematyka: stackoverflow.com/questions/18744164/...
Sebastien Lorber
5
Alternatywnie, można użyć nowszego modułu grid css - który nie ma tego problemu
Danield
1
Dodałem ogólne rozwiązanie JS dla przypadków, gdy szerokość elementu podrzędnego jest zmienna, dzięki czemu liczba elementów w wierszu jest również zmienna.
tao

Odpowiedzi:

416

Dodaj ::afterautomatycznie wypełniające miejsce. Nie musisz zanieczyszczać swojego HTML. Oto kodepen, który to pokazuje: http://codepen.io/DanAndreasson/pen/ZQXLXj

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.grid::after {
  content: "";
  flex: auto;
}
Dan Andreasson
źródło
17
Czy można by w jakiś sposób sprawić, by działała w przestrzeni kosmicznej?
Tom
60
@DanAndreasson Istnieją dwa problemy, nie zaczyna się od lewej (jak odstęp między), a także odstęp między elementami ostatniego rzędu jest inny niż w poprzednim rzędzie (symulowanie niektórych elementów o stałej szerokości w „dowolnym rozmiarze” grid - dotyczy obu) ... codepen.io/anon/pen/gPoYZE Chciałem zachować „strategię” (spacja lub spacja), ale zacznij od lewej, jak w poprzednich liniach ... I chciałem wiedzieć, czy można uogólnić swoje niesamowite rozwiązanie.
Tom
44
Działa to tylko dlatego, że przedmioty mają dopełnienie do miejsca ich i połączone szerokości procent równy 100% dla każdego zestawu 4. W ten codepen usunąłem justify-content: space-between;z .gridi usunięte .grid:afteri to działa tak samo. Teraz, jeśli spróbujesz czegoś takiego , całkowicie się psuje. Zauważ, że szerokości dla każdego zestawu 4 nie sumują się do 100%. W skrzypce PO szerokości są ustawione w px, więc twoje rozwiązanie nie działa w tej sytuacji.
Jacob Alvarez
22
Próbując tego rozwiązania, początkowo elementy, które były krótkie w ostatnim rzędzie, nie były prawidłowo rozłożone space-between. Jednak, kiedy ustawić flex-basisod .grid:afterdo tego samego rozmiaru jak inne przedmioty w siatce (per-przerwania, przeważające powyższy default / kod bazowy moduł), ostatni wiersz rozprzestrzeniania się prawidłowo. Wygląda na to, że działa w Safari, iOS, Firefox, Chrome (trzeba przetestować IE), a mój największy rozmiar wiersza to 3 przy mojej początkowej implementacji.
webbower
8
Na moje potrzeby działało to z następującą modyfikacją: { content: "";flex: 0 0 32%;max-width: 480px;}i zmieniłem maksymalną szerokość wraz ze zmianami zapytań o media, więc siatka była idealna dla wszystkich szerokości.
Colin Wiseman
160

Jedną z technik byłoby wstawienie pewnej liczby dodatkowych elementów (tyle, ile maksymalna liczba elementów, których można oczekiwać w rzędzie), które mają zerową wysokość. Przestrzeń jest nadal podzielona, ​​ale zbędne wiersze zapadają się w nicość:

http://codepen.io/dalgard/pen/Dbnus

body {
  padding: 5%;
}

div {
  overflow: hidden;
  background-color: yellow;
}

ul {
  display: flex;
  flex-wrap: wrap;
  margin: 0 -4px -4px 0;
  list-style: none;
  padding: 0;
}

li {
  flex: 1 0 200px;
  height: 200px;
  border-right: 4px solid black;
  border-bottom: 4px solid black;
  background-color: deeppink;
}
li:empty {
  height: 0;
  border: none;
}

*,
:before,
:after {
  box-sizing: border-box;
}
<div>
  <ul>
    <li>a</li>
    <li>b</li>
    <li>c</li>
    <li>d</li>
    <li>e</li>
    <li>f</li>
    <li>g</li>
    <li>h</li>
    <li>i</li>
    <li>j</li>
    <li>k</li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>

W przyszłości może to zostać osiągnięte poprzez użycie wielu ::after(n).

dalgard
źródło
11
Niestety zanieczyszcza to znaczniki w sposób nie semantyczny, ale działa całkowicie. : SI żałuję, że nie znałem żadnego innego sposobu replikacji tego zachowania, flexboksa lub innego, który nie wymagałby elementów nie-semantycznych.
Ryan Norbauer
33
Zgadzam się, jest brudny, ale działa i jest mniej hackerski niż wiele hacków. Kurwa, używam go, dopóki :: after (12) nie uzyska wsparcia lub dodadzą dodatkowe opcje uzasadnienia. Szkoda, bo sposób, w jaki usprawiedliwia działanie Flexbox, jest po prostu zły! Jeśli uzasadniasz akapit tekstu, nigdy nie próbowałbyś uzasadnić ostatniego wiersza. Zdecydowanie powinna być opcją, nie mogę uwierzyć, że to przegapili.
Codemonkey
4
Wymyśliłem rozwiązanie tylko CSS. Zastrzeżenie polega na tym, że zawsze może uwzględniać tylko dwa brakujące elementy, więc będzie działać bezpiecznie tylko w elastycznej siatce z maksymalnie trzema przedmiotami na rząd owijania. Demo: codepen.io/lukejacksonn/pen/dozqVq Podstawową zasadą jest użycie pseudoelementów jako dodatkowych elementów podrzędnych i nadanie im tej samej właściwości elastyczności co elementy w kontenerze.
lukejacksonn
7
@Codemonkey Jesus. Dopiero zacząłem używać Flexboksa, zastanawiając się, jak pozbyć się tych wszystkich hacków mających na celu wyrównanie tych bloków w siatce, a teraz okazuje się, że to po prostu niemożliwe! Natychmiast uderzyłem w ten blok, osiągając granice, o których myślałem, że prawie nigdy nie osiągnęłbym z radością rozwiązania wszystkich tych starych nierozwiązywalnych problemów CSS. Chyba nie tak szybko. Właściwe wyśrodkowanie w pionie zajęło tylko 20 lat - na pewno możemy poczekać. Jezu, wydaje się to takie proste zadanie ...
Andrey
3
@dalgard Nie sądzę. Zobacz mój komentarz .
Jacob Alvarez
108

Jak wspomniano w innych plakatach - nie ma czystego sposobu wyrównania do lewej strony ostatniego wiersza za pomocą Flexboksa (przynajmniej zgodnie z bieżącą specyfikacją)

Jednak za to, co jest warte: dzięki modułowi układu siatki CSS jest to zaskakująco łatwe do wytworzenia:

Zasadniczo odpowiedni kod sprowadza się do tego:

ul {
  display: grid; /* 1 */
  grid-template-columns: repeat(auto-fill, 100px); /* 2 */
  grid-gap: 1rem; /* 3 */
  justify-content: space-between; /* 4 */
}

1) Ustaw element kontenera w kontener siatkowy

2) Ustaw siatkę z automatycznymi kolumnami o szerokości 100px. (Zwróć uwagę na użycie funkcji autouzupełniania (stosowanej do auto-fit- która (dla układu 1-wierszowego) zwija puste ścieżki do zera - powodując, że elementy rozszerzają się, aby zająć pozostałe miejsce. Spowodowałoby to uzasadnione „odstęp między 'układ, gdy siatka ma tylko jeden wiersz, który w naszym przypadku nie jest tym, czego chcemy. (sprawdź to demo, aby zobaczyć różnicę między nimi)).

3) Ustaw odstępy / rynny dla rzędów i kolumn siatki - tutaj, ponieważ chcesz mieć układ „odstępu” - odstęp będzie faktycznie odstępem minimalnym, ponieważ będzie się powiększał w miarę potrzeby.

4) Podobne do Flexbox.

Codepen Demo (zmiana rozmiaru, aby zobaczyć efekt)

Danield
źródło
4
Niezłe rozwiązanie. Jedynym problemem jest to, że nie działa z IE10 / 11.
zendu
1
Jeśli chodzi o auto-fit, w Chrome 57-60 wystąpił błąd (i przeglądarki oparte na jego silniku, takim jak Samsung Internet 6.0), ponieważ specyfikacja była wówczas nieco niejednoznaczna . Teraz specyfikacja została wyjaśniona, a nowe wersje Chrome są renderowane auto-fitpoprawnie, ale przeglądarki ze starym silnikiem są nadal w użyciu, więc należy zachować ostrożność przy tej wartości.
Ilya Streltsyn
4
W świetle obecnych możliwości powinna to być zaakceptowana odpowiedź. Użycie :afterpseudoelementu może prowadzić do niepożądanych wyników w przypadkach krawędzi.
Paul
2
@ Danield ta sugestia bardzo mi pomogła, dziękuję!
Krys
4
To powinna być zaakceptowana odpowiedź. Chciałbym połączyć go z Flexboksem jako awarią, w duchu stopniowego ulepszania: przeglądarki, które nie obsługują siatki, wyświetlają wersję Flexboksa, która jest wystarczająco blisko mnie.
Palantir
27

Bez żadnych dodatkowych znaczników, po prostu dodanie ::afterdziałało dla mnie, określając szerokość kolumny.

.grid {
  display:flex;
  justify-content:space-between;
  flex-wrap:wrap;
}
.grid::after{
  content: '';
  width: 10em // Same width of .grid__element
}
.grid__element{
  width:10em;
}

Z HTML takim jak ten:

<div class=grid">
   <div class="grid__element"></div>
   <div class="grid__element"></div>
   <div class="grid__element"></div>
</div>
Nicolás Arévalo
źródło
8
to interesujące, ale nie do końca poprawne. problem pojawia się, gdy masz do czynienia z więcej niż dwoma elementami w dolnym rzędzie - odstępy między elementami w powyższych rzędach nigdy nie pojawiają się w ostatnim; przedmioty są zapakowane razem, co neguje pierwotną użyteczność odstępu między nimi.
John Haugeland,
nawet lepiej, jeśli używasz flex-basis: 10emzamiast szerokości.
beytarovski
14

Nie możesz Flexbox nie jest systemem gridowym. Nie ma konstrukcji językowych do robienia tego, o co prosisz, a przynajmniej nie, jeśli używasz justify-content: space-between. Najbliższe, jakie można uzyskać za pomocą Flexbox, to użycie orientacji kolumny, która wymaga ustawienia wyraźnej wysokości:

http://cssdeck.com/labs/pvsn6t4z (uwaga: prefiksy nie są dołączone)

ul {
  display: flex;
  flex-flow: column wrap;
  align-content: space-between;
  height: 4em;
}

Łatwiej byłoby jednak po prostu użyć kolumn, które mają lepsze wsparcie i nie wymagają ustawiania określonej wysokości:

http://cssdeck.com/labs/dwq3x6vr (uwaga: prefiksy nie są dołączone)

ul {
  columns: 15em;
}
Cimmanon
źródło
2
Jest sposób; zobacz moją odpowiedź.
dalgard
@dalgard, twoja odpowiedź jest obejściem, a nie prawdziwym rozwiązaniem. odpowiedź cimmanona jest poprawna.
Jonasz
1
@Jonah Myślę, że „technika” jest uczciwym opisem mojej odpowiedzi. Z pewnością zadziałało jako rozwiązanie dla wielu osób, w tym osoby pytającej.
dalgard 30.04.16
2
@dalgard Nie zmienia to faktu, że Flexbox nie udostępnia konstruktorów językowych, aby wykonać to, o co proszono. Ponadto argumentowałbym, że dodawanie fałszywych elementów jest bardzo brudną praktyką, już przy użyciu tabel do rozmieszczenia.
cimmanon
4
To nie jest ładne, ale rozwój front-end jest sztuką możliwą; pragmatyzm jest podstawową przesłanką. Wydaje mi się, że słowo „ ekstremalnie” jest niewłaściwe, ponieważ dodatkowe elementy są używane do stylizacji na 99,9% prawdziwych stron internetowych (por. Elementy kontenera Bootstrap).
dalgard
12

Możliwym rozwiązaniem jest zastosowanie justify-content: flex-start;na .gridkontenerze, ograniczeń wielkości dla jego elementów podrzędnych i marginesów na odpowiednich elementach podrzędnych - w zależności od pożądanej liczby kolumn.

W przypadku siatki 3-kolumnowej podstawowy CSS wyglądałby tak:

.grid {
    display: flex;
    flex-flow: row wrap;
    justify-content: flex-start;
}

.grid > * {
    flex: 0 0 32%;
    margin: 1% 0;
}

.grid > :nth-child(3n-1) {
    margin-left: 2%;
    margin-right: 2%;
}

To kolejne niedoskonałe rozwiązanie, ale działa.

http://codepen.io/tuxsudo/pen/VYERQJ

Jared
źródło
11

Wiem, że jest tu wiele odpowiedzi, ale .. Najprostszym sposobem na to jest gridużycie zamiast flexi za grid template columnspomocą repeatoraz auto fills, gdzie musisz ustawić liczbę pikseli, które podałeś każdemu elementowi, 100pxz kodu fragmentu.

.exposegrid {
     display: grid;
     grid-template-columns: repeat(auto-fill, 100px);
     justify-content: space-between;
}
 .exposetab {
     width: 100px;
     height: 66px;
     background-color: rgba(255, 255, 255, 0.2);
     border: 1px solid rgba(0, 0, 0, 0.4);
     border-radius: 5px;
     box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
     margin-bottom: 10px;
}
<div class="exposegrid">
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
</div>

Srebrny Surfer
źródło
2
Jest to właściwe rozwiązanie, aby wyrównać pozycje ostatniego rzędu.
a.barbieri,
Zgadzam się, właściwym sposobem jest użycie siatki. Można to osiągnąć za pomocą Flexboksa, ale znacznie czystszego w użyciu siatki.
nbarth
6

Tak.! Możemy, ale z pewnymi zapytaniami o media i maksymalną liczbą kolumn jest predefiniowanych .

Tutaj używam 4 kolumn. Sprawdź mój kod:

.container {
  display: flex;
  display: -webkit-flex;
  display: -moz-flex;
  flex-flow: row wrap;
  -webkit-flex-flow: row wrap;
  -moz-flex-flow: row wrap;
}

.container .item {
  display: flex;
  display: -webkit-flex;
  display: -moz-flex;
  justify-content: center;
  -webkit-justify-content: center;
  -moz-justify-content: center;
  flex-basis: 25%; //max no of columns in %, 25% = 4 Columns
}

.container .item .item-child {
  width: 130px;
  height: 180px;
  background: red;
  margin: 10px;
}

@media (max-width: 360px) {
  .container .item {
    flex-basis: 100%;
  }
}

@media (min-width:360px) and (max-width: 520px) {
  .container .item {
    flex-basis: 50%;
  }
}

@media (min-width:520px) and (max-width: 680px) {
  .container .item {
    flex-basis: 33.33%;
  }
}
<div class="container">

  <div class="item">
    <div class="item-child">1</div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>

</div>

UWAGA
1) Nie ma potrzeby tworzenia div dziecka. Może to być dowolny inny znacznik, taki jak „img” r, cokolwiek chcesz.
2) Jeśli chcesz uzyskać więcej kolumn, dostosuj zapytania o media i maksymalną liczbę kolumn.

Mohamed Mohaideen AH
źródło
To tworzy tylko 3 w najnowszej IE
Akxe
6

Jeśli chcesz siatkę z pewną przestrzenią między elementami i elementami rozpoczynającymi się bez początkowej spacji, to proste rozwiązanie działa:

.grid {
    display: flex;
    flex-flow: row wrap;
    margin: 0 -5px; // remove the inital 5px space
    width: auto;
}
.grid__item {
    width: 25%;
    padding: 0 5px; // should be same as the negative margin above.
}

Jeśli chcesz początkowej przestrzeni 5 pikseli, po prostu usuń ujemny margines :) Proste.

https://jsfiddle.net/b97ewrno/2/

Przyjęta odpowiedź, choć dobra, powoduje, że między elementami w drugim rzędzie nie ma miejsca.

OZZIE
źródło
1
Zaskoczony, że nie ma już więcej głosów. To piękne podejście należy do muzeum Flex.
Eduardo La Hoz Miranda,
1
@EduardoLaHozMiranda dzięki! Ale dlaczego „muzeum”? IE11 nie obsługuje css grid i większość stron nadal musi to obsługiwać. + Niektóre duże timery w tworzeniu frontendów nadal twierdzą, że istnieją różne przypadki użycia grida lub flexboksa. Być może chodziło Ci tylko o to, że powinna to być ważna część historii sieci: D
OZZIE
1
Lol, tak. Byłem wtedy podekscytowany. Oznaczało to, że było to świetne i minimalne podejście do tego problemu.
Eduardo La Hoz Miranda
@dencey nie musisz wiedzieć, że w przypadku tego rozwiązania jest to 25%, więc maksymalnie 4 na wiersz, ale możesz użyć dowolnego procentu
OZZIE
@OZZIE Mam na myśli, że szerokość elementu jest stała (jak 100 pikseli), ale szerokość kontenera jest dynamiczna, więc elementy w wierszu są dynamiczne.
dencey
4

Jeśli chcesz wyrównać ostatni element do siatki, użyj następującego kodu:

Pojemnik siatkowy

.card-grid {
  box-sizing: border-box;
  max-height: 100%;
  display: flex;
  flex-direction: row;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  justify-content: space-between;
  align-items: stretch;
  align-content: stretch;
  -webkit-box-align: stretch;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  -ms-flex-flow: row wrap;
  flex-flow: row wrap;
}

.card-grid:after {
  content: "";
  flex: 1 1 100%;
  max-width: 32%;
}

Element w siatce

.card {
  flex: 1 1 100%;
  box-sizing: border-box;
  -webkit-box-flex: 1;
  max-width: 32%;
  display: block;
  position: relative;

}

Sztuczka polega na ustawieniu maksymalnej szerokości elementu równej maksymalnej szerokości .card-grid: after.

Demo na żywo na Codepen

Frank Spin
źródło
cthulu błogosławi ciebie i twój komputer
L422Y,
3
To podejście nie działa, gdy rozmiar karty jest stały, a liczba kart w każdym rzędzie jest nieznana. codepen.io/zendu/pen/WXNGvo
zendu
3

Możliwe jest użycie „flex-start” i ręczne dodanie marginesów. Wymaga hakowania matematycznego, ale jest zdecydowanie łatwy do wykonania i ułatwia korzystanie z preprocesora CSS, takiego jak LESS.

Zobacz na przykład ten MNIEJ mixin:

.flexboxGridMixin(@columnNumber,@spacingPercent) {
  @contentPercent: 100% - @spacingPercent;
  @sideMargin: @spacingPercent/(@columnNumber*2);
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
  > * {
    box-sizing: border-box;
    width: @contentPercent/@columnNumber;
    margin-left: @sideMargin;
    margin-right: @sideMargin;
  }
}

A następnie można go łatwo użyć do wyświetlenia responsywnego układu siatki:

ul {
  list-style: none;
  padding: 0;
  @spacing: 10%;
  @media only screen and (max-width: 499px) { .flexboxGridMixin(1,@spacing); }
  @media only screen and (min-width: 500px) { .flexboxGridMixin(2,@spacing); }
  @media only screen and (min-width: 700px) { .flexboxGridMixin(3,@spacing); }
  @media only screen and (min-width: 900px) { .flexboxGridMixin(4,@spacing); }
  @media only screen and (min-width: 1100px) { .flexboxGridMixin(5,@spacing); }
}

li {
  background: pink;
  height: 100px;
  margin-top: 20px;
}

Oto przykład

http://codepen.io/anon/pen/YyLqVB?editors=110

Sebastien Lorber
źródło
Nigdy nie używasz @contentPercent. Czy miałeś zamiar?
neverfox 31.01.16
szerokość: @ contentPercent / @ columnNumber;
realtebo
ŁAŁ ! Jestem pod wrażeniem tego rozwiązania. Spróbuję dostosować się do mojej sytuacji
realtebo
3

Ten problem został dla mnie rozwiązany za pomocą siatki CSS,

To rozwiązanie ma zastosowanie tylko wtedy, gdy masz ustaloną liczbę kolumn, tj. Nie. elementów do wyświetlenia w jednym rzędzie

-> używając siatki, ale nie określając liczby wierszy, ponieważ liczba elementów zwiększa się, zawija się w kolumny i dynamicznie dodaje rzędy, w tym przykładzie podałem trzy kolumny

-> nie musisz dawać żadnej pozycji swojemu dziecku / komórce, ponieważ spowoduje to naprawę, czego nie chcemy.

.grid-class{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  column-gap: 80px;
}

Ashwin
źródło
1

Ta wersja jest najlepszym sposobem dla bloków o stałej szerokości:

http://codepen.io/7iomka/pen/oxxeNE

W innych przypadkach - wersja Dalgard

http://codepen.io/dalgard/pen/Dbnus

body {
  padding: 5%;
}

div {
  overflow: hidden;
  background-color: yellow;
}

ul {
  display: flex;
  flex-wrap: wrap;
justify-content:center;
  margin: 0 -4px -4px 0;
  list-style: none;
  padding: 0;
}

li {
  flex: 1 0 200px;
  height: 200px;
  max-width:200px;
  min-width:200px;
  border-right: 4px solid black;
  border-bottom: 4px solid black;
  background-color: deeppink;
}
li:empty {
  height: 0;
  border: none;
}

*,
:before,
:after {
  box-sizing: border-box;
}
<div>
  <ul>
    <li>a</li>
    <li>b</li>
    <li>c</li>
    <li>d</li>
    <li>e</li>
    <li>f</li>
    <li>g</li>
    <li>h</li>
    <li>i</li>
    <li>j</li>
    <li>k</li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>

Znacovean Simion
źródło
0

Istnieje sposób bez Flexboksa, chociaż musisz spełnić następujące warunki. 1) Pojemnik ma wypełnienie. 2) Przedmioty mają ten sam rozmiar i dokładnie wiesz, ile chcesz na linię.

ul {
  padding: 0 3% 0 5%;
}
li {
  display: inline-block; 
  padding: 0 2% 2% 0;
  width: 28.66%;
}

Mniejsze wypełnienie po prawej stronie kontenera pozwala na dodatkowe wypełnienie po prawej stronie każdego elementu listy. Zakładając, że inne elementy w tym samym obiekcie nadrzędnym co obiekt listy są uzupełnione wartością 0 5%, będzie z nimi równo. Możesz także dopasować wartości procentowe do dowolnych marginesów lub użyć wartości pikseli.

Oczywiście możesz zrobić to samo bez wypełniania kontenera, używając n-child (IE 9+), aby usunąć margines na co trzecim polu.

ansorensen
źródło
0

Korzystając z Flexboksa i kilku zapytań o media, zrobiłem to małe obejście: http://codepen.io/una/pen/yNEGjv (jest trochę zhackowane, ale działa):

.container {
  display: flex;
  flex-flow: row wrap;
  justify-content: flex-start;
  max-width: 1200px;
  margin: 0 auto;
}

.item {
  background-color: gray;
  height: 300px;
  flex: 0 30%;
  margin: 10px;

  @media (max-width: 700px) {
     flex: 0 45%;
  }

  @media (max-width: 420px) {
    flex: 0 100%;
  }

  &:nth-child(3n-1) {
    margin-left: 10px;
    margin-right: 10px;
  }
}
Una Kravets
źródło
0

Zrobiłem dla niego mixin SCSS.

@mixin last-row-flexbox($num-columns, $width-items){

  $filled-space: $width-items * $num-columns;
  $margin: calc((100% - #{$filled-space}) / (#{$num-columns} - 1));

  $num-cols-1 : $num-columns - 1;

  &:nth-child(#{$num-columns}n+1):nth-last-child(-n+#{$num-cols-1}) ~ & {
    margin-left: $margin;
  }
  @for $i from 1 through $num-columns - 2 { 
    $index: $num-columns - $i;
    &:nth-child(#{$num-columns}n+#{$index}):last-child{
      margin-right: auto;
    }
  }
}

To jest link do codepen: http://codepen.io/diana_aceves/pen/KVGNZg

Musisz tylko ustawić szerokość elementów w procentach i liczbie kolumn.

Mam nadzieję, że ci to pomoże.

Diana
źródło
0

Oto kolejna para miksów scss.

Te miksy zakładają, że nie będziesz używać wtyczek js, takich jak Isotope (nie przestrzegają one kolejności znaczników html, przez co psują się nth regułami css).

Będziesz mógł w pełni z nich skorzystać, zwłaszcza jeśli najpierw piszesz swoje responsywne punkty przerwania. Najlepiej będzie użyć flexbox_grid () w mniejszym punkcie przerwania i flexbox_cell () w następujących punktach przerwania. flexbox_cell () zajmie się resetowaniem wcześniej ustawionych marginesów, które nie są już używane w większych punktach przerwania.

A tak przy okazji, dopóki poprawnie skonfigurujesz właściwości flex kontenera, możesz także użyć tylko flexbox_cell () na elementach, jeśli to konieczne.

Oto kod:

// apply to the container (for ex. <UL> element)
@mixin flexbox_grid($columns, $gutter_width){

  display: flex;
  flex-direction:row;
  flex-wrap:wrap;
  justify-content: flex-start;

  > *{
    @include flexbox_cell($columns, $gutter_width);
  }
}

// apply to the cell (for ex. a <LI> element)
@mixin flexbox_cell($columns, $gutter_width){
  $base_width: 100 / $columns;
  $gutters: $columns - 1;
  $gutter_offset: $gutter_width * $gutters / $columns;

  flex-grow: 0;
  flex-shrink: 1;
  flex-basis: auto; // IE10 doesn't support calc() here

  box-sizing:border-box; // so you can freely apply borders/paddings to items
  width: calc( #{$base_width}% - #{$gutter_offset} );

  // remove useless margins (for cascading breakponts)
  &:nth-child(#{$columns}n){
    margin-right: 0;
  }

  // apply margin
  @for $i from 0 through ($gutters){
    @if($i != 0){
      &:nth-child(#{$columns}n+#{$i}){
        margin-right: $gutter_width;
      }
    }
  }
}

Stosowanie:

ul{
   // just this:
   @include flexbox_grid(3,20px);
}

// and maybe in following breakpoints, 
// where the container is already setted up, 
// just change only the cells:

li{
   @include flexbox_cell(4,40px);
}

Oczywiście od Ciebie zależy ostateczne ustawienie wypełnienia / marginesu / szerokości kontenera oraz dolnych marginesów komórki i tym podobnych.

Mam nadzieję, że to pomoże!

Luca Reghellin
źródło
0

To dość zuchwałe, ale działa dla mnie. Starałem się osiągnąć spójne odstępy / marginesy.

.grid {
  width: 1024px;
  display: flex;
  flex-flow: row wrap;
  padding: 32px;
  background-color: #ddd;  

  &:after {
    content: "";
    flex: auto;
    margin-left:-1%;
  }

  .item {
    flex: 1 0 24.25%;
    max-width: 24.25%;
    margin-bottom: 10px;
    text-align: center;
    background-color: #bbb;

    &:nth-child(4n+2),
    &:nth-child(4n+3),
    &:nth-child(4n+4) {
      margin-left: 1%;
    }

    &:nth-child(4n+1):nth-last-child(-n+4),
      &:nth-child(4n+1):nth-last-child(-n+4) ~ .item {
        margin-bottom: 0;
    }    

  }
}

http://codepen.io/rustydev/pen/f7c8920e0beb0ba9a904da7ebd9970ae/

RustyDev
źródło
0

Wygląda na to, że nikt nie zaproponował rozwiązania flex-grow dla ostatniego przedmiotu. Chodzi o to, aby twój ostatni przedmiot Flex zajął tyle miejsca, ile może, używając Flex-Grow: 1.

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.grid > *:last-child {
  flex-grow: 1;
}

Uwaga: To rozwiązanie nie jest idealne, szczególnie jeśli masz wyśrodkowane elementy w elementach elastycznych, ponieważ będą one wyśrodkowane na możliwie dużym ostatnim elemencie elastycznym.

Dionys
źródło
0

Jest to kombinacja wielu odpowiedzi, ale robi dokładnie to, czego potrzebowałem - czyli wyrównuje ostatnie dziecko w elastycznym pojemniku po lewej stronie, zachowując zachowanie odstępu między nimi (w tym przypadku jest to trzykolumna układ).

Oto znaczniki:

.flex-container {
  display: flex;
  justify-content: space-between;
  flex-direction: row;
}

.flex-container:after {
  content: "";
  flex-basis: 30%;
}
Małgorzata
źródło
1
Aby być bardziej ogólnym: rozmiar oparty na fleksie musi być równy rozmiarowi dzieci.
Christian Toffolo,
1
Znalazłem flex-grow: 0.9zamiast flex-basisprac dla dowolnej liczby kolumn. Testowany w wielu nowoczesnych przeglądarkach - działa w nich wszystkich, ale wypełnienie jest uszkodzone w IE (ale działa w Edge0
Patabugen
0

Zarozumiały:

  • Chcesz 4-kolumnowy układ siatki z zawijaniem
  • Liczba przedmiotów niekoniecznie jest wielokrotnością 4

Ustaw lewy margines na każdym elemencie z wyjątkiem 1, 5 i 9 elementu i tak dalej. Jeśli lewy margines wynosi 10 pikseli, wówczas każdy wiersz będzie miał margines 30 pikseli podzielony na 4 elementy. Procentowa szerokość towaru jest obliczana w następujący sposób:

100% / 4 - horizontal-border - horizontal-padding - left-margin * (4 - 1) / 4

Jest to przyzwoite obejście problemów dotyczących ostatniego rzędu Flexboksa.

.flex {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  margin: 1em 0 3em;
  background-color: peachpuff;
}

.item {
  margin-left: 10px;
  border: 1px solid;
  padding: 10px;
  width: calc(100% / 4 - 2px - 20px - 10px * (4 - 1) / 4);
  background-color: papayawhip;
}

.item:nth-child(4n + 1) {
  margin-left: 0;
}

.item:nth-child(n + 5) {
  margin-top: 10px;
}
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
</div>
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
</div>
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
</div>

Salman A.
źródło
0

Jeśli znasz szerokość odstępów między elementami w rzędzie i liczbę elementów w rzędzie, zadziałałoby to:

Przykład: 3 elementy z rzędu, odstęp 10 pikseli między elementami

div:last-child:nth-child(3n+2) {
  flex-grow: 1
  margin-left: 10px
}
norwegia
źródło
0

Po prostu użyj sztuczki Jquery / JavaScript, aby dodać pusty div:

if($('.exposegrid').length%3==2){
 $(".exposegrid").append('<div class="exposetab"></div>');
}
Waheed Mazhar
źródło
-1

Och chłopcze, myślę, że znalazłem dobre rozwiązanie z minimalnym CSS i bez JS. Sprawdź to:

img {width:100%;}
li {
  display: inline-block;
  width:8em;
  list-style:none;
}
ul {text-align: justify;}
<ul>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

Kluczem tutaj jest zapamiętanie, że to, co próbujemy osiągnąć, jest dokładnie tym, co text-align: justifyrobi!

Puste elementy w kodzie HTML mają na celu idealne wyświetlanie ostatniego wiersza bez zmiany wyglądu, ale mogą nie być potrzebne, biorąc pod uwagę to, co próbujesz osiągnąć. Aby uzyskać idealną równowagę w każdej sytuacji, potrzebujesz co najmniej x-4 pustych elementów, x oznacza liczbę elementów do wyświetlenia lub n-2, n oznacza liczbę kolumn, które chcesz wyświetlić.

Sharcoux
źródło
-1

Wystarczy dodać kilka fałszywych przedmiotów o tych samych właściwościach, z wyjątkiem wysokości ustawionej na 0px do końca.

Erik Parso
źródło
Dodawanie fałszywych przedmiotów to zła praktyka pod każdym względem. Nie powinieneś wypełniać DOM elementami tylko po to, aby włamać się do css, chyba że jest to obowiązkowe. Z wielu powodów, od dostępności, przez zalanie bazy kodowej dziwnymi rzeczami, przez uczynienie logiki bardziej złożoną do zrozumienia, a lista jest długa. Nie polecaj hacków, chyba że wyraźnie stwierdzisz, że może to być złe rozwiązanie lub istnieje specjalny przypadek.
Eksapsy
-4

chcesz wyrównać

użyj align-content: flex-start;zamiastjustify-content: space-between;

powoduje to przesunięcie elementów z ostatniego rzędu w lewo, a także równomierne rozłożenie przestrzeni,

.container {
  display: flex;
  flex-flow: row wrap;
  align-content: flex-start;
  /*justify-content: space-between; remove this line!!!! */ 
}

https://codepen.io/anon/pen/aQggBW?editors=1100


Rozwiązanie danAnderson NIE JEST DYNAMICZNE .PERİOD !!

gdy szerokość elementu zmieniła się z 25 na 28 dan anderson traci przestrzeń między obrazami

danAnderson: https://codepen.io/anon/pen/ZwYPmB?editors=1100

dynamiczny: https://codepen.io/anon/pen/aQggBW?editors=1100

to właśnie próbowałem powiedzieć. dans jest hacky .....

bh_earth0
źródło
-7

Byłem w stanie to zrobić justify-content: space-betweenna pojemniku

chovy
źródło