//Approach 1:
dynamicWidthClass = computed(()=>{
if (window.innerWidth > 992 && window.innerWidth <= 1284) {
return "pl-25";
} else if (window.innerWidth > 1284 && window.innerWidth <= 1828) {
return "pl-18";
} else if (window.innerWidth < 992 || window.innerWidth >= 1920) {
return "pl-5";
}
return "pl-3"
});
windowInnerWidth = signal(window.innerWidth)
//Approach 2:
dynamicWidthClass = signal("pl-3");
@HostListener("window:resize", ["$event"])
onResize(event) {
if (window.innerWidth > 992 && window.innerWidth <= 1284) {
this.dynamicWidthClass.set("pl-25");
} else if (window.innerWidth > 1284 && window.innerWidth <= 1828) {
this.dynamicWidthClass.set("pl-18");
} else if (window.innerWidth < 992 || window.innerWidth >= 1920) {
this.dynamicWidthClass.set("pl-5");
}
}
<div
class="wrapper d-flex flex-column flex-row-fluid vh-100"
id="kt_wrapper"
>
<app-header></app-header>
<div [ngClass]="dynamicWidthClass()">
<router-outlet></router-outlet>
</div>
<app-footer class="mt-20r"
></app-footer>
</div>
I have the following two approaches of an example style snippet I intend to use to make my Angular route elements nested within a parent component more responsive based on the viewport width changes, which approach could suit me better? I currently noticed that both the approaches work differently but both have one thing in common which is that they require a reload on each viewport resize.
Am I doing this wrong and do I have to only rely on CSS media queries or some other approach? The main challenge I face here is that my current project is primarily powered by Bootstrap which comes loaded with a crazy number of classes that are hard to track if I intend to personalize it with my own, so I’m trying to implement a more robust approach to make my code responsive without dealing with custom classes or removing bootstrap
2
Answers
SASS Solution:
I think you should prefer media queries for such requirements. I use the sass operator
@extend
to apply this class dynamically.Angular Solution:
As per Matthieu Riegler feedback, the code from
fromEvent
will trigger a change detection cycle so to make the code more efficient you can wrap thefromEvent
inside azone.runOutsideAngular
so that change detection does not fire multiple times and usezone.run
to update the signal during the final update, I also usedebounceTime
to reduce the number of times thefromEvent
fires.So as per the feedback, we move the listener to the
constructor
and emit the value only when necessary, also you should make sure this subscription is unsubscribed on destroy.Full Code:
Stackblitz Demo
Similar to the suggested solution of using
@media
queries andextend
you could make use of CSS container queries, which simplifies your process in the same way by removing the need to explicitly listen for viewport resize events.However, whereas
@media
queries are still bound to the viewport dimensions@container
queries are solely concerned with the dimensions of the parent element, which can have it’s situational benefits depending on your use case.