ThomasFromUganda
ThomasFromUganda

Reputation: 410

How to programmatically add a css rule to an element

I am using Angular 6 and Typescript. Here's my issue. I need to add a specific CSS rule to the host of a component that I am writing. I cannot apply that rule systematically, I need to have some logic in ngOnInit() before adding my rule. I know this sounds like bad practice, but there are no workarounds and this is the only way I can solve the problem I am facing. I can easily add classes on new styles to my host, but I cannot seem to find a way to add a rule.

Some people have been marking my question as a duplicate. Please read my question carefully. I am not trying to add a class, I am trying to a add a RULE. This is very different and there are no results for such question.

Here's the two rules I have that I want to add to my host element depending on some condition:

custom-component + custom-component > .vertical-component {
    margin-top: 1rem;
}

and

custom-component + custom-component > .horizontal-component {
    margin-left: 1rem;
}

In my component code, I have something like this:

export class CustomComponent {
    public constructor(private host: ElementRef, private renderer: Renderer2) {

    }

    public applyStylesToHost(): void {
        if (this.variant == TYPE.VERTICAL) {
            // Set the rule with the margin-top
        } else {
            // Set the rule with the margin-left
        }
    }
}

I was looking for a method like this.renderer.setRule(), but there is no such thing. How can I programmatically add a specific rule to my host element?

The closest thing I found is this link. The author suggest doing document.createElement("style").sheet.addRule(), but when I tried to do it, the method addRule didn't exist on the sheet element.

Upvotes: 0

Views: 1357

Answers (3)

Kamil Szot
Kamil Szot

Reputation: 17817

Could you just add them as <style> tag to the whole document?

var st = document.createElement('style'); 
st.appendChild(document.createTextNode(`
    custom-component + custom-component > .vertical-component {
        margin-top: 1rem;
    }
`));  
document.head.appendChild(st);

Upvotes: 0

Serkus
Serkus

Reputation: 31

If you want to go this way, you should use probably method:

renderer.setStyle(...)

or

renderer.addClass(...)
renderer.removeClass(...)

I suggest to read documentation for Renderer2

Upvotes: 2

Michael Dimmitt
Michael Dimmitt

Reputation: 1054

As Balastrong mentions you could use ngClass logicFinished = false

ngOnInit() {
  ... your logic
  this.logicFinished = true
}

[ngClass]="{'vertical-component': logicFinished, 'horizontal-component': !logicFinished}"

Alternative javascript hack to fix the problem.

this.yourElement = document.getElementById('yourElement') as HTMLElement
this.yourElement.style.margin = '1rem 0 0 0'
this.yourElement.style.margin = '0 0 0 1rem'

But NgClass seems a better solution for the problem.

Upvotes: 1

Related Questions