0

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.

5
  • 1
    Does this answer your question? Angular: conditional class with *ngClass Commented May 29, 2020 at 12:25
  • @Balastrong No, the question you linked is regarding classes. I want to add a specific rule, which I have provided in the code. The closest thing I found is this: davidwalsh.name/add-rules-stylesheets However, it does not work for some reason. The method addRule() on style.sheet doesn't exist. Commented May 29, 2020 at 12:31
  • Are you looking for HostBinding? stackoverflow.com/questions/35168683/… Commented May 29, 2020 at 12:35
  • @Eliseo Not really. I already found how to apply classes or styles to host. My issue is that this is the selector I want to add custom-component + custom-component > .horizontal-component . In plain English, I my custom-component can either by of type 'vertical' or 'horizontal'. If it is vertical, then I want to add margin-top to my host only if it is preceded by an other custom-component. Commented May 29, 2020 at 12:39
  • How to modify attributes classes and styles in the dom digitalocean.com/community/tutorials/… Commented May 29, 2020 at 12:48

3 Answers 3

2

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

Sign up to request clarification or add additional context in comments.

Comments

1

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.

1 Comment

Unfortunately, this will not solve my issue. As mentionned, I am not trying to add a class, I am trying to add a rule with a specific selector. You can find what are the two rules I want to add conditonnally, but there are not simple classes.
0

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);

1 Comment

I think he is trying to have the child element influence the parent element. By modifying the css class.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.