I am fairly new to Angular and came from React.js background.
I have made a simple grid component like below:
grid.component.js
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'app-grid',
template: `
<div [ngStyle]="styles()" [ngClass]="passClass">
<ng-content></ng-content>
</div>
`,
styles: [`
div {
display: flex;
}
`]
})
export class GridComponent implements OnInit {
@Input() direction: string;
@Input() justify: string;
@Input() align: string;
@Input() width: string;
@Input() passClass: string;
constructor() { }
ngOnInit() {
}
styles() {
return {
'flex-direction': this.direction || 'row',
'justify-content': this.justify || 'flex-start',
'align-items': this.align || 'flex-start',
...(this.width && { width: this.width })
};
}
}
And I want to use it in other components like below:
aboutus.component.html
<app-grid passClass="about-us page-container">
<app-grid direction="column" passClass="left">
<div class="title blue bold">
An open community For Everyone
</div>
<div class="large-desc grey">
This conference is brought to you by
the Go Language Community in
India together with the Emerging
Technology Trust (ETT). ETT is a non-
profit organization, established to
organize and conduct technology
conferences in India. It’s current
portfolio includes
</div>
</app-grid>
</app-grid>
aboutus.component.sass
.about-us
position: relative
.left
width: 50%
&:after
bottom: 0
right: 0
z-index: 0
margin-right: -5vw
position: absolute
content: url(../../assets/images/footer.svg)
But, what happens is the CSS attached with the second component will not work.
I know a little bit about CSS isolation but could not understand if it affects here.
P.S.: Please feel free to provide feedback to things outside of scope this question as well.
It is not possible to pass CSS classes as variables in your template. So if your expectation in aboutus.component.html
was to be able to pass the left
CSS class as a variable in your template, that will not work.
There are a few things I can point out that will hopefully help:
If you want to modify a CSS class that is internal to a component from outside that component, one option is to use ng-deep.
In your particular case, I don't think ng-deep
is necessary. I'd suggest to drop the div
element within the app-grid
component and instead apply the styles to the host element using @HostBinding
decorator. With that approach you can drop the passCss
altogether because now wherever you use yourapp-grid
component you can style that component in CSS using the app-grid
selector.
grid.component.ts:
import { Component, OnInit, Input, HostBinding, SafeStyle } from '@angular/core';
@Component({
selector: 'app-grid',
template: `<ng-content></ng-content>`,
styles: [`
:host {
display: flex;
}
`]
})
export class GridComponent implements OnInit {
@Input() direction: string;
@Input() justify: string;
@Input() align: string;
@Input() width: string;
constructor(private sanitizer:DomSanitizer) { }
ngOnInit() {
}
@HostBinding('style')
styles(): SafeStyle {
const styles = `
flex-direction: ${this.direction || 'row'};
justify-content: ${this.justify || 'flex-start'};
align-items: ${this.align || 'flex-start'};
`;
return this.sanitizer.bypassSecurityTrustStyle(styles);
}
}
aboutus.component.sass:
app-grid {
// You can style the host element of a component
// just like any native HTML element and without
// needing to use `ng-deep`
}
You may also want to look into CSS Custom Properties. Custom CSS properties are not shielded by view-encapsulation. This gives you the ability to create a CSS API for a component, if you will, and those properties can be used anywhere within a component.
aboutus.component.sass
app-grid {
--image: url(../../assets/images/footer.svg)
}
grid.component.sass
div {
content: var(--image);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With