30

I am now trying for hours. I use Material2 and simply want to change the color of the progress-bar. I know there are those themes (primary/accent/warn) but I want to have a custom color (green) for my progressbar.

I already tried the weirdest css-combinations.. but with no effort. Maybe someone had the same problem?

Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
Mka24
  • 369
  • 1
  • 3
  • 8
  • How about setting these classes: https://github.com/angular/material2/blob/master/src/lib/progress-bar/_progress-bar-theme.scss#L10-L20 – acdcjunior Feb 19 '18 at 16:27
  • For the cleanest solution, refer to the answer of @s-sarangi – Oli Feb 14 '22 at 14:47

14 Answers14

60

You can use ::ng-deep selector to achieve what you want, this answer has some info on it.

How I did it:

CSS

::ng-deep .mat-progress-bar-fill::after {
    background-color: #1E457C;
}

::ng-deep .mat-progress-bar-buffer {
    background: #E4E8EB;
}

::ng-deep .mat-progress-bar {
    border-radius: 2px;
}

HTML

<mat-progress-bar  mode="determinate" value="{{progress}}"></mat-progress-bar>

And the result is this:

enter image description here

EDIT:

I found a way to avoid using ::ng-deep as it will be removed from angular soon. It seems that if you move your style from your component.css file to the global styles.css file it will work without ::ng-deep.

So, a style defined above can change in

mat-progress-bar .mat-progress-bar-buffer {
  background: #E4E8EB;
}

Move it to styles.css and it will be applied like this:

enter image description here

LATER EDIT

As an explanation why setting styles in the global style sheet works:

For components the default is that angular adds a attribute to each DOM-element of a component, and then adds the same attribute to every class in the css for the same component. Adding styles to a global stylesheet does not add these attributes, hence the style will be applied. (thanks Jompis for this)

This worked for me on a new project. I did not checked specifically with the old code but the conditions are the same and there is no reason for it not to work.

