Masonry

Angular Bootstrap 5 Masonry component

Responsive masonry built with Angular Bootstrap 5. Masonry is a grid layout based on columns & it optimizes the use of space inside the web page by reducing any unnecessary gaps.

To learn more read Docs.


Basic layout

<div #container class="masonry-with-columns">
  <div style="order: 0">1</div>
  <div style="order: 1">2</div>
  <div style="order: 2">3</div>
  <div style="order: 0">4</div>
  <div style="order: 1">5</div>
  <div style="order: 2">6</div>
  <div style="order: 0">7</div>
  <div style="order: 1">8</div>
  <div style="order: 2">9</div>
  <div style="order: 0">10</div>
  <div style="order: 1">11</div>
  <div style="order: 2">12</div>
  <div style="order: 0">13</div>
  <div style="order: 1">14</div>
  <div style="order: 2">15</div>
</div>
body {
  margin: 0;
  padding: 1rem;
}

.masonry-with-columns {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
  -webkit-flex-wrap: wrap;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
  max-height: 1000px;
}

.masonry-with-columns div {
  -webkit-box-flex: 1;
  -webkit-flex: 1 0 auto;
  -ms-flex: 1 0 auto;
  flex: 1 0 auto;
  background: #00997b;
  color: white;
  margin: 0 1rem 1rem 0;
  text-align: center;
  font-weight: 900;
  font-size: 2rem;
}

.masonry-with-columns div:nth-child(1) {
  height: 163px;
  line-height: 163px;
}

.masonry-with-columns div:nth-child(2) {
  height: 495px;
  line-height: 495px;
}

.masonry-with-columns div:nth-child(3) {
  height: 120px;
  line-height: 120px;
}

.masonry-with-columns div:nth-child(4) {
  height: 309px;
  line-height: 309px;
}

.masonry-with-columns div:nth-child(5) {
  height: 317px;
  line-height: 317px;
}

.masonry-with-columns div:nth-child(6) {
  height: 277px;
  line-height: 277px;
}

.masonry-with-columns div:nth-child(7) {
  height: 339px;
  line-height: 339px;
}

.masonry-with-columns div:nth-child(8) {
  height: 491px;
  line-height: 491px;
}

.masonry-with-columns div:nth-child(9) {
  height: 281px;
  line-height: 281px;
}

.masonry-with-columns div:nth-child(10) {
  height: 499px;
  line-height: 499px;
}

.masonry-with-columns div:nth-child(11) {
  height: 490px;
  line-height: 490px;
}

.masonry-with-columns div:nth-child(12) {
  height: 289px;
  line-height: 289px;
}

.masonry-with-columns div:nth-child(13) {
  height: 356px;
  line-height: 356px;
}

.masonry-with-columns div:nth-child(14) {
  height: 406px;
  line-height: 406px;
}

.masonry-with-columns div:nth-child(15) {
  height: 196px;
  line-height: 196px;
}

.masonry-with-columns div:nth-child(16) {
  height: 237px;
  line-height: 237px;
}

.masonry-with-columns div:nth-child(17) {
  height: 367px;
  line-height: 367px;
}

.masonry-with-columns div:nth-child(18) {
  height: 472px;
  line-height: 472px;
}

.masonry-with-columns div:nth-child(19) {
  height: 413px;
  line-height: 413px;
}

.masonry-with-columns div:nth-child(20) {
  height: 337px;
  line-height: 337px;
}

.masonry-with-columns div:nth-child(21) {
  height: 406px;
  line-height: 406px;
}

.masonry-with-columns div:nth-child(22) {
  height: 368px;
  line-height: 368px;
}

.masonry-with-columns div:nth-child(23) {
  height: 130px;
  line-height: 130px;
}

.masonry-with-columns div:nth-child(24) {
  height: 209px;
  line-height: 209px;
}

.masonry-with-columns div:nth-child(25) {
  height: 203px;
  line-height: 203px;
}

.masonry-with-columns div:nth-child(26) {
  height: 368px;
  line-height: 368px;
}

.masonry-with-columns div:nth-child(27) {
  height: 163px;
  line-height: 163px;
}

.masonry-with-columns div:nth-child(28) {
  height: 418px;
  line-height: 418px;
}

.masonry-with-columns div:nth-child(29) {
  height: 123px;
  line-height: 123px;
}

.masonry-with-columns div:nth-child(30) {
  height: 256px;
  line-height: 256px;
}

.masonry-with-columns div:nth-child(31) {
  height: 196px;
  line-height: 196px;
}

.masonry-with-columns div:nth-child(32) {
  height: 224px;
  line-height: 224px;
}

.masonry-with-columns div:nth-child(33) {
  height: 122px;
  line-height: 122px;
}

.masonry-with-columns div:nth-child(34) {
  height: 303px;
  line-height: 303px;
}

.masonry-with-columns div:nth-child(35) {
  height: 159px;
  line-height: 159px;
}

