Reputation: 53
I would like to know if it's possible to style a component through the 'styles' property of angular's @component object.
Here is an example of what I'm trying to achieve, pay attention to the {{ratio}} variable in 'styles' property.
@Component({
selector: 'img-thumb',
templateUrl: './img-thumb.component.html',
styleUrls: ['./img-thumb.component.css'],
styles: [`
:host:after{
content: '';
display: block;
padding-bottom: {{ratio}};
}
`],
host: {
'[style.height.px]' : 'height',
'[style.padding.px]' : 'gap'
}
})
export class ImgThumbComponent implements OnInit {
@Input() height : any
@Input() gap : any
@Input() ratio : any
//More code...
}
Basically I'm trying to implement :after on the host with a variable. If it's possible, I prefer to implement it inside the .ts file of the component.
Upvotes: 1
Views: 2038
Reputation: 1121
As it is not possible to add inline pseudo-element styles, one workaround would be to use Angular's renderer2 methods to create a new <style>
tag and append it to the DOM at runtime. Here's a component:
import { Component, ElementRef, ViewChild, OnInit, Renderer2 } from '@angular/core';
@Component({
selector: 'app-component',
template: '<div #stylesContainer></div>'
})
export class singleComp implements OnInit{
// Get destination container
@ViewChild("stylesContainer") private stylesDist: ElementRef;
// Define variable values
height: string = "150px";
gap: string = "30px";
ratio: string = "10px";
// Create the actual CSS style and store it in variables
styleClass = ".class{ height: "+this.height+"; padding: "+this.gap+"}";
pseudoStyle = ".class:after{content: '';display: block;padding-bottom: "+this.ratio+"}";
constructor(private renderer: Renderer2) {}
ngOnInit() {
// Dynamically create the CSS tags
const classStyle = this.renderer.createText(this.styleClass);
const pseudoElementStyle = this.renderer.createText(this.pseudoStyle);
// Insert the previously defined style into a new <style> element
const newStyleElement = this.renderer.createElement('style');
this.renderer.appendChild(newStyleElement, classStyle);
this.renderer.appendChild(newStyleElement, pseudoElementStyle);
this.renderer.appendChild(this.stylesDist.nativeElement, newStyleElement);
}
}
In the component above the variables height
, gap
and ratio
are hardcoded, but you can get them via @input. The HTML template contains a div
with the local reference #stylesContainer
this will be the destination element on where to dynamically append the styles.
When the component initialises, it generates a new <style>
tag containing the dynamic styles including the pseudo-element ones. Then using the Renderer2 from Angular, it appends the new <style>
tag back into the <div #stylesContainer>
which you get from using @ViewChild
Upvotes: 1