Can make same masonry with flex

hello,
i trying make layout look like masonry like below.


i did like https://jsfiddle.net/cb4dk6av/

<div class="product-are-container">
                <div class="category-wrapper">
                    <div class="category-header">
                        <h1>Header</h1>
                    </div>
                    <ul class="category-items">
                        <li class="item-wrapper">
                            <div class="item-row-1">
                                <div class="item-title">
                                    <h3>Item Title</h3>
                                    <div class="item-subtitle-wrapper">
                                        <i class="fas fa-calculator">1</i>
                                        <i class="fas fa-box-open">100</i>
                                    </div>
                                </div>
                                <div class="item-price">
                                    <span>500$</span>
                                </div>
                                <div class="item-order">
                                    <i class="zmdi zmdi-shopping-cart-plus"></i>
                                </div>
                            </div>
                        </li>
                    </ul>
                </div>
                ・・・・others items・・・・
            </div>
・・・・other elements・・・・
.product-are-container {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}
.category-wrapper {
  flex: 0.5fr;
  align-self: start;
}
・・・・other elements・・・・

it seem not ok. do you have anysuggestion to fix this problem?

You can’t really do masonry (automatically) with flexbox unless you want to set a height for the columns and have content running vertically rather than left to right. Although there are a number of demos showing masonry layouts using flexbox (or grid) they all rely on magic numbers (like the fixed height) and will break under real life usage (e.g.when a user resizes text or there is more content than expected).

A more solid approach is to use css columns but once again content will run down the column before filling the next column. It should however produce the required masonry effect.

e.g.

If you wanted to mess about with columns on your code you could try something like this.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
html {
  font-size: 62, 5%;
}
ul li {
  list-style: none;
  margin-left: 2.5rem;
}

.product-area {
  width: 90%;
  margin: auto;
}
.product-area-text {
  margin: 0.5rem auto;
  padding: 2rem auto;
}
.product-are-container {
  columns: 3 280px;/* 280px is the minimum width of the column*/
  column-gap: 1rem;
  font-size: 1.2rem;
}
.category-wrapper {
  display: inline-block; /* stops block being split across columns. Could use break-inside: avoid for modern browsers; */
  width: 100%;
  break-inside: avoid;
  text-align: center;
  font-weight: bold;
}

.product-area-text,
.category-header {
  text-align: center;
}
.category-header {
  font-size: 1rem;
  background-color: #f7f7f7;
}
.category-wrapper {
  margin: 0.5rem 0.5rem;
  border: 0.1rem solid #e2e2e2;
  border-radius: 0.3rem;
}
.item-wrapper {
  margin: 0;
  border-top: 0.1rem solid #e2e2e2;
}
.item-row-1,
.item-price,
.item-order {
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}
.item-row-1 {
  flex-direction: row;
  padding: 0.5rem;
  font-size: 0.8rem;

  .item-title {
    display: flex;
    justify-content: flex-start;
    flex: 1.5;
  }

  .item-price {
    flex: 0.5;
    color: white;
    padding: 0.3rem;
    font-size: 1rem;
    font-weight: 600;
    border-radius: 0.3rem;
    background-color: #86bc42;
  }
  .item-order {
    flex: 0.5;
  }
}
.item-title {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  .item-subtitle-wrapper {
    display: flex;
    width: 40%;
    justify-content: space-between;
    margin-top: 0.3rem;
  }
}

.item-row-1:hover {
  box-shadow: 0 0.3rem 1.5rem rgba(0, 0, 0, 0.06),
    0 -0.3rem 1.5rem rgba(0, 0, 0, 0.06);
  .item-price {
    color: #86bc42;
    background-color: white;
    border: 0.1rem solid #86bc42;
  }
}
.item-order > i {
  color: white;
  padding: 0.5rem;
  border-radius: 0.3rem;
  background-color: #86bc42;
}
.item-order > i:hover {
  color: #86bc42;
  background-color: white;
  border: 0.1rem solid #86bc42;
}

4 Likes

thanks you very much. It work for me.

1 Like