Ist es möglich, dass flexible Elemente eng an den darüber liegenden Elementen ausgerichtet sind?

71

Dies ist praktisch das Pinterest-Layout. Die online gefundenen Lösungen sind jedoch in Spalten eingeschlossen, was bedeutet, dass der Container versehentlich horizontal wächst. Das ist nicht das Pinterest-Layout, und es funktioniert nicht gut mit dynamisch geladenen Inhalten.

Was ich tun möchte, ist eine Reihe von Bildern mit fester Breite und asymmetrischer Höhe, die horizontal angeordnet sind, aber in eine neue Reihe gewickelt werden, wenn die Grenzen des Containers mit fester Breite erreicht sind:

Kann Flexbox dies tun oder muss ich auf eine JS-Lösung wie Masonry zurückgreifen?

Guybrush Threepwood
quelle
Es ist nicht klar, wie die Reihenfolge Ihrer Elemente sein soll, und es ist sehr wichtig. Könnten Sie ihnen Zahlen hinzufügen?
Tao
Ich denke darüber nach, aber es könnte die möglichen Antworten einschränken. Ich weiß, dass die ersten drei von links nach rechts 1, 2, 3 sind, aber es ist mir egal, ob 4 unter 1, 2 oder 3 liegt. (Wenn die vertikale Platzierung das Kriterium ist, sollte sie unter 3 liegen ; wenn es sich um eine horizontale Platzierung handelt, sollte sie unter 1 liegen.) Alles ist möglich!
Guybrush Threepwood
4
Keine Flexbox ist keine gute Lösung für dieses Layout. Sie sollten Mauerwerk oder im schlimmsten Fall CSS-Säulen verwenden. Dies ähnelt meiner Antwort auf diese Frage, sodass es Ihnen möglicherweise hilft, stackoverflow.com/questions/34417059/…
Nenad Vracar
1
Ein bisschen spät auf der Party, hier ist der answer to a similar questionvon Evan Sharp, Autor des Pinterest-Skripts und Mitbegründer von Pinterest, der die Logik erklärt.
Tao

Antworten:

43

Flexbox ist ein "1-dimensionales" Layoutsystem: Es kann Elemente entlang horizontaler oder vertikaler Linien ausrichten.

Ein echtes Rastersystem ist "zweidimensional": Es kann Elemente entlang horizontaler UND vertikaler Linien ausrichten. Mit anderen Worten, Zellen können sich über Spalten und Zeilen erstrecken, was Flexbox nicht kann.

Aus diesem Grund verfügt die Flexbox nur über eine begrenzte Kapazität zum Aufbau von Gittern. Dies ist auch ein Grund, warum das W3C eine andere CSS3-Technologie entwickelt hat, Grid Layout (siehe unten).


In einem Flex-Container mit flex-flow: row wrapmüssen Flex-Elemente in neue Zeilen umbrochen werden .

Dies bedeutet, dass ein Flex-Element nicht unter ein anderes Element in derselben Zeile gewickelt werden kann .

Geben Sie hier die Bildbeschreibung ein

Beachten Sie oben, wie Div # 3 unter Div # 1 umbrochen wird und eine neue Zeile erstellt. Es kann nicht unter div # 2 gewickelt werden .

Wenn Elemente nicht die höchsten in der Reihe sind, bleibt daher ein Leerraum übrig, wodurch unschöne Lücken entstehen.

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Bildnachweis: Jefree Sujit


column wrap Lösung

Wenn Sie zu wechseln flex-flow: column wrap, werden Flex-Elemente vertikal gestapelt, und ein gitterartiges Layout ist besser erreichbar. Ein Container in Säulenrichtung weist jedoch auf Anhieb drei potenzielle Probleme auf:

  1. Es erweitert den Container horizontal und nicht vertikal (wie das Pinterest-Layout).
  2. Der Behälter muss eine feste Höhe haben, damit die Gegenstände wissen, wo sie verpackt werden müssen.
  3. Zum jetzigen Zeitpunkt weist es einen Mangel in allen gängigen Browsern auf, in denen der Container nicht erweitert wird, um zusätzliche Spalten aufzunehmen .

Infolgedessen ist ein Container in Spaltenrichtung in vielen Fällen möglicherweise nicht realisierbar.


Andere Lösungen

Michael Benjamin
quelle
6

Was Sie wollen, können Sie in 3 erreichen 2 Arten werden, CSS-weise:

1. Flexbox:

    .parent {
        display: flex;
        flex-direction: column;
        flex-wrap: wrap;
        max-width: {max-width-of-container} /* normally 100%, in a relative container */
        min-height: {min-height-of-container}; /* i'd use vh here */
    }
    .child {
        width: {column-width};
        display: block;
    }

2. CSS-Spalten

