Angular & CSS Grid: Dynamic Grid Properties

Angular @HostBinding with CSS Grid

Introduction

Source Code / Live Demo: StackBlitz 🚀

Article Goal: Investigate one way to dynamically modify CSS Grid Properties using Angular’s @HostBinding Decorator.

Article Topics:

Use CSS-Grid with Angular Components by leveraging the :host selector

with by leveraging the selector How to adjust CSS Grid Properties such as column-template-rows and gap with TypeScript dynamically.

such as and with dynamically. Angular’s DOM Sanitizer, why we have to bypass security and some guidelines we should follow when doing so.

Our Application

CSS Grid (Container and Items)

Our CSS Grid will be composed of two Angular components. A parent/container and a child/item. CSS Grid is a relatively new convention for writing CSS that allows us to build reactive grids to place and align elements.

Using the :host selector, Angular Components can select themselves. We can use this concept to treat our components as a grid-container or a grid-item and avoid using wrapper divs . 🎁

display: grid : Defines the element as a grid-container

: Defines the element as a grid-container grid-template-rows : Defines a maximum number of rows and row-size

: Defines a maximum number of rows and row-size grid-auto-flow: column : Tells the grid to create a new column (Instead of a new row) when it runs out of space vertically .

: Tells the grid to create a (Instead of a new row) when it runs out of space . gap : Defines space between each item.

In our example, each row will take up 1 fraction of the space. Since we have specified 3 rows in our case repeat(3, 1fr) , each row will take 1/3 the height of the div. Our columns will take up space based on context size.

CSS Grid Tip 💎

Want to center something like the content in our grid-items? Make the grid-item it’s own grid-container and leverage justify-items and align-items .

.grid-item-class-name {

display: grid;

justify-items: center;

align-items: center;

}

HostBinding

Now that we have a basic understanding of our Grid we can access the CSS Properties in our Angular Component Class.

Host binding allows us to access and apply CSS styles and classes on our component. — I like to think of this as updating properties on the :host selector via TypeScript.

Updating our HostBinding variable will change the CSS Property value on the component. We can hook this up to an event to allow the user to update our grid.

Angular Tip 💎

We can also add and remove classes using @HostBinding

export class MyComponent {

@HostBinding('class.is-valid')

get validValue() { return this.value.valid; }

}

Handling Events

Now that Angular and CSS Grid have been married by HostBinding. We will allow the user (with restriction) to update grid-template-columns and gap .

Using an Angular Directive is an easy way to allow sibling components to communicate with each other. On button click, we will send an event to the container to update the host binding.

The snippet above accomplishes the following

Subscribes to gap updates, updating the gap by 5px on event, which will increase or decrease the spacing between grid-items

on event, which will increase or decrease the spacing between grid-items Subscribes to row updates, updating the first parameter in repeat() by 1, which will increase or decrease the number of rows in our grid.

by 1, which will increase or decrease the number of rows in our grid. Validate gap and rows to make sure we don’t go below 1 row or 0 gap.

Uses the DOM Sanitizer to allow us to pass style as a String.

The source for the buttons and directive can be found on StackBlitz; they are straight-forward and small. — The container does all the heavy lifting. 🏋️‍♀️

Angular Tip 💎

If a parent has a directive, all of the parent’s children can inject that directive instance in their Typescript Class.

<!-- HTML -->

<app-container appConnector>

<app-item id="Hello"></app-item>

<app-item id="2"></app-item>

<app-item id="3"></app-item>

</app-container> /* TypeScript */

export class ItemComponent {

constructor(public appConnector: ConnectorDirective) {

this.appConnector.eventEmitter.subscribe(...)

}

}

DOM Sanitizer

There are many articles and resources on learning about Angular’s DOM Sanitizer.

Without the use of bypassSecurityTrustStyle

Here is my short take on it. If we lock-down where the user can send input and what input the user can send, it can be considered “safe” to bypass Angular’s DOM Sanitizer. 🧼

We allow the user to update the first parameter in the CSS repeat() function (where). We restrict the user’s input to a button click; we control the value a click produces (what). 🔐

Conclusion

Angular :host Selector enables us to treat components as css-grids or css-grid-items

Selector enables us to treat components as css-grids or css-grid-items Angular @HostBinding Decorator allows us to access and update CSS classes and styles

Decorator allows us to access and update CSS classes and styles Angular sanitizes potentially dangerous updates to the DOM. We should think about where and what we allow users to update when by-passing this functionality.

and we allow users to update when by-passing this functionality. Thanks for reading! 🎉

Resources