DEV Community

John Peters
John Peters

Posted on • Updated on

Angular CSS using Directives only

Directives Instead of CSS

CSS is messy for sure, hard to refactor and it's everywhere. What if we can encapsulate CSS into Directives making them dynamically adhere to input parameters?

import { Directive, ElementRef, Input, OnInit } from "@angular/core";

@Directive({
   selector: "[appGrid]",
})
export class GridDirective implements OnInit {
   /** Enter number as string; units are em */
   @Input() minWidth: string = "5em";
   /** Enter number as string; units are fr */
   @Input() maxWidth: string = "1fr";
   /** Just put in number units are in em */
   @Input() columnGap: string = "0.5em";

   constructor(private elementRef: ElementRef) {}

   ngOnInit() {
      let css = `
     display: grid;
     grid-template-columns: repeat(auto-fit, minmax(${this.minWidth},${this.maxWidth}));
     grid-column-gap: ${this.columnGap};`;
      this.elementRef.nativeElement.setAttribute("style", css);
   }
}
Enter fullscreen mode Exit fullscreen mode

It currently only supports Columns, but is easily changed to do other things. Because it uses auto-fit the number of columns are 100% fluid meaning they shrink and expand based on the width of the window. No media queries necessary. All the @Inputs have default values so everything works out-of-the-box. However, the minmax values are able to be injected from the user of the directive.

How do we use it?

Simply add "appGrid" into any HTML container tag, like this:

<div appGrid>
  //each successive html container is a candidate for its own column
</div>
Enter fullscreen mode Exit fullscreen mode

Take away: What you see above is the replacement of using the class attribute and any back-end specific styles. Because of intellisense, we can right click on appGrid and "go to definition" at any time. It's just a better way to effect styling all around.

View Encapsulation is unaffected by this.

Coming up: Adding More function to the Angular Grid Directive...

JWP2020

Top comments (0)