Angular - Material:如何自定义进度条颜色?

31

我已经尝试了数个小时,使用Material2并想简单地更改进度条的颜色。我知道有主题(primary/accent/warn),但我想为我的进度条设置自定义颜色(绿色)。

我已经尝试过最奇怪的CSS组合...但没有效果。也许有人遇到过同样的问题?


设置这些类怎么样:https://github.com/angular/material2/blob/master/src/lib/progress-bar/_progress-bar-theme.scss#L10-L20 - acdcjunior
为了最干净的解决方案,请参考@s-sarangi的答案。 - Oli
14个回答

60

您可以使用::ng-deep选择器来实现您想要的效果,这个答案中提供了一些相关信息。

我的做法:

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>

结果是这样的:

在此输入图像描述

编辑:

我找到了一种避免使用 ::ng-deep 的方法,因为它很快将从 Angular 中删除。 似乎如果您将样式从您的 component.css 文件移动到全局的styles.css 文件中,则可以在不使用 ::ng-deep 的情况下工作。

因此,上面定义的样式可以更改。

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

将其移动到styles.css,它将像这样应用:

enter image description here

后续编辑

解释一下为什么在全局样式表中设置样式可以起作用:

对于组件,默认情况下,Angular会向组件的每个DOM元素添加一个属性,然后将相同的属性添加到该组件的每个CSS类中。将样式添加到全局样式表不会添加这些属性,因此样式将被应用。 (感谢Jompis

在我的新项目上,这对我起作用了。虽然我没有特别检查旧代码,但条件是相同的,没有理由不起作用。


3
这应该被选为最佳答案,因为它直接且准确地回应了问题,而不需要改变CSS到SCSS和其他无关的内容。 - Ovidiu
3
ng-deep已经被弃用。 - Thiago C. S Ventura
3
我知道它已经被弃用了,但目前没有其他替代方案可行。更多细节 - Marian Simonca
2
详细说明为什么全局样式可以生效:这是由于ViewEncapsulation的工作原理。对于组件,默认情况下,Angular会向每个组件的DOM元素添加一个属性,然后将相同的属性添加到该组件的每个CSS类中。将样式添加到全局样式表中不会添加这些属性,因此样式将被应用。 - Jompis
在 Angular 15 之后,这里有一些新的工作和新的 CSS 类。.mdc-linear-progress__buffer 可以设置背景颜色,然后 .mdc-linear-progress__bar-inner 可以设置边框颜色。 - Janne Harju

13

更新: 在决定禁用 CSS 模块时要谨慎,确保您充分理解相关的潜在风险。虽然重要的是要对自己的理解有信心,但要避免被教条主义真理所限制。始终努力全面地理解您正在解决的问题。

由于迄今为止没有人提到......

这是我解决它的方法。

@Meet Dave 关于他的方法是正确的。但是,你应该使用 encapsulation: ViewEncapsulation.None(禁用 CSS 模块)

像这样:

组件

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

Sass(在我的情况下)

.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;
  }
}

视图

<mat-progress-bar
  class="audio-progress-bar"
  mode="buffer"
></mat-progress-bar>

4
ViewEncapsulation.None 这么做就像玩火。 - Dem Pilafian
嘿@DemPilafian,给我更多细节(我已经有一段时间没有接触Angular了),也许我可以更新答案并提供更多信息。如果我没记错的话,它周围没有安全风险。 - Thiago C. S Ventura
1
@ThiagoC.SVentura,这只是你的问题,但组件内部的CSS看起来像全局CSS文件中的样式,当您访问包含此组件的页面时。因此,请制作非常好的CSS选择器,以避免这些样式影响其他组件的样式。您还可以使用::ng-deep,即使它被标记为已弃用。它将在我们周围存在一段时间,因为目前还没有替代品。在有了一些标准解决方案之后,将会有迁移工具可用。我会假设。 - Janne Harju
我目前正在重构一个项目,因为之前的开发人员使用了ViewEncapsulation.None。如果您想保持应用程序的可维护性,请不要使用它。 - Lukaesch
刚刚更新,提醒人们注意风险。如果您觉得有必要,可以进一步扩展说明。 - Thiago C. S Ventura

10

更新:

不要使用/deep/,简称TL;DR:/deep/在技术上是无效的(如同被淘汰了:p)

有关更多信息,请参见:Angular 2中使用/deep/和>>>的方法

现在,要更改mat-progress bar的颜色, 这是我让它工作的方法,

转到styles.scss文件(或项目中的主要CSS / SCSS文件)

添加此类-->

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

您的mat-progress应该使用上述类,如-->
<mat-progress-bar class="green-progress" mode="indeterminate"></mat-progress-bar>

1
我本来想避免使用::ng-deep,但不幸的是这对我没有起作用。上面@Simonca的答案(使用::ng-deep)确实有效。 - Darren Alfonso
1
仅添加这个不起作用!此外,我们还需要添加组件封装以使其工作,例如:encapsulation: ViewEncapsulation.None。 - Oleksandr Yefymov

5

Angular 8 解决方案:

对我来说,解决方法是将我的样式放在顶层的一个 .scss 文件中。同时,也需要在.scss 中按照以下方式进行选择:

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;
  }
}


4

对我来说,我只需要在CSS中加入这个规则:

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

但是,如果您使用主题,则会更加简单。


3
我可以建议将预设的主要/警告/强调颜色之一更改为您的自定义颜色。
在您的styles.scss中(如果您的样式文件是css,则必须更改以支持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

谢谢,这对我有用。我刚刚创建了一个新的theme.scss,并将其包含到angular-cli.json中,在那里我覆盖了颜色 :)。非常感谢。 - Mka24

2

更改组件类型装饰器中的配置:

encapsulation: ViewEncapsulation.None

然后...

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

2
你可以在styles.scss中添加自定义类并为其添加样式(使用!important)。
.your-custom-class{
  background-color: colorname !important;
}

或者你可以使用现有的类来覆盖已定义的 CSS 属性,方法是将它们添加到你的全局 styles.scss 文件中。
.mat-progress-bar-fill::after{
  background-color: colorname;
}
.mat-progress-bar-buffer {
  background: colorname;
}

.mat-progress-bar-fill::after{ background-color: colorname; } .mat-progress-bar-buffer { background: colorname; }以上代码段是我认为最简洁的方式。 - Oli

1

对我来说,以上的解决方案都没有起作用(使用Angular 14和Angular Materials 15.1)。

首先,为了找到问题,我必须使用DevTools浏览器调试工具检查元素。

以下是更改填充条颜色的代码(实际上是边框...):

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

这段代码必须放在根样式表(style.css)中。
关于mat-progress-bar-buffer,只需使用以下代码(放在style.css文件中):
mat-progress-bar  {
:first-child {
background-color: gray;
 }
}

0

不使用::ng-deepViewEncapsulation或主题,我们可以仅通过放置以下代码在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;
    }
}

使用上述在style.scss中的样式模式,我能够自定义进度条的几乎任何方面。我们可以根据所使用的进度条类型调整模式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接