0

i don't know how I can insert css code into my angular component.

let sheet: any = document.createElement('style');
sheet.type = "text/css";
sheet.textContent = `\n @keyframes ${this.config.animationConfig.name} { from { ${this.config.animationConfig.steps[0]} } to { ${this.config.animationConfig.steps[1]} } }`;

best regards and thank you for your help

Jonaz

1
  • just add it to html head. there is no way to apply angular encapsulation to dynamic styles, because it should happen during compilation phase of project Commented Nov 20, 2020 at 9:09

2 Answers 2

0

This is just an example implementation - there might be easier / better way to do this, but it should be a good starting point for you.

First, grab the reference to some element on your template:

@ViewChild('someDivElement', {static: true}) stylesContainer: ElementRef;

Then, each time you need to recalculate styles you can do something like this:

  private changeStyles(): void {
    const styleContent = this.getSomeStyleContent(); // This should be a string value of what you would put inside the <style> element.

    // Get the native element from the container reference
    const placeholderElement: HTMLDivElement = this.stylesContainer.nativeElement;

    // If there is already element in it, remove it. If you need something else than styles in that component,
    // query the item differently, e.g. by type.
    if (placeholderElement.firstChild) {
      placeholderElement.removeChild(placeholderElement.firstChild);
    }

    // Add your styles inside the placeholder.
    placeholderElement.insertAdjacentHTML('afterbegin', `<style>${styles}</style>`);
  }

Note that this is NOT encapsulated, meaning it will affect html on whole site, not only within that component. Also note that it will force a reflow (or two if there were previous styles) but there's not much we can about it.

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

5 Comments

Does this also work with Mat-Components, for example <mat-button></mat-button>
It's not encapsulated, so if you add styles properly then it should. Though perhaps an easier solution would be using ngStyle, ngClass or some other approach?
I also thought on ngStyle or ng Class but the problem is, that I want to insert css keyframe animation and the angular animation system is based on js and therefore to slow.
Not sure what your usecase is, plus I'm not great at CSS and animations, but perhaps you could leverage hardcoding animations themselves and only updating the CSS variables through bindings? Seems much cleaner than actually inserting containers with styles into the template. For example - check this answer: stackoverflow.com/a/63506012/4550158 (and linked github issue if you're not using Angular 9+ yet - thinks it has some workarounds).
I understand what you mean, but in our project the customer will handle everything, included the whole structure of the keyframe animation. Thats the reason, why I asked how I can inject css animation into the component, but my supervisor is fine with the answer above. Thank you for your help!
0

Does this also work with Mat-Components, for example

// Get the native element from the container reference
    const placeholderElement: HTMLDivElement = this.stylesContainer.nativeElement;

    // If there is already element in it, remove it. If you need something else than styles in that component,
    // query the item differently, e.g. by type.
    if (placeholderElement.firstChild) {
      placeholderElement.removeChild(placeholderElement.firstChild);
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.