angularionic-frameworkfont-awesomeangular-fontawesome

angular-fontawesome fa-layers-counter color change


I am using the angular-fontawesome library as part of an ionic application. I can't seem to get the fa-layer-counter component to change color away from it's default red shade.

<fa-layers [fixedWidth]="true">
    <fa-icon [icon]="['far', 'bell']"></fa-icon>
    <fa-layers-counter content=""></fa-layers-counter>
</fa-layers>

I've tried:

  1. Adding a class to change the SCSS background-color like so:
<fa-layers [fixedWidth]="true">
    <fa-icon [icon]="['far', 'bell']"></fa-icon>
    <fa-layers-counter content="" class="color-change"></fa-layers-counter>
</fa-layers>

.color-change {
    --background-color: var(--ion-color-success) !important;
}
  1. Tapping into the span sub-element that gets created (with element and class name):
<fa-layers [fixedWidth]="true">
    <fa-icon [icon]="['far', 'bell']"></fa-icon>
    <fa-layers-counter content="" class="color-change"></fa-layers-counter>
</fa-layers>

.color-change > .fa-layers-counter {
    --background-color: var(--ion-color-success) !important;
}
  1. Styling inline.
  2. Using a style other than backgorund-color.

I'm out of ideas and couldn't get anything to work. Any ideas?


Solution

  • The first issue is that you attempt to change --background-color, which is a CSS variable. This variable is not recognised by angular-fontawesome. So you should change background-color CSS property instead.

    Then there are two things at play here: CSS cascades and Angular view encapsulation.

    So the intuitive way is to add a class to the <fa-layers-counter>. It will correctly add a class and change colour of <fa-layers-counter> element. But the problem is that the actual dot is a <span> inside <fa-layers-counter>, which overrides the background-color value set on its parent.

    <fa-layers-counter class="color-change"> <!-- you set your colour here -->
      <span class="fa-layers-counter"></span> <!-- but it is overridden on the child element by the library -->
    </fa-layers-counter>
    

    To solve this problem angular-fontawesome provides classes input, which allows to assign class on the internal <span> element.

    So <fa-layers-counter [classes]="['change-color']"></fa-layers-counter> would result in below markup:

    <fa-layers-counter>
      <span class="fa-layers-counter color-change"></span>
    </fa-layers-counter>
    

    However this still does not work, because of Angular's view encapsulation. color-change class is defined in your host component and Angular will prevent it's rule to be applied to the fa-layers-counter's content (which is a different component). To overcome this you need to tell Angular that you actually want to apply this to content of another component. The final solution will look like below:

    <fa-layers-counter [classes]="['change-color']"></fa-layers-counter>
    
    /* :host is a small precaution, to ensure that .change-color is only applied in the host's subtree. This is not required, but makes it less likely for `.change-color` class rules to leak in the unexpected place. */
    :host ::ng-deep .change-color {
      background-color: green;
    }
    

    Here is a working example on StackBlitz: https://stackblitz.com/edit/angular-z8v4ux-kof4dr