Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
675 views
in Technique[技术] by (71.8m points)

html - How to wrap flexbox over multiple rows and columns?

I'm trying to build a gallery in form of a masonry, but I can't get my head around wrapping of flexboxes?

enter image description here

I got a simple UL list and I've added the style needed, but things are not floating and wrapping as it should.

.masonry {

  margin: 48px -2px;
  padding-left: 0;
  list-style: none;
  align-items: flex-start;
  flex-direction: row;
  flex-wrap: wrap;
  display: flex;
}

.masonry li {

  height: 300px;
  flex-basis: calc(33.33% - 4px);
  margin: 2px;
  text-align: center;
  display: flex;
  
  background-color: #C9F4FF;
}

.masonry li:nth-child(1), .masonry li:nth-child(7) {

  height: 604px;
  
  background-color: #FFB4FF;
}

.masonry li:nth-child(4), .masonry li:nth-child(4) {

  flex-basis: calc(66.66% - 4px);
  background-color: #B9EDA8;
}
<!-- masonry starts -->
    <ul class="masonry">
        <li>&nbsp;</li>
        <li>&nbsp;</li>
        <li>&nbsp;</li>
        <li>&nbsp;</li>
        <li>&nbsp;</li>
        <li>&nbsp;</li>
        <li>&nbsp;</li>
        <li>&nbsp;</li>
    </ul>
<!-- masonry ends -->
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Flexbox can't do that with its own layout capabilities, it needs some help, so here is a CSS solution that assume the size of the items is given.

The main trick here is to add an extra element inside the li and make that the "styled" one, and use the li for the main layout.

The "light green" items gets a left/right margin, to push them accordingly, and with that make space for the "light purple".

Since a flex item (here the li) can't dynamically grow both vertical and horizontal, we instead use its inner div to take twice the height, and with that enable the requested layout.

This setup, combined with Flexbox's order property, will now make it very simply to adjust its layout using e.g. media query for a portrait layout (vertically stacked) etc.


Note, to make this all dynamically sized by its content, either a script or CSS Grid will be needed.

Here is a great post shedding some light (and more solutions) on Masonry:


Stack snippet

.masonry {
  margin: 48px -2px;
  padding-left: 0;
  list-style: none;
  align-items: flex-start;
  flex-wrap: wrap;
  display: flex;
}

.masonry li {
  flex-basis: calc(100% / 3);
  height: 200px;
  display: flex;
}

.masonry li div {
  display: relative;
  flex: 1;
  margin: 2px;
  text-align: center;
  display: flex;
  background-color: #C9F4FF;
}

.masonry li:nth-child(1) div,
.masonry li:nth-child(7) div {
  display: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: calc(200% - 4px);              /*  twice the height  */
  background-color: #FFB4FF;
}

.masonry li:nth-child(4),
.masonry li:nth-child(8) {
  flex-basis: 100%;                      /*  100% width to force wrap  */
}

.masonry li:nth-child(4) div,
.masonry li:nth-child(8) div {
  background-color: #B9EDA8;
}

.masonry li:nth-child(4) div {
  margin-left: calc((100% / 3) + 2px);   /*  pushed to left  */
}

.masonry li:nth-child(8) div {
  margin-right: calc((100% / 3) + 2px);  /*  pushed to right  */
}
<!-- masonry starts -->
<ul class="masonry">
    <li><div>&nbsp;</div></li>
    <li><div>&nbsp;</div></li>
    <li><div>&nbsp;</div></li>
    <li><div>&nbsp;</div></li>
    <li><div>&nbsp;</div></li>
    <li><div>&nbsp;</div></li>
    <li><div>&nbsp;</div></li>
    <li><div>&nbsp;</div></li>
</ul>
<!-- masonry ends -->

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...