(Diese Lösung hat den sehr netten Vorteil der eingebauten Lösung column-span- ziemlich praktisch für Titel). Der Nachteil ist die Reihenfolge der Artikel in Spalten (die erste Spalte enthält das erste Drittel der Artikel usw.). Ich habe eine jsFiddle dafür gemacht.

    .parent {
        -webkit-columns: {column width} {number of columns}; /* Chrome, Safari, Opera */
        -moz-columns: {column width} {number of columns}; /* Firefox */
        columns: {column width} {number of columns};
    }
    .child {
         width: {column width};
    }
    /* where {column width} is usually fixed size 
     * and {number of columns} is the maximum number of columns.
     * Additionally, to avoid breaks inside your elements, you want to add:
     */
    .child {
        display: inline-block;
        -webkit-column-break-inside: avoid;
        page-break-inside: avoid;
        break-inside: avoid-column;
    }

3. Mauerwerk Plugin

absolute Positionierung nach Berechnung der gerenderten Artikelgrößen über JavaScript (Masonry Plugin).

tao
quelle
1
# 1 funktioniert bei mir nicht mit dem neuesten Firefox (ich sollte mit einem Spielplatzbeispiel aktualisieren; werde dies tun). # 2 kam tatsächlich sehr nahe, mit ein paar Macken, die ausgearbeitet werden mussten, aber ich verstehe, dass es das neue CSS-Grid-System verwendet, das eine sehr schlechte Browser-Unterstützung hat.
Guybrush Threepwood
Sie haben Recht mit # 1. Ich konnte es nicht mit Flex zum Laufen bringen. Ich bin mir nicht sicher, was Sie unter "sehr schlechter Browserunterstützung" verstehen. Können Sie mir bitte einige Zahlen zeigen? Ich denke, # 2 hat Probleme für weniger als 5% der Benutzer. Korrigiere mich, wenn ich falsch liege.
Tao
Wenn Sie sich die Statistiken zu Usage Relative ansehen, wird das Grid-System für eine große Anzahl von Benutzern nicht unterstützt, sodass es wahrscheinlich noch nicht produktionsbereit ist. Es ist jedoch eine großartige Lösung, danke dafür. caniuse.com/#search=grid
Guybrush Threepwood
2
Faszinierend. Können Sie Unterschiede zwischen Raster und Spalten erkennen ?
Tao
1

Der columnAnsatz scheint ein guter Kompromiss zu sein, wenn Sie column-widthüber vminoder vmaxEinheiten und Drop setzen column-count(erstes Snippet), display:gridund vminist auch eine Option für die Zukunft (zweites Snippet).

Ausschnitt inspiriert von @ Lanti Antwort.

Demo mit vmin testen

.container {

}

ul {
  margin: 0;
  padding: 0;
}

ul li {
  list-style: none;
  font-size: 0;
}

.portfolio ul {
  -webkit-column-width:50vmin;
     -moz-column-width:50vmin;
          column-width:50vmin;
  -webkit-column-fill:balance;
     -moz-column-fill:balance;
          column-fill:balance;
  -webkit-column-gap: 3px;
     -moz-column-gap: 3px;
          column-gap: 3px;
}

.portfolio ul:hover img {
  opacity: 0.3;
}

.portfolio ul:hover img:hover {
  opacity: 1;
}

.portfolio ul li {
  margin-bottom: 3px;
}

.portfolio ul li img {
  max-width: 100%;
  transition: 0.8s opacity;
}
<section class="container portfolio">
  <ul>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/IMG_2959-1400px.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/lantosistvan-portfolio-010.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/IMG_6188-dng-k.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/20151220-csaladi-peregi-046-k.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/20151230-csalad-szalai-0194-k.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/lantosistvan-portfolio-001(1).jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171819-portfolio.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171829-portfolio.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171938-portfolio.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171953-portfolio.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528194754-portfolio.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528184948-portfolio.jpg" alt="" /></li>
  </ul>
</section>

ein Link unter anderem https://web-design-weekly.com/2014/11/18/viewport-units-vw-vh-vmin-vmax/


display:grid Dies macht es auch mit der automatischen Füllung einfach, erfordert jedoch die Festlegung eines Bereichswerts auf das höchste Bild, damit Zeilen und Spalten inbrizieren können

.container {}

ul {
  margin: 0;
  padding: 0;
}

ul li {
  list-style: none;
  font-size: 0;
}

.portfolio ul {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(50vmin, 1fr));
  grid-gap: 5px;
  grid-auto-rows: minmax(10px, 1fr);
  grid-auto-flow: dense;
}

.portfolio ul:hover img {
  opacity: 0.3;
}

.portfolio ul:hover img:hover {
  opacity: 1;
}

.portfolio ul li {
  margin-bottom: 3px;
}

.portfolio ul li img {
  max-width: 100%;
  transition: 0.8s opacity;
}

