Angular: Toggle Dark and Light Theme

Dhrubo Dh
4 min readApr 8, 2021

Recently for work, I have been working with Angular. Coming from a React background, there is a bit of a learning curve. But I am having fun exploring Angular. This week I have learned and implemented an option to change the default theme of an Angular app between light and dark theme. In this post, I will explain how I implemented it using Angular Material.

For the demo purpose, I quickly generated an app using Angular/CLI and added angular material to it.

ng new dark-mode-demo
ng add @angular/material

While choosing the theme for Angular Material, I chose SCSS instead of CSS and chose Custom instead of any pre-built theme. Choosing SCSS is important since we need to use SASS to implement our custom theme. Angular Material provides some angular CLI schematics to quickly create basic Material components and for this purpose, I used ‘navigation’ schematics to generate a component consists of a toolbar and a side-nav inside my app folder.

ng generate @angular/material:navigation navigation

After this, I deleted everything in app.component.html and added the ‘app-navigation’ selector and in the browser, it displayed like this.

Not bad for few lines of code. Now I wanted a toggle in the toolbar where a user would be able to switch between light and dark theme and I went ahead and added mat-slide-toggle to the toolbar. The idea is to when the toggle is not on, the app will be in light theme, and turning the toggle on will trigger the dark mode. I stored a boolean value into a variable called isDarkMode in the navigation component and set the initial value to ‘false’.

It was time for me to go to the styles.scss file and figure out the themes. Angular CLI actually generated a theme for me and after a little clean up the file looked like this:

So, Material has three distinct colors for any theme: primary, accent, and warn. The angular material website has more info on that. To make use of Angular material theming, it needed to be imported at the top file and then it imported the mat-core() Sass mixin, only needs to be imported in one place in the whole application and this allows all the components to use the common material style. Then it declared three variables and stored the value using the mat-palette function passed in available mat-colors(eg: $mat-indigo). Then it declared a light default theme for the project, using mat-light-theme function provided by Material and passing in the color variables. Using the include directly in the file, light-theme became the app’s default theme. Let's see it in action in the browser.

Light Theme

Now, I declared a dark theme, following a similar pattern, and this time, I declared the dark theme with a CSS class so I can use it in my app. So the styles.scss looked like this:

With Dark Theme

Notice how I did not include the warn color since I wanted it to be stay red. Now I could use this dark mode class in my navigation component and see the theme in action. I headed over to the navigation component HTML file and in the mat-sidenav-container added a ngClass directive that will be true or false based on the isDarkMode variable.

Navigation Component HTML

To see if the theme was working I changed the variable isDarkMode value from false to true and this was in the browser:

There is a Dark theme! Now I only needed to bind the toggling function to the toggler and for that, I imported the forms module to the app module so I could use [(ngModel)]. After that, I binded the variable to the toggle and it looked like this:

Navigation Component HTML

Now I could toggle between dark mode and light mode and it was working fine in the browser except the content area. It was still white in the dark mode. To quickly fix that I added mat-app-background class to the navigation container and that fixed it.

Browser dark-mode

Thanks for reading. Any feedback and suggestions will be appreciated.

--

--