Angular 2 - How to dynamically change an entire CSS stylesheet based on URL queryparams
After a lot of digging around, finally found the solution I was looking for.
And it was so straight forward, hope this helps others that might be needing to do the same thing..
Get the css path from query params and then Inject the Document into a TS file...
append the link to the head of the document.
I did this in a Router Guard using canActivate.
I got the query param from the routerstatesnpshot like so:
Inject the DOCUMENT( don't forget the import) in the constructor
http://server.com/xxx&broker=1&client=2&css=http://cssServer.com/my_dynamic_stylesheet.css
import { DOCUMENT } from '@angular/common';
@Inject(DOCUMENT) private document: Document
this.setDynamicStyle(state.root.queryParamMap.get('css'));
setDynamicStyle(cssURL: string) {
const head = this.document.getElementsByTagName('head')[0];
const style = this.document.createElement('link');
style.id = 'css-styling';
style.rel = 'stylesheet';
style.href = `${cssURL}`;
head.appendChild(style);
}
Thanks to:
https://juristr.com/blog/2019/08/dynamically-load-css-angular-cli/
Generate dynamic css based on variables angular
Direct approach available in angular is using ngstyle as follows
<div [ngStyle]="{'color': style.colorVal ? style.colorVal : '#000', 'font-size' : style.fontSize ? style.fontSize : '16px' }"></div>
After going through different methods and approached to add dynamic css to all pages on angular app I ended up with following solutions.
Requirement : generate dynamic css based on values returned from and API to change design and styling.
Solution :
- create a new component and create a service to load dynamic css variables from API.
- Add style tag in template file and use variable values for properties.
- Load this template on all pages or on main template.
- On app build style will be moved to head tag.
Code sample
import { CssService} from './Css.service';
@Component({
selector: 'DynamicCss',
templateUrl: './DynamicCss.component.html',
styleUrls: ['./DynamicCss.component.scss']
})
export class ServiceProviderComponent implements OnInit {
cssVariables: any;
constructor(private cssService:CssService){
/* call the service/api to get the css variable values in cssVariables */
}
}
Now apply css using jquery or javascript to append css with help of function like following
appendCss(customData)
{
let text = '.custom-form-1 {
background-image: url("`+customData.background_image+`");
}';
$(document).ready(function(){
$("style").append(text);
});
}
and call this function after loading custom data from service or other variable like I did it ngOnInit
ngOnInit(){
this.appendCss(this.customizeFormData);
}
Its using jquery but can be done with javascript/typescript as well if you dont want to use jquery in your angular app
Other useful resource https://github.com/angular/angular/issues/9343#issuecomment-312035896
What are the ways to add conditional css file in Angular
You can use ngClass directive:
<div id="mydiv" [ngClass]="{'myCSSclass' : condition}"></div>
Dynamically load CSS stylesheet in link tag
Is having empty href attribute with Ok?
It is a relative URL that resolves to the current URL, which is an HTML document, which is not a stylesheet. So no.
Is there any other tag that would better suite in this situation?
No. Append a new <link>
element to document.head
when your CSS wants to load the CSS. There is no need for a placeholder element at all.
Angular 6, how to change style (rotate, colour, scale) of img based on variables (continuous change)
but then ngStyle is listening perpetually to page changes, whereas I wish to trigger the style change when a specific action occurs, instead of listening to all page changes if possible?
That's the whole point of Angular: you bind data to the view via a declarative template syntax it offers, and let it figure out when to update.
If you try to trigger update by manually knowing when data changes, you're probably doing something wrong (or you're optimizing a specific part of the library). Letting Angular do the update is the correct thing to do.
update () {
this.styles = { /* ... */ }
}
<div [ngStyle]="styles">...</div>
Related Topics
How to Get Screen Position of CSS3-3D Transformed Elements
Customize Zoom In/Out Button in Leaflet.Js
List Reorder Animation with Angularjs
Is There a Performance Difference Between the Sx Prop and the Makestyles Function in Material Ui
How to Fix Chart Legends Width-Height with Overflow Scroll in Chartjs
How to Disable JavaScript for Responsive Design
Click and Hold Event Listener with JavaScript
How to Add a Classname to a CSS Variable
Blinking Fixed Header in Site with Scrolling Animation
Automatic Two Columns with CSS or JavaScript
Set a Font Specifically for All Numbers on the Page
Partial Password Masking on Input Field
Fullcalendar.Io: How to Display One Event Per Line in Agendaweek Then Mix All in One
Using JavaScript Calculated Values in Less