Managing CSS in Angular App for Cross Browsers and OS
Do you want to organize your CSS files in your angular app? Do you want to find out the strategy to segregate the CSS based on cross browsers and operating systems? You CSS designer should not be worried how to manage these. As a developer you should setup your angular app such that it works out of the box.
Introduction
I will use angular 10 project. Then I will install ngx-device-detector
node
package and finally I will demonstrate the best practice to follow to
dynamically load cross browser and operating system related CSS files in your
angular application.
Installing ngx-device-detector Angular Library
I am assuming that you have created one angular project named as manage-css
using angular cli ng new manage-css --styles=scss
. I have angular project
created with sass
styles.
npm i -S ngx-device-detector
Showing OS and Browser Info using ngx-device-detector Angular Library
Add below code in app component to see how ngx-device-detector works.
app.component.ts
import { Component } from '@angular/core';
import { DeviceDetectorService, DeviceInfo } from 'ngx-device-detector';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
title = 'manage-css';
deviceInfo: DeviceInfo;
constructor(private deviceDetectorService: DeviceDetectorService) {
this.deviceInfo = this.deviceDetectorService.getDeviceInfo();
}
}
app.component.html
<div>
<ul>
<li>user Agent - </li>
<li>Os - </li>
<li>browser - </li>
<li>device - </li>
<li>os_version - </li>
<li>browser_version - </li>
<li>deviceType - </li>
<li>orientation - </li>
</ul>
</div>
Adding default style.scss for all Browsers (IE & Chrome etc.)
styles.scss
would be our default style file. You could imagine this is our
base style file.
#test {
background-color: aqua;
height: auto;
width: 200px;
}
Letโs crate a div
in app.component.html
<div id="test">
This is angular app
<br>
Chrome color: aqua
<br>
IE color: yellow
</div>
Now our site is running both in chrome and IE browser nicely
Chrome:
IE browser:
Now I have requirement to show border only on IE browser not in Chrome.
Adding IE Browser specific CSS Files in Angular App
Letโs assume we are writing CSS for chrome browser as default. And we want to
extend few style class for IE browser. So lets create styles-ie.scss
and
extend one of our default class test
from styles.scss
.
extended test
class and added border
@import "./styles.scss";
#test {
// @extend .test;
border: 5px red dashed;
}
We need to add this file in angular.json so that angular will add this to the index.html file when we serve or build.
Go to angular.json
> architect
> build
> options
> styles
and add
below code
"styles": [
{ "input": "src/styles.scss", "bundleName": "styles" },
{ "input": "src/styles-ie.scss", "bundleName": "styles-ie" }
],
Now lest run npm run build
Notice we have 2 files styles.css
and
styles-ie.css
in dist/manage-css folder
Now in the Index.hml
you see Angular build add both CSS files.
We do not want that. Because, I want IE style files to be removed while running in Chrome.
Loading only Chrome Styles on Chrome Browser
Now, I will use deviceInfo object to determine which browser I am in. Then I
will use Document
from @angular/common
to remove the IE specific style
files.
In order to do above I will prefer to create angular service StyleService
and
execute this when my application initialized.
Creating Style Service and Remove IE Specific style files
Lets search all the link nodes with having style files ending with -ie.css
and
remove them.
Create style.service.ts
add below code:
import { DOCUMENT } from '@angular/common';
import { Inject, Injectable } from '@angular/core';
import { DeviceDetectorService, DeviceInfo } from 'ngx-device-detector';
@Injectable({ providedIn: 'root' })
export class StyleService {
deviceInfo: DeviceInfo;
constructor(
private readonly deviceDetectorService: DeviceDetectorService,
@Inject(DOCUMENT) private readonly document: any
) {}
execute() {
this.removeIEStylesIfRunningInChrome();
}
private removeIEStylesIfRunningInChrome() {
this.deviceInfo = this.deviceDetectorService.getDeviceInfo();
const head = this.document.getElementsByTagName('head')[0];
if (this.deviceInfo.browser === 'Chrome') {
[...(this.document.querySelectorAll('link') as any)]
.filter((x) => x.href?.indexOf('-ie.css') > -1)
.forEach((f) => head.removeChild(f));
}
}
}
Create init-styles.ts
import { StyleService } from './style.service';
export function initStyles(styleService: StyleService) {
return () => {
styleService.execute();
};
}
In app.module.ts
add provider to call initStyles
providers: [
{
provide: APP_INITIALIZER,
useFactory: initStyles,
deps: [StyleService],
multi: true,
},
],
Showing Chrome and IE specific styles only
Now lets run ng serve
and in Chrome IE specific styles are removed only Chrome Styles are loaded ๐
and IE browser has extra style file for IE browser specific styles-ie.css
๐
Adding Operating system specific styles in Angular app
I want to add styles-mac.scss
and add black border to be shown only on MAC.
Add styles-mac.scss
@import "./styles.scss";
#test {
// @extend .test;
border: 5px black dashed;
}
Update angular.json
to add MAC sass files.
"styles": [
{ "input": "src/styles.scss", "bundleName": "styles" },
{ "input": "src/styles-ie.scss", "bundleName": "styles-ie" },
{ "input": "src/styles-mac.scss", "bundleName": "styles-mac" }
],
Update the styles.service
to add new method to remove MAC styles if running on
Windows OS and call on execute
function.
execute() {
this.removeIEStylesIfRunningInChrome();
this.removeMacStylesIfRunningInWindowsOS();
}
private removeMacStylesIfRunningInWindowsOS() {
this.deviceInfo = this.deviceDetectorService.getDeviceInfo();
const head = this.document.getElementsByTagName('head')[0];
if (this.deviceInfo.os === 'Windows') {
[...(this.document.querySelectorAll('link') as any)]
.filter((x) => x.href?.indexOf('-mac.css') > -1)
.forEach((f) => head.removeChild(f));
}
}
GitHub Repository: https://github.com/rupeshtiwari/organize-css-angular
Become full stack developer ๐ป
If you want to become full stack developer and grow your carrier as new software developer or Lead Developer/Architect. Consider subscribing to our full stack development training programs. We have All-Access Monthly membership plans and you will get unlimited access to all of our video courses, slides, source code & Monthly video calls.
- Please subscribe to All-Access Membership PRO plan to access current and future angular, node.js and related courses.
- Please subscribe to All-Access Membership ELITE plan to get everything from PRO plan. Additionally, you will get access to monthly live Q&A video call with Rupesh and you can ask doubts/questions and get more help, tips and tricks.
Your bright future is awaiting for you so visit today FullstackMaster and allow me to help you to board on your dream software company as a Developer,Architect or Lead Engineer role. ๐ Say ๐ to me!