li {
  border: solid blue;
  grid-row-end: span 1;
  display: flex;
  align-items: center;
  background: lightgray;
}

li:nth-child(1),
li:nth-child(3),
li:nth-child(6),
li:nth-child(7),
li:nth-child(8),
li:nth-child(9),
li:nth-child(10),
li:nth-child(11) {
  border: solid red;
  grid-row-end: span 2
}
<section class="container portfolio">
  <ul>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/IMG_2959-1400px.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/lantosistvan-portfolio-010.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/IMG_6188-dng-k.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/20151220-csaladi-peregi-046-k.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/20151230-csalad-szalai-0194-k.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/lantosistvan-portfolio-001(1).jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171819-portfolio.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171829-portfolio.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171938-portfolio.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171953-portfolio.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528194754-portfolio.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528184948-portfolio.jpg" alt="" /></li>
  </ul>
</section>

Sie können https://css-tricks.com/snippets/css/complete-guide-grid/ sehen.

G-Cyrillus
quelle
Die Reihenfolge der Bilder im ersten Snippet ist falsch, das ist das Problem beim Anordnen in Spalten. Aber der zweite scheint auf den Punkt zu kommen! Wirklich schön
Guybrush Threepwood
0

Sie können den Mauerwerkseffekt gemäß Ihrem Screenshot erzielen, aber Sie haben die Höhe des äußeren Div dynamisch eingestellt

html {
  box-sizing: border-box;
}
*,
*:before,
*:after {
  box-sizing: inherit;
}
.item-list {
  max-width: 400px;
  border: 1px solid red;
  display: -ms-flexbox;
	-ms-flex-direction: column;
	-ms-flex-wrap: wrap;
	display: flex;
	flex-direction: column;
	flex-wrap: wrap;
	height: 100vw;
}
.item-list__item {
  border: 1px solid green;
  width: 50%;
}
<div class="item-list" >
  <div class="item-list__item">
    Is we miles ready he might going. Own books built put civil fully blind fanny. Projection appearance at of admiration no. As he totally cousins warrant besides ashamed do. Therefore by applauded acuteness supported affection it. Except had sex limits
    county enough the figure former add. Do sang my he next mr soon. It merely waited do unable.
  </div>
  <div class="item-list__item">
    Is we miles ready he might going. Own books built put civil fully blind fanny. Projection appearance at of admiration no. As he totally cousins warrant besides ashamed do.
  </div>
  <div class="item-list__item">
    Is we miles ready he might going. Own books built put civil fully blind fanny. Projection appearance at of admiration no. As he totally cousins warrant besides ashamed do. Therefore by applauded acuteness supported affection it. Except had sex limits
  </div>
  <div class="item-list__item">
    Is we miles ready he might going. Own books built put civil fully blind fanny. Projection appearance at of admiration no. As he totally cousins warrant besides ashamed do.
  </div>
  <div class="item-list__item">
    Is we miles ready he might going. Own books built put civil fully blind fanny. Projection appearance at of admiration no. As he totally cousins warrant besides ashamed do. Therefore by applauded acuteness supported affection it. Except had sex limits
  </div>
</div>

David Chelliah
quelle
0

Stattdessen flexboxempfehle ich, für solche Gitter Spalten zu verwenden . Wie Sie sehen können, kann der Abstand auf den unteren Bildern besser sein, aber für eine native CSS-Lösung finde ich das ziemlich ordentlich. Nicht mehr JS:

.container {
  max-width: 900px;
  width: 100%;
  margin: 0 auto;
}

ul {
  margin: 0;
  padding: 0;
}

ul li {
  list-style: none;
  font-size: 0;
}

.portfolio ul {
  -moz-column-count: 4;
  -webkit-column-count: 4;
  column-count: 4;
  -moz-column-gap: 3px;
  -webkit-column-gap: 3px;
  column-gap: 3px;
}

.portfolio ul:hover img {
  opacity: 0.3;
}

.portfolio ul:hover img:hover {
  opacity: 1;
}

.portfolio ul li {
  margin-bottom: 3px;
}

.portfolio ul li img {
  max-width: 100%;
  transition: 0.8s opacity;
}
<section class="container portfolio">
  <ul>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/IMG_2959-1400px.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/lantosistvan-portfolio-010.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/IMG_6188-dng-k.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/20151220-csaladi-peregi-046-k.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/20151230-csalad-szalai-0194-k.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/lantosistvan-portfolio-001(1).jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171819-portfolio.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171829-portfolio.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171938-portfolio.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171953-portfolio.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528194754-portfolio.jpg" alt="" /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528184948-portfolio.jpg" alt="" /></li>
  </ul>
</section>

Lanti
quelle
Das sieht gut aus, aber die Reihenfolge der Elemente ist falsch. Der herausfordernde Teil besteht darin, die Elemente horizontal auszulegen und dann vertikal zu wickeln.
Guybrush Threepwood