1

I'm fairly new to theming, I'm mainly a backend developer. Currently, I'm trying to customize CSS properties/classes from an external file, but because of angular's encapsulation, it's not working. With the default, emulated, encapsulation my .btn class is displayed like this:

wrong style class encapsulated

Using ViewEncapsulation.None, I get the desired behavior:

correct style class

In my component's SCSS file, I import the external SCSS file and customize some properties:

@import "@scope/theming/assets/core";

.btn {
    --#{$prefix}btn-bg: var(--#{$prefix}bg-surface);

    display: inline-flex;
    align-items: center;
    justify-content: center;
    white-space: nowrap;
    ...
}

The @scope/theming/assets/core SCSS file imports the SCSS from bootstrap and other files. I thought that by importing the SCSS file directly in the component, the style would be correctly applied, but that's not the case.

As far as I understand, changing encapsulation to None is not the "best" solution. If that's the case, is there a better solution for what I'm trying to do? I've read about a lot things, including mixins, but I'm not quite sure how they'd fit in my scenario.

Note: This is an angular library.

eestein
  • 4,914
  • 8
  • 54
  • 93
  • Wrap the specific scss in a `:host ::ng-deep { ... }` [example](https://github.com/MintPlayer/mintplayer-ng-bootstrap/blob/master/libs/mintplayer-ng-bootstrap/card/src/card/card.component.scss) – Pieterjan Feb 07 '23 at 19:53
  • Or I think in your case you might need `::ng-deep` ([example](https://github.com/MintPlayer/mintplayer-ng-bootstrap/blob/master/libs/mintplayer-ng-bootstrap/form/src/form/form.component.scss)). But try to avoid this if possible – Pieterjan Feb 07 '23 at 20:01
  • @Pieterjan thanks for your answer, I saw and tried that as well, but since ng-deep is deprecated, that's not a solution I'd like to go with. Also, it didn't work for me as well. Thanks again. – eestein Feb 07 '23 at 20:01
  • What's your take on that? If I use only ng-deep, it works, but since it's deprecated and the behavior is the same as encapsulation none (since I'm wrapping the whole thing), I'm not comfortable going that route, unless there's no other option. – eestein Feb 07 '23 at 20:01
  • 1
    Ah you're right about that. But I don't think the angular team developed an alternative to `::ng-deep` yet (for stripping component scopes from the css selectors). Atm I just keep using it, and I'll see if the alternative is released. In my case it's an angular component library, so I did compare to how [angular material](https://github.com/angular/components/blob/main/src/material/card/card.ts#L47) deals with this. – Pieterjan Feb 07 '23 at 20:06
  • 1
    Yes, it's been deprecated for many years now... – eestein Feb 07 '23 at 20:06
  • Updated my last comment – Pieterjan Feb 07 '23 at 20:10
  • Good point, I didn't even think about checking how they did it :face_palm: But yes, if they still use it, I'm going to maintain the encapsulation none at least until someone proposes a better solution. Thanks! – eestein Feb 07 '23 at 20:24
  • Most comments [here(old thread however)](https://stackoverflow.com/questions/47024236/what-to-use-in-place-of-ng-deep) seem to indicate that it has to do with support for the shadow-DOM. I have to note however that `:host ::ng-deep` is better than `ViewEncapsulation.None` to prevent the leaking of styles – Pieterjan Feb 07 '23 at 20:36
  • I read about that in a response from Gunther, but `:host ::ng-deep` didn't work for me. Only `::ng-deep`. – eestein Feb 07 '23 at 20:42

1 Answers1

0

You can write .css in a global .css (generally it's used the styles.css or styles.scss) or write .css that only work with a component.

ViewEncapsulation.None makes that the .css you write in component becomes global (it's applied to all the app)

With this two "simple ideas" to change the .css of one component the "easy way" is change the "global" .css. Like this SO

Exist another way that is use css variables (sorry, I can not find the post we told time ago)

In our component.css (imagine the selector has app-my-card) we have, e.g.

.my-class{
   background-color: var(--background-color,rgb(167, 34, 34));
}

And a parent can define

app-my-card {
  --background-color: blue;
}
Eliseo
  • 50,109
  • 4
  • 29
  • 67
  • Hi Eliseo, thanks for your answer. If understood correctly what you said, I'm not sure it applies to my scenario. It would be counterproductive to change the external source files. Not only in case of an update, but also because of the amount of files. Since it's bootstrap CSS, I'd like to not touch it and still be able to have it applied on my component. – eestein Feb 08 '23 at 08:55
  • The bootstrap.min.css should be always a "global" .css. For this, or the file is added to styles array in angular.json (It's under project-->your-app-->architect-->build-->options). or the file is import in styles.css. In your component.css you should import **only** the necessary "functions" or the "sass variables" (the css variables should be common and are well defined in global way). If you need an special .css for your component simply declare in your component.css – Eliseo Feb 08 '23 at 09:05
  • Sorry, I think I forgot to mention a very important detail... (just updated my question) this is a library, not an app. The only way to import the SCSS is inside my component's SCSS. And, as I mentioned in my question and there's even code in there, I am adding special CSS in my component.scss, that gets correctly applied, as it should. The problem is with the external one, that doesn't. Unless I set encapsulation to none or use ng-deep. Maybe you didn't understand my question or I wasn't clear enough, if the latter, I'm sorry. – eestein Feb 08 '23 at 09:16
  • @eestein, use `ViewEncapsulation.None` **is the same** that write .css in "styles.css". I prefer this approach -using [specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity) and the "tecnica" I showed in the first link of my answer- to ng-deep. – Eliseo Feb 08 '23 at 09:56
  • I'm going to take some time to read your answer again with more time, because I still don't understand how that would work in my scenario. But that could be my lack of SCSS knowledge. I'll read it more carefully and get back to you. Thanks again. – eestein Feb 08 '23 at 10:00