Abstractic
Abstractic

Reputation: 195

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

The result looks like this, which is kinda funny :)

enter image description here

Maybe someone knows how to write the correct CSS to make things wrap correctly?

Upvotes: 4

Views: 9271

Answers (3)

Abstractic
Abstractic

Reputation: 195

I've created a quick image gallery from the help I got and have to say it was as simple and neat as I wanted it.

enter image description here

body {
    
    padding: 48px;
    font-family: Helvetica, Arial, sans-serif;
}
.masonry {
    margin: -2px;
    padding-left: 0;
    list-style: none;
    align-items: flex-start;
    flex-direction: row;
    flex-wrap: wrap;
    display: flex
}

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

@media (max-width: 1199.98px) {
    .masonry li {
        height: 250px
    }
}

@media (max-width: 991.98px) {
    .masonry li {
        height: 200px
    }
}

@media (max-width: 767.98px) {
    .masonry li {
        flex-basis: calc(100% / 2) !important;
        height: 160px !important
    }
}

.masonry li:nth-child(1) a, .masonry li:nth-child(7) a {
    width: calc(100% - 2px);
    height: calc(200% - 2px);
    position: absolute;
    left: 0;
    top: 0
}

.masonry li:nth-child(4), .masonry li:nth-child(8) {
    flex-basis: 100%
}

.masonry li:nth-child(4) a {
    margin-left: calc((100% / 3) + 1px)
}

.masonry li:nth-child(8) a {
    margin-right: calc((100% / 3) + 1px)
}

.masonry a {
    margin: 1px;
    text-align: center;
    text-decoration: none;
    position: relative;
    color: #fff;
    display: flex;
    flex: 1
}

@media (max-width: 767.98px) {
    .masonry a {
        width: auto !important;
        height: auto !important;
        margin: 1px !important;
        position: relative !important
    }
}

.masonry a:hover {
    text-decoration: none
}

.masonry a:hover img {
    transform: scale(1.04);
    opacity: 1
}

.masonry img {
    transition: opacity .2s, transform .3s;
    opacity: .5
}

.masonry-image {
    width: 100%;
    height: 100%;
    overflow: hidden;
    background-color: #000;
    position: absolute;
    z-index: 1;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0
}

.masonry-caption {
    width: 100%;
    min-width: 0;
    padding: 24px;
    align-items: center;
    justify-content: center;
    position: relative;
    flex-direction: column;
    flex-wrap: nowrap;
    overflow: hidden;
    display: flex;
    z-index: 2
}

@media (max-width: 575.98px) {
    .masonry-caption {
        padding: 0
    }
}

.masonry-caption:hover strong, .masonry-caption:hover span {
    transition: background-color .4s ease-in-out;
    background-color: #000
}

.masonry-caption strong, .masonry-caption span {
    padding: 4px 8px;
    transition: background-color .15s ease-in-out
}

.masonry-caption strong {
    margin-bottom: 8px;
    font-family: "opensans-semibold";
    font-size: 1.625rem
}

@media (max-width: 991.98px) {
    .masonry-caption strong {
        font-size: 1.4rem
    }
}

@media (max-width: 767.98px) {
    .masonry-caption strong {
        margin: 0;
        font-size: 1.1rem;
        background-color: transparent !important
    }
}

@media (max-width: 991.98px) {
    .masonry-caption span {
        font-size: .938rem
    }
}

@media (max-width: 767.98px) {
    .masonry-caption span {
        font-size: .875rem;
        background-color: transparent !important
    }
}