.masonry-with-columns div:nth-child(36) {
  height: 320px;
  line-height: 320px;
}
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  title = 'mdb-angular-ui-kit-free';

  @ViewChild('container', { static: true }) container: ElementRef<HTMLElement>;

  ngOnInit() {
    this.setup();
  }

  setup() {
    const numCols = 3;
    const colHeights = Array(numCols).fill(0);
    const container = this.container.nativeElement;

    Array.from(container.children).forEach((child: any, i: number) => {
      const order = i % numCols;
      child.style.order = order;
      colHeights[order] += parseFloat(child.clientHeight);
    });
    container.style.height = Math.max(...colHeights) + "px";
  }
}

Horizontal option

<div class="masonry-with-columns-2" id="masonry-with-columns-2">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
  <div>9</div>
  <div>10</div>
  <div>11</div>
  <div>12</div>
  <div>13</div>
  <div>14</div>
  <div>15</div>
</div>
body {
  margin: 0;
  padding: 1rem;
}

.masonry-with-columns-2 {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-flex-wrap: wrap;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
}

.masonry-with-columns-2 div {
  height: 150px;
  line-height: 150px;
  background: #9b1b30;
  color: white;
  margin: 0 1rem 1rem 0;
  text-align: center;
  font-weight: 900;
  font-size: 2rem;
  -webkit-box-flex: 1;
  -webkit-flex: 1 0 auto;
  -ms-flex: 1 0 auto;
  flex: 1 0 auto;
}

.masonry-with-columns-2 div:nth-child(1) {
  width: 222px;
}

.masonry-with-columns-2 div:nth-child(2) {
  width: 102px;
}

.masonry-with-columns-2 div:nth-child(3) {
  width: 155px;
}

.masonry-with-columns-2 div:nth-child(4) {
  width: 365px;
}

.masonry-with-columns-2 div:nth-child(5) {
  width: 132px;
}

.masonry-with-columns-2 div:nth-child(6) {
  width: 106px;
}

.masonry-with-columns-2 div:nth-child(7) {
  width: 199px;
}

.masonry-with-columns-2 div:nth-child(8) {
  width: 164px;
}

.masonry-with-columns-2 div:nth-child(9) {
  width: 424px;
}

.masonry-with-columns-2 div:nth-child(10) {
  width: 467px;
}

.masonry-with-columns-2 div:nth-child(11) {
  width: 350px;
}

.masonry-with-columns-2 div:nth-child(12) {
  width: 168px;
}

.masonry-with-columns-2 div:nth-child(13) {
  width: 296px;
}

.masonry-with-columns-2 div:nth-child(14) {
  width: 440px;
}

.masonry-with-columns-2 div:nth-child(15) {
  width: 110px;
}

.masonry-with-columns-2 div:nth-child(16) {
  width: 413px;
}

.masonry-with-columns-2 div:nth-child(17) {
  width: 333px;
}

.masonry-with-columns-2 div:nth-child(18) {
  width: 441px;
}

.masonry-with-columns-2 div:nth-child(19) {
  width: 74px;
}

.masonry-with-columns-2 div:nth-child(20) {
  width: 122px;
}

.masonry-with-columns-2 div:nth-child(21) {
  width: 189px;
}

.masonry-with-columns-2 div:nth-child(22) {
  width: 91px;
}

.masonry-with-columns-2 div:nth-child(23) {
  width: 269px;
}

.masonry-with-columns-2 div:nth-child(24) {
  width: 394px;
}

.masonry-with-columns-2 div:nth-child(25) {
  width: 139px;
}

.masonry-with-columns-2 div:nth-child(26) {
  width: 240px;
}

.masonry-with-columns-2 div:nth-child(27) {
  width: 184px;
}

.masonry-with-columns-2 div:nth-child(28) {
  width: 261px;
}

.masonry-with-columns-2 div:nth-child(29) {
  width: 358px;
}

.masonry-with-columns-2 div:nth-child(30) {
  width: 393px;
}

.masonry-with-columns-2 div:nth-child(31) {
  width: 370px;
}

.masonry-with-columns-2 div:nth-child(32) {
  width: 399px;
}

.masonry-with-columns-2 div:nth-child(33) {
  width: 263px;
}

.masonry-with-columns-2 div:nth-child(34) {
  width: 135px;
}

.masonry-with-columns-2 div:nth-child(35) {
  width: 221px;
}

.masonry-with-columns-2 div:nth-child(36) {
  width: 233px;
}

Flexbox option

<div class="masonry-with-flex">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
  <div>9</div>
  <div>10</div>
  <div>11</div>
  <div>12</div>
  <div>13</div>
  <div>14</div>
  <div>15</div>
</div>
body {
  margin: 0;
  padding: 1rem;
}

.masonry-with-flex {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
  -webkit-flex-wrap: wrap;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
  max-height: 1000px;
}

.masonry-with-flex div {
  width: auto;
  background: #975a58;
  color: white;
  margin: 0 1rem 1rem 0;
  text-align: center;
  font-weight: 900;
  font-size: 2rem;
}

.masonry-with-flex div:nth-child(1) {
  height: 334px;
  line-height: 334px;
}

.masonry-with-flex div:nth-child(2) {
  height: 428px;
  line-height: 428px;
}

.masonry-with-flex div:nth-child(3) {
  height: 432px;
  line-height: 432px;
}