Marian Simonca
  • 1,472
  • 1
  • 16
  • 29
  • 3
    This should be the selected answer as it responds directly and correctly to the matter at hand, without the need to change CSS to SCSS and other bull. – Ovidiu Sep 20 '18 at 07:39
  • 3
    ng-deep is deprecated – Thiago C. S Ventura Feb 13 '19 at 12:18
  • 2
    I know it is deprecated, but there is no other replacement that works for now. [more details](https://stackoverflow.com/questions/47024236/what-to-use-in-place-of-ng-deep). – Marian Simonca Feb 13 '19 at 14:43
  • 2
    To elaborate on why it works in the global styles: It's because of how ViewEncapsulation works. For components the default is that angular adds a attribute to each DOM-element of a component, and then adds the same attribute to every class in the css for the same component. Adding styles to a global stylesheet does not add these attributes, hence the style will be applied. – Jompis Sep 20 '19 at 09:35
  • After Angular 15 here are working and new css classes .mdc-linear-progress__buffer and set background-color and then .mdc-linear-progress__bar-inner set border-color. – Janne Harju Feb 03 '23 at 09:33
13

UPDATE: Exercise caution when deciding to disable CSS modules, ensuring that you fully comprehend the potential risks involved. While it's important to be confident in your understanding, avoid being confined to dogmatic truths. Always strive to grasp the problems you're addressing thoroughly.

Since nobody mentioned so far...

He's how I solved it.

@Meet Dave is right about his approach. But you should use encapsulation: ViewEncapsulation.None (disables css modules)

Something like this:

Component

@Component({
  selector: '...',
  templateUrl: '...',
  styleUrls: ['...'],
  encapsulation: ViewEncapsulation.None,
})

Sass (in my case)

.audio-progress-bar {
  &.mat-progress-bar {
    height: 10px;
  }

  .mat-progress-bar-fill::after {
    background-color: #37474f;
  }

  .mat-progress-bar-buffer {
    background-color: #90a4ae;
  }

  /* remove animation and the dots*/ 
  .mat-progress-bar-background {
    animation: none;
    background-color: #eceff1;
    fill: #eceff1;
  }
}

View

<mat-progress-bar
  class="audio-progress-bar"
  mode="buffer"
></mat-progress-bar>
Thiago C. S Ventura
  • 2,448
  • 1
  • 29
  • 43
  • 4
    `ViewEncapsulation.None` is playing with fire. – Dem Pilafian Nov 10 '20 at 23:01
  • Hey @DemPilafian, give me more details (it's been a while I haven’t touched Angular) maybe I can update the answer with more infos. If can remember well there was no security risks around it. – Thiago C. S Ventura Mar 12 '21 at 23:45
  • 1
    @ThiagoC.SVentura it is just all you but inside thats component css tend to be like tehy are in global css files after you visit page where this component is. So make really good css selectors to avoid that these styles won't affect other components styles. Also you can use ::ng-deep even it is marked as deprecated. It will be around us for awile because there is no replacement for us yet. After there is some some standard solution there will be migration tool for it. I will assume. – Janne Harju Feb 03 '23 at 08:42
  • I am currently refactoring a project because a previous dev was using ViewEncapsulation.None. Please don't use it if you want to keep your app maintainable – Lukaesch Feb 09 '23 at 19:25
  • Just updated to make people aware of the risks. Feels free to expand on that if you feel so :) – Thiago C. S Ventura Jun 01 '23 at 11:43
9

Update:

Avoid using deep, TL;DR: Deep is technically invalid (like, deeprecated :p)

For more info refer: The use of /deep/ and >>> in Angular 2

Now, to change the color of mat-progress bar, Here is how I got it working,

Head over to your styles.scss file (or the main css/scss file in your project)

Add this class -->

.green-progress .mat-progress-bar-fill::after {
    background-color: green !important;
}

Your mat-progress should use the above class, like -->

<mat-progress-bar class="green-progress" mode="indeterminate"></mat-progress-bar>
Meet Dave
  • 990
  • 10
  • 11
  • 1
    I wanted to avoid using ::ng-deep, but unfortunately this didn't work for me. The answer by @Simonca above (using ::ng-deep) did work. – Darren Alfonso Jan 09 '19 at 02:23
  • 1
    Adding only this don't work! In addition we have add to the component encapsulation to make it working, like: encapsulation: ViewEncapsulation.None, – Oleksandr Yefymov Oct 15 '22 at 23:26
5

Angular 8 solution:

for me it was putting my styling in a top level .scss file. Also had to select in .scss as follows:

html:


<mat-progress-bar [ngClass]="passwordStatusBarColor" 
                  aria-label="Password strength meter"
                  mode="determinate"
                  [value]="progress">
</mat-progress-bar>

<!--passwordStatusBarColor could be 'weak', 'weakest', etc. with a corresponding rule-->

styles.scss:

.weakest {
  .mat-progress-bar-fill::after {
    background-color: yellow;
  }
}

str8up7od
  • 338
  • 3
  • 15
4

For me I just need to put in CSS this rule:

div.mat-progress-bar-primary.mat-progress-bar-fill.mat-progress-bar-element::after{ background-color: green; }

But clearly is easier if you use a theme.

Luiz Rossi
  • 772
  • 5
  • 19
3

I can suggest to change one of the premade primary/warn/accent colors to your custom color.

In your styles.scss (if your style file is css you will have to change it to support scss):

  @import '~@angular/material/theming';
  // Plus imports for other components in your app.

  // Include the common styles for Angular Material. We include this here so that you only
  // have to load a single css file for Angular Material in your app.
  // Be sure that you only ever include this mixin once!
  @include mat-core();

  // Define the palettes for your theme using the Material Design palettes available in palette.scss
  // (imported above). For each palette, you can optionally specify a default, lighter, and darker
  // hue.

  $mat-blue: (
    50: #e3f2fd,
    100: #bbdefb,
    200: #90caf9,
    300: #64b5f6,
    400: #42a5f5,
    500: #2196f3,
    600: #1e88e5,
    700: #1976d2,
    800: #1565c0,
    900: #0d47a1,
    A100: #82b1ff,
    A200: #448aff,
    A400: #2979ff,
    A700: #2B66C3,
    contrast: (
      50: $black-87-opacity,
      100: $black-87-opacity,
      200: $black-87-opacity,
      300: $black-87-opacity,
      400: $black-87-opacity,
      500: white,
      600: white,
      700: white,
      800: $white-87-opacity,
      900: $white-87-opacity,
      A100: $black-87-opacity,
      A200: white,
      A400: white,
      A700: white,
    )
  );

  $candy-app-primary: mat-palette($mat-blue, A700);
  $candy-app-accent:  mat-palette($mat-orange, A200, A100, A400);

  // The warn palette is optional (defaults to red).
  $candy-app-warn:    mat-palette($mat-red);

  // Create the theme object (a Sass map containing all of the palettes).
  $candy-a-theme($candy-app-theme);
pp-theme: mat-light-theme($candy-app-primary, $candy-app-accent, $candy-app-warn);

  // Include theme styles for core and each component used in your app.
  // Alternatively, you can import and @include the theme mixins for each component
  // that you are using.
  @include angular-material
TheUnreal
  • 23,434
  • 46
  • 157
  • 277
  • thanks, that worked for me.. I just made a new theme.scss and included it to the `angular-cli.json`, there I override the colours :) . big thanks – Mka24 Feb 20 '18 at 09:52
