Today, I was trying to figure out how to dynamically load CSS in an Angular 5 application and found out a workable solution. In this short post, I will show you how I managed to do that.
Let’s start by creating a new Angular application.
$ ng new myapp
This will scaffold a new Angular application.
Next, we will update the app.component.html
with the following markup.
<h1>Working with dynamic CSS loading -:)</h1>
Now, we want to change colour of h1 tag to green if random number is even else it should be red. It is a simple example but it will show how to do it.
Let’s update the app.component.ts
so that it exposed one property cssUrl
.
import { Component, OnInit, isDevMode } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { cssUrl: string; constructor(public sanitizer: DomSanitizer) { } ngOnInit() { const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; const n = randomIntegerInRange(1, 100) % 2; this.cssUrl = n % 2 === 0 ? '/assets/styles1.css' : '/assets/styles2.css'; } }
The code shown above does the following:
- It implements OnInit lifecycle hook. This hook is called before component is rendered.
- We set
cssUrl
value tostyles1.css
if number is even else we set it tostyles2.css
.
Next, we need to create two css files in assets
directory. The advantage of keeping css in assets directory is that they will not be packaged in the application package. Thus, keeping package size in check.
Following are the contents of styles1.css
h1 { color: green; }
Following are the contents of styles2.css
h1 { color: red; }
Now that we have created the style files. We just need to update app.component.html
to use the cssUrl
property.
<link rel="stylesheet" [href]='sanitizer.bypassSecurityTrustResourceUrl(cssUrl)'> <h1>Working with dynamic CSS loading -:)</h1>
We had to use Angular’s DomSanitizer sanitizer.bypassSecurityTrustResourceUrl(cssUrl)
to tell Angular that url is safe to use. If you don’t do it then Angular will give you an error.
Error: unsafe value used in a resource URL context
There is another similar solution suggested in angular-cli Github issue that you can use. It makes use of webpack.
Hello, This works but every time the navigate using routing the style is reloaded. I am using bootstrap for styling and Angular Material theme.
I solved it defining
this.cssUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.configuracion.cssUrl);
in my component.
Then, in my template:
I hope it works
its not working..
great work but every time page reload using routing the stryle.How to fix it?
Thank you sir. It works for me. Good Solution.
Please tell where exactly to add — “this.cssUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.configuracion.cssUrl); link.
Thanks for this, it really helped us with a difficult issue we were struggling with. I can’t quite believe that it worked in IE11 😉
Thanks you so much you has give a nice solution that resolve my problem.
It worked really very well. Thank you so much
You could also create a `link` element dynamically, set the attributes, and append it to the `head`
Do you see the request going to load css in Netwrok tab?
To solve the constant reload issue, you have to do the sanitising in the component, not int the template.
e.g. In component:
cssShopUrl: SafeResourceUrl;
this.cssShopUrl = this.sanitizer.bypassSecurityTrustResourceUrl(‘/assets/css/shop.’ + this.shop.shopNo + ‘.css’);
e.g. In template:
“““