.masonry-with-flex div:nth-child(4) {
  height: 292px;
  line-height: 292px;
}

.masonry-with-flex div:nth-child(5) {
  height: 312px;
  line-height: 312px;
}

.masonry-with-flex div:nth-child(6) {
  height: 191px;
  line-height: 191px;
}

.masonry-with-flex div:nth-child(7) {
  height: 302px;
  line-height: 302px;
}

.masonry-with-flex div:nth-child(8) {
  height: 224px;
  line-height: 224px;
}

.masonry-with-flex div:nth-child(9) {
  height: 475px;
  line-height: 475px;
}

.masonry-with-flex div:nth-child(10) {
  height: 440px;
  line-height: 440px;
}

.masonry-with-flex div:nth-child(11) {
  height: 426px;
  line-height: 426px;
}

.masonry-with-flex div:nth-child(12) {
  height: 362px;
  line-height: 362px;
}

.masonry-with-flex div:nth-child(13) {
  height: 129px;
  line-height: 129px;
}

.masonry-with-flex div:nth-child(14) {
  height: 344px;
  line-height: 344px;
}

.masonry-with-flex div:nth-child(15) {
  height: 236px;
  line-height: 236px;
}

.masonry-with-flex div:nth-child(16) {
  height: 378px;
  line-height: 378px;
}

.masonry-with-flex div:nth-child(17) {
  height: 312px;
  line-height: 312px;
}

.masonry-with-flex div:nth-child(18) {
  height: 172px;
  line-height: 172px;
}

.masonry-with-flex div:nth-child(19) {
  height: 474px;
  line-height: 474px;
}

.masonry-with-flex div:nth-child(20) {
  height: 252px;
  line-height: 252px;
}

.masonry-with-flex div:nth-child(21) {
  height: 355px;
  line-height: 355px;
}

.masonry-with-flex div:nth-child(22) {
  height: 401px;
  line-height: 401px;
}

.masonry-with-flex div:nth-child(23) {
  height: 369px;
  line-height: 369px;
}

.masonry-with-flex div:nth-child(24) {
  height: 449px;
  line-height: 449px;
}

.masonry-with-flex div:nth-child(25) {
  height: 411px;
  line-height: 411px;
}

.masonry-with-flex div:nth-child(26) {
  height: 122px;
  line-height: 122px;
}

.masonry-with-flex div:nth-child(27) {
  height: 262px;
  line-height: 262px;
}

.masonry-with-flex div:nth-child(28) {
  height: 154px;
  line-height: 154px;
}

.masonry-with-flex div:nth-child(29) {
  height: 308px;
  line-height: 308px;
}

.masonry-with-flex div:nth-child(30) {
  height: 327px;
  line-height: 327px;
}

.masonry-with-flex div:nth-child(31) {
  height: 374px;
  line-height: 374px;
}

.masonry-with-flex div:nth-child(32) {
  height: 106px;
  line-height: 106px;
}

.masonry-with-flex div:nth-child(33) {
  height: 340px;
  line-height: 340px;
}

.masonry-with-flex div:nth-child(34) {
  height: 492px;
  line-height: 492px;
}

.masonry-with-flex div:nth-child(35) {
  height: 475px;
  line-height: 475px;
}

.masonry-with-flex div:nth-child(36) {
  height: 373px;
  line-height: 373px;
}
import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'mdb-angular-ui-kit-free';
}

Images option

<div #container class="masonry-with-flex masonry-with-columns" style="max-height: 1200px">
  <img src="https://mdbootstrap.com/img/Photos/Others/food3.webp" style="width: 33.3%" />
  <img src="https://mdbootstrap.com/img/Photos/Others/image06.webp" style="width: 33.3%" />
  <img src="https://mdbootstrap.com/img/Photos/Others/image17.webp" style="width: 33.3%" />
  <img src="https://mdbootstrap.com/img/Photos/Others/image02.webp" style="width: 33.3%" />
  <img src="https://mdbootstrap.com/img/Photos/Others/image008.webp" style="width: 33.3%" />
  <img src="https://mdbootstrap.com/img/Photos/Others/image010.webp" style="width: 33.3%" />
  <img src="https://mdbootstrap.com/img/Photos/Others/image002.webp" style="width: 33.3%" />
  <img src="https://mdbootstrap.com/img/Photos/Others/image005.webp" style="width: 33.3%" />
  <img src="https://mdbootstrap.com/img/Photos/Others/image18.webp" style="width: 33.3%" />
</div>
.masonry-with-columns,
.masonry-with-flex {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
  -webkit-flex-wrap: wrap;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
}

.masonry-with-columns div {
  -webkit-box-flex: 1;
  -webkit-flex: 1 0 auto;
  -ms-flex: 1 0 auto;
  flex: 1 0 auto;
}
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  title = 'mdb-angular-ui-kit-free';

  @ViewChild('container', { static: true }) container: ElementRef<HTMLElement>;

  ngOnInit() {
    this.setup();
  }

  setup() {
    const container = this.container.nativeElement;

    Array.from(container.children).forEach((child: any, i) => {
      const order = i % 3;
      child.style.order = order;
    });
  }
}