Angular Material Components Theming System: Complete Guide

Angular Material Components Theming System: Complete Guide

# Modifying Angular Material Component's Styles It is a very common need in almost all applications to modify the components provided by 3rd party libraries. Those modifications are generally done for changing the styles. And it is very crucial for such libraries to provide ways to achieve those modifications easily. In this article, we will learn how to modify styles so that our changes do not conflict with future updates of Angular Material library. As a bonus, I will provide a list of thumb rules which you should follow while making any style changes. ## Angular Material Button Angular Material’s buttons are already enhanced with Material design and ink ripples, and they also have a range of presentation options. You can change the look and feel of buttons by using different attribute directives for different situations and needs. For instance `mat-button` is a rectangular button with text content, `mat-raised-button` is the same as `mat-button`, but with elevation and `mat-icon-button` is circular and it’s meant to contain an icon. You can check all variants on the [official site](https://material.angular.io/components/button/overview). And there are 3 theme colors provided with all variants: `primary`, `accent` and `warn`. Now, even with these many variants and options, we may need to modify the default Angular Material button to achieve a feature or change of style. Let’s look and learn how to make both the changes effectively. ## How to change styles Before moving into how to change styles, let’s first understand some rules to avoid any conflicting changes. These rules are consolidated from [customizing component styles guidelines](https://material.angular.io/guide/customizing-component-styles). ### Thumb rules Keep below rules in mind whenever you want to change styles of any Angular Material component. 1. Define custom styles for a component’s host element 2. Change styles which affect either position or layout of that component 1. `margin`, `position`, `top`, `left`, `transform`, `z-index`, etc. 3. Apply above styles modifications by defining a custom CSS class and applying it to component’s host element 4. Do not change the styles which affect size or internal layout of the component 1. `padding`, `height`, `width`, or `overflow` 5. Do not change or override the styles of internal elements of Angular Material components, like in Angular Material button, there are some internal components which produce ripple effect, we should avoid modifying styles of such components 6. Provide custom styles to overlay components, like `MatDialog`, `MatMenu`, etc. through `panelClass` property. Add that class to your global stylesheet after including theme mixins. By following above rules, not just for Angular Material components but any component library, we can safely achieve needed modifications and avoid causing breaking styles. Now, keeping the above rules in mind, we will try to change styles of Angular Material buttons. For this tutorial, we will focus on below 2 styles changes: 1. Color 2. Shape And at the end of the section we will also have a brief look for size and typography. ### Color The very basic change we may need to `font-color` and `background-color` of buttons. And that, too with different states, like `:hover`, `:focus` and `:active`. We will create a custom-theme, which should get applied only when it’s inside `.custom-theme` class. ```scss // src/styles/themes/_custom-theme.scss @use "@angular/material" as mat; $custom-primary: mat.define-palette(mat.$pink-palette, 700, 500, 900); $custom-accent: mat.define-palette(mat.$blue-grey-palette, A200, A100, A400); $custom-theme: mat.define-dark-theme( ( color: ( primary: $custom-primary, accent: $custom-accent, ), ) ); .custom-theme { @include mat.button-color($custom-theme); @include mat.progress-spinner-color($custom-theme); } ``` Note that we have only included `button-color` and `progress-spinner-color`, because in our demo we only use those 2 components. You can also use `all-component-colors` mixin to add all components’ colors, but it will increase the size of the final output style. So, now with the above code, if in the HTML code, we simply wrap the main container with `custom-theme` class, it will apply custom-theme to components inside it. Let’s look at the output: ![output after applying custom theme](https://res.cloudinary.com/dbgsyjnmu/image/upload/v1698673436/angular-material.dev/Screenshot_2023-10-30_191310_jpeudb.png) ### Shape Next, let’s change the shape. We want to add a shape variant such that buttons have a rounded borders. Now, according to thumb-rules discussed earlier, we can change the styles of host-element which affect the layout of the component itself. So, to achieve the shape change, we can simply add a class with needed changes and apply it safely to Angular Material buttons: ```scss .button-rounded { border-radius: 25% / 50%; } ``` Now, if you apply the class `button-rounded`, you won’t see the change. The reason behind that is all variants of Angular Material buttons have their own `border-radius` already applied. So, considering [selector specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity), we will have to modify our code like below: ```scss .button-rounded { &.mat-mdc-button, &.mat-mdc-raised-button, &.mdc-button--unelevated, &.mdc-button--outlined { border-radius: 25% / 50%; } } ``` ![rounded buttons](https://res.cloudinary.com/dbgsyjnmu/image/upload/v1698742286/angular-material.dev/Screenshot_2023-10-31_142102_hzzfnw.png) ### Other styles changes Apart from color and size, there can be more changes needed. Let’s briefly look at some and how to modify them. #### Size To make size changes work accurately,we need to handle the size of all inner components (like ripple, label, touch area, etc.) respectfully for a `mat-button` in our example. Angular Material library provides an easy way to do it. It's called density. ##### Density Density mixins includes styles related to the size and spacing of elements in your application. These style should be included at least once in your application. In Angular Material, Density can have maximum value as `0` and minimum value as `-3`, which translates to height of `36px` and `24px` respectively. Please note that density only takes care of size and spacing of element, not the `font-size`, for `font-size` you will have use typography mixin. #### Typography This mixin includes styles related to the fonts used in your application, including the font family, size, weight, line-height, and letter-spacing. These style should be included at least once in your application. ### Size variant Now keeping all things about density and typography in mind, let's create a smaller size variant for Angular Material button. #### 1. Create a file for size Create a file `src/styles/sizes/_index.scss` with below content: ```scss // src/styles/sizes/_index.scss @use "@angular/material" as mat; $regular-font-family: "'Inter', sans-serif"; $sm-typography: mat.define-typography-config( $font-family: $regular-font-family, $button: mat.define-typography-level( $font-size: 14px, ), ); $sm-theme: mat.define-light-theme( ( typography: $sm-typography, density: -2, ) ); .sm { @include mat.button-density($sm-theme); @include mat.button-typography($sm-theme); @include mat.progress-spinner-density($sm-theme); @include mat.progress-spinner-typography($sm-theme); } ``` Few points to observe in above code: 1. We are creating a `$sm-typography` config, only with `$button` option. And we are giving `14px` font-size to it. Note that we are also providing `$font-family`, if we do not provide, it will take default font-family, which is "Roboto". 2. We are creating a `$sm-theme` with `$sm-typography` as typography config and `-2` as density, which will give `28px` base height to the button and it will also adjust the respective sizes 3. We are creating a `.sm` class and including mixins for `density` and `typography` for button and progress-spinner components #### 2. Import size file The last step is to import size file in main styles file: ```scss // src/styles.scss @use "./styles/sizes"; // rest remains same ``` And then you simply wrap Angular Material buttons in `sm` class, you will see the small variants: ![smaller variant buttons](https://res.cloudinary.com/dbgsyjnmu/image/upload/v1698742441/angular-material.dev/Screenshot_2023-10-31_142349_l71qcd.png)
Support Free Content Creation

Contributions & Support

Even though the courses and articles are available at no cost, your support in my endeavor to deliver top-notch educational content would be highly valued. Your decision to contribute aids me in persistently improving the course, creating additional resources, and maintaining the accessibility of these materials for all. I'm grateful for your consideration to contribute and make a meaningful difference!

Envelop
Don't miss any update

Stay up to date

Subscribe to the newsletter to stay up to date with articles, courses and much more!

Angular Material Dev

Angular Material Dev is one place stop for developers to learn about integrating Material Design in Angular applications like a pro.

Find us on X (Twitter) and LinkedIn