2

You can add a custom class and add styles to the same in styles.scss (with !important).

.your-custom-class{
  background-color: colorname !important;
}

or you can use the existing class to override the defined css properties by adding them to your global styles.scss file.

.mat-progress-bar-fill::after{
  background-color: colorname;
}
.mat-progress-bar-buffer {
  background: colorname;
}
S Sarangi
  • 21
  • 3
  • `.mat-progress-bar-fill::after{ background-color: colorname; } .mat-progress-bar-buffer { background: colorname; }` The above code section is the cleanest way imo – Oli Feb 14 '22 at 14:43
2

Change the config in the component typeDecorator:

encapsulation: ViewEncapsulation.None

then...

.mat-progress-bar-fill::after {
  background-color: $color;
}
Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
1

For me none of the solutions above worked for me. (using Angular 14 and Angular Materials 15.1)

First of all, to find the problem i had to inspect the elements using the DevTools browser debugger.

Here is the code to change the color of the fill bar (actually border...) :

.mdc-linear-progress__bar-inner {  
border-color: red !important;
}

This code must be placed in the root stylesheet (style.css).

Regarding the mat-progress-bar-buffer, simply used the following code (to put in the style.css file) :

mat-progress-bar  {
:first-child {
background-color: gray;
 }
}
0

Angular 7 and Material 7.1.1

 ::ng-deep .mat-progress-spinner circle, .mat-spinner circle{
        stroke: green !important; 
}
Lucas Breitembach
  • 1,515
  • 11
  • 15
Srihari GouthamGr
  • 298
  • 2
  • 4
  • 13
0

Without using ::ng-deep, ViewEncapsulation or theming, we can customise the progress bar using just clean scss by placing below code in style.scss:

.mat-progress-bar {
    .mat-progress-bar-fill::after{
        background: #007bff;
    }
    .mat-progress-bar-buffer{
        background: white;
    }
}

.mat-progress-bar[mode=indeterminate] {
    .mat-progress-bar-fill::after{
        animation-duration: 1000ms !important;
    }
    animation-duration: 1000ms !important;
    .mat-progress-bar-primary{
        .mat-progress-bar-fill::after{
            animation-duration: 1000ms !important;
        }
        animation-duration: 1000ms !important;
    }
    .mat-progress-bar-secondary {
        .mat-progress-bar-fill::after{
            animation-duration: 1000ms !important;
        }
        animation-duration: 1000ms !important;
    }
}

Using the above styling pattern in style.scss, I was able to customise pretty much any aspect of the progress bar. We can adjust the mode as per the type of progress bar we are using.

Siva Kiran
  • 1,817
  • 1
  • 12
  • 8
0

In your html:

<mat-progress-bar class="my-progress-bar" mode="indeterminate"></mat-progress-bar>

In your global style (the one mentioned in .angular-cli.json under styles property:

//This one is the moving color
.my-progress-bar .mat-progress-bar-fill::after {
  background-color: #e91b22;
}

// This will become the background color of your bar
.my-progress-bar .mat-progress-bar-buffer {
  background: white;
}

Even if you include any material theme, above config will override it

Prateek Bhuwania
  • 755
  • 1
  • 8
  • 19
0

2023 answer:

.mat-mdc-progress-bar {
    --mdc-linear-progress-active-indicator-color: green; //progress bar color
    --mdc-linear-progress-track-color: black; // background color
}
Ap0st0l
  • 515
  • 4
  • 26
-2

You can override only progress bar backgroud-color through this method added custom class then apply css by combination of tag and class like-

<mat-progress-bar class="my-color" mode="determinate" value="40"></mat-progress-bar>

Change into style.css

mat-progress-bar.my-color .mat-progress-bar-fill::after { background-color: green; }

Akshay Garg
  • 1,010
  • 8
  • 15