.cover {

    width: 100%;
    max-width: 100%;
    height: inherit;
    object-position: 50% 50%;
    object-fit: cover;
}
<!-- masonry starts -->
    <ul class="masonry">
        <li>
            <a href="" class="masonry-holder" title="">
                <div class="masonry-caption"><strong>Image title</strong><span>label</span></div>
                <div class="masonry-image"><img src="https://farm6.staticflickr.com/5594/15041847508_8e9ef380f9_z.jpg" rel="noindex" class="cover" width="360" height="240" alt=""></div>
            </a>
        </li>
        <li>
            <a href="" class="masonry-holder" title="">
                <div class="masonry-caption"><strong>Image title</strong><span>label</span></div>
                <div class="masonry-image"><img src="https://farm6.staticflickr.com/5559/15225339791_f01c6697b6_z.jpg" rel="noindex" class="cover" width="360" height="240" alt=""></div>
            </a>
        </li>
        <li>
            <a href="" class="masonry-holder" title="">
                <div class="masonry-caption"><strong>Image title</strong><span>label</span></div>
                <div class="masonry-image"><img src="https://farm4.staticflickr.com/3914/15041657969_ac472610cb_z.jpg" rel="noindex" class="cover" width="360" height="240" alt=""></div>
            </a>
        </li>
        <li>
            <a href="" class="masonry-holder" title="">
                <div class="masonry-caption"><strong>Image title</strong><span>label</span></div>
                <div class="masonry-image"><img src="https://farm6.staticflickr.com/5564/15041850517_00f9b6667f_z.jpg" rel="noindex" class="cover" width="360" height="240" alt=""></div>
            </a>
        </li>
        <li>
            <a href="" class="masonry-holder" title="">
                <div class="masonry-caption"><strong>Image title</strong><span>label</span></div>
                <div class="masonry-image"><img src="https://farm6.staticflickr.com/5591/15041649519_f9862e81c9_z.jpg" rel="noindex" class="cover" width="360" height="240" alt=""></div>
            </a>
        </li>
        <li>
            <a href="" class="masonry-holder" title="">
                <div class="masonry-caption"><strong>Image title</strong><span>label</span></div>
                <div class="masonry-image"><img src="https://farm6.staticflickr.com/5596/15228427075_a56b625397_z.jpg" rel="noindex" class="cover" width="360" height="240" alt=""></div>
            </a>
        </li>
        <li>
            <a href="" class="masonry-holder" title="">
                <div class="masonry-caption"><strong>Image title</strong><span>label</span></div>
                <div class="masonry-image"><img src="https://farm4.staticflickr.com/3917/15228055382_58c02657b8_z.jpg" rel="noindex" class="cover" width="360" height="240" alt=""></div>
            </a>
        </li>
        <li>
            <a href="" class="masonry-holder" title="">
                <div class="masonry-caption"><strong>Image title</strong><span>label</span></div>
                <div class="masonry-image"><img src="https://farm6.staticflickr.com/5553/15228056972_9b780d2891_z.jpg" rel="noindex" class="cover" width="360" height="240" alt=""></div>
            </a>
        </li>
    </ul>
<!-- masonry ends -->

Here's a responsive masonry grid made with flexbox, if someone else need a bit inspiration for their work.

Upvotes: 5

Asons
Asons

Reputation: 87303

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

Upvotes: 4

Shaik
Shaik

Reputation: 378

Use bootstrap Grid System

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Bootstrap Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> 
</head>
<body>
  <div class="col-md-12 col-sm-12 col-xs-12">

      <div class="col-md-4 col-sm-12 col-xs-12">
        <div class="pink">

        </div>
      </div>
      <div class="col-md-8 col-sm-12 col-xs-12">
        <div class="col-md-6 col-sm-6 col-xs-6">
          <div class="lightblue">

          </div>
        </div>
        <div class="col-md-6 col-sm-6 col-xs-6">
          <div class="lightblue">

          </div>
        </div>
    <div class="clearfix">

    </div>
    <div class="col-md-12 col-sm-12 col-xs-12">
       <div class="gray">

      </div>

    </div>

      </div>
  </div>

  <div class="col-md-12 col-sm-12 col-xs-12">
  <div class="col-md-8 col-sm-12 col-xs-12">
        <div class="col-md-6 col-sm-6 col-xs-6">
          <div class="lightblue">

          </div>
        </div>
        <div class="col-md-6 col-sm-6 col-xs-6">
          <div class="lightblue">

          </div>
        </div>
    <div class="clearfix">

    </div>
    <div class="col-md-12 col-sm-12 col-xs-12">
       <div class="gray">

      </div>

    </div>

      </div>
      <div class="col-md-4 col-sm-12 col-xs-12">
        <div class="pink">

        </div>
      </div>

  </div>
</body>

</html>

In CSS

.pink
{
  background-color:#FFB5FB;
  height:230px;
}
.lightblue
{
  background-color:#C6F4FE;
  height:100px;
}
.gray
{
  background-color:#B3EDAD;
  height:100px;
  margin:30px 0px;

}
.col, .col-1, .col-10, .col-11, .col-12, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-auto, .col-lg, .col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-auto, .col-md, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-auto, .col-sm, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-auto, .col-xl, .col-xl-1, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-auto
{
  padding-right: 3px;
    padding-left: 3px;
}

Here is the demo on Jsfiddle https://jsfiddle.net/d3aht26z/11/

Upvotes: 0

Related Questions