0

I have plenty of Angular mat-cards i.e. uncertain number of cards with images of different sizes.

What i am trying implement is a auto fill and adjustment of such cards depending on the container, something like this.

enter image description here

Now example above is using 4 columns and possible using grid.

Now, how do I implement that with cards? I tried using flex but somehow not able to properly implement it. Here's my worthless try.

<div class="mat-card-container" style="
display: flex;
justify-content: center;    /* Add this */
flex-wrap: wrap;

">
<div class="mat-card-holder" style="
margin:0.6em;
width:220px;
" *ngFor="let art of arts.records">
    <mat-card class="art-card" >
      <mat-card-header>
        <mat-card-title>{{ art.TITLE }}</mat-card-title>
        <mat-card-subtitle>{{ art.AUTHOR }}</mat-card-subtitle>
      </mat-card-header>
      <img mat-card-image src="http://localhost/piwigo/{{ art.URL }}" alt="Photo of a Shiba Inu">
      <mat-card-content>
          {{art.TECHNIQUE}} / {{art.SCHOOL}} / {{art.FORM}} / {{art.TYPE}} / {{art.LOCATION}}
      </mat-card-content>
    </mat-card>
</div>
</div>

This is giving me this much, but still there are alot of gaps to be covered.

enter image description here

This is only lining them up in columns, how to i dynamically fill and adjust these in container? Assuming if container size changes, cards should rearrange without changing their own css i.e. dimensions. Is my code correct uptill? And how do i fill the gap in between?

Mercurial
  • 3,615
  • 5
  • 27
  • 52

1 Answers1

0

To the extend of my knowledge, this layout style you are looking to implement cannot be achieved by css in of itself.

With some help from a javascript helper library, this is easily implemented. As you are using Angular, this is an Angular wrapper to the previous library which will permit to do such a design.

Replying from my phone and can't really reproduce your exact ui, but copying verbatim here their example implementation,

App.module.ts

import { MasonryModule } from '@thisissoon/angular-masonry';

const masonryProviders = [
  { provide: Masonry, useFactory: () => window['Masonry'] },
];

@NgModule({
  imports: [MasonryModule.forRoot(masonryProviders)],
})
export class AppModule {}

angular.json

"scripts": [
  "../node_modules/masonry-layout/dist/masonry.pkgd.js"
],

app.component.ts

export class AppComponent implements AfterViewInit, OnDestroy {
  @ViewChild('grid') public grid: ElementRef;

  public masonryInstance: MasonryInstance;

  public cards = cards;

  constructor(@Inject(Masonry) public masonry) {}

  ngAfterViewInit() {
    const options: MasonryOptions = {
      itemSelector: '.card',
      columnWidth: '.card',
      gutter: 20,
      fitWidth: true,
    };
    this.masonryInstance = new this.masonry(this.grid.nativeElement, options);
  }

  layout() {
    this.masonryInstance.layout();
  }

  ngOnDestroy() {
    this.masonryInstance.destroy();
  }
}

app.component.css

:host {
  display: block;
  margin-top: 1rem;
}

.grid {
  margin: 0 auto;
}

.card {
  display: inline-block;
  margin-bottom: 1rem;
  width: 18rem;
}

app.component.html

<div class="grid" #grid>
  <div class="card" *ngFor="let card of cards">
    <div class="card-body">
      <h5 class="card-title">{{ card.title }}</h5>
      <p class="card-text">{{ card.text }}</p>
      <a href="#" class="btn btn-primary">Go somewhere</a>
    </div>
  </div>
</div>
  • Thanks for pointing me in right direction, I ended up using [this](https://www.npmjs.com/package/ngx-masonry) library instead (I am a lazy bum). However, [this](https://github.com/klederson/angular-masonry-directive) is pretty simple lightweight library too. – Mercurial Sep 29 '19 at 13:38
  • How do i call the `layout()` function of ngx-gallery. I don't seem to be able to fetch that. – Mercurial Sep 29 '19 at 16:04