DEV Community

Jason F
Jason F

Posted on

Dynamically change number of columns in a grid using ngStyle

Today I'll show you how I used ngStyle along with CSS grid to create a resizeable grid.

Alt Text

ngStyle For The Win

ngStyle is a built-in attribute directive that lets you set styles by binding to an expression such as a function.

Here in my card-container.component.html I am binding to my getStyles method.



  <div class="cards-grid" [ngStyle]="getStyles()">
    <app-card
      *ngFor="let band of bands; index as i"
      [bandData]="bands[i]"
    ></app-card>
  </div>


Enter fullscreen mode Exit fullscreen mode

This getStyles in my card-container.component.ts method returns an object with my defined styles. The magic is in the grid-template-columns value. I am using string interpolation to pass in a property called columns.



 public getStyles() {
    return {
      display: 'grid',
      'grid-template-columns': `repeat(${this.columns}, 1fr)`,
      'justify-items': 'center',
    };
  }


Enter fullscreen mode Exit fullscreen mode

If we look at the entire card-container.component.html component, you will see that I'm using an input and this is where the value for the columns property comes from.



<div class="card-container">
  <div class="cards-header">
    <mat-form-field>
      <mat-label>Columns</mat-label>
      <input matInput type="number" min="1" max="5" [(ngModel)]="columns" />
    </mat-form-field>
  </div>
  <div class="cards-grid" [ngStyle]="getStyles()">
    <app-card
      *ngFor="let band of bands; index as i"
      [bandData]="bands[i]"
    ></app-card>
  </div>
</div>


Enter fullscreen mode Exit fullscreen mode

If we look at the entire card-container.component.ts file you will see that I initialize the columns property to 4.



import { Component, OnInit } from '@angular/core';
import * as bandData from './powermetal.json';

@Component({
selector: 'app-card-container',
templateUrl: './card-container.component.html',
styleUrls: ['./card-container.component.scss'],
})
export class CardContainerComponent implements OnInit {
public columns: number = 4;
public bands: any = (bandData as any).default;

constructor() {}
ngOnInit(): void {}

public getStyles() {
return {
display: 'grid',
'grid-template-columns': repeat(</span><span class="p">${</span><span class="k">this</span><span class="p">.</span><span class="nx">columns</span><span class="p">}</span><span class="s2">, 1fr),
'justify-items': 'center',
};
}
}

Enter fullscreen mode Exit fullscreen mode




Thoughts?

I'd love you hear your thoughts on this. I don't think you would want to use an input like I'm doing here. The number of columns could go in to a settings page, or wherever else it fits in to the application.

Repository

If you want to see the code, you can check it out here.

Top comments (0)