Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

css encapsulation in Angular

I have been recently exploring the css and dom encapsulation by the Angular components.

I scaffolded a quick project using ng-cli and loaded a component. Let's say that component selector is 'app-component'. This encapsulates all the dom and css pertaining to this component within itself. All good so far.

What I have learned from my previous readings is that components neither allow external CSS to bleed in nor the internal CSS bleed out (this is more specific to web components)

Now, in the index.html file I included a bootstrap css file just to observe whether the styles from bootstrap css bleeds into the component or not and to my surprise it did. I could use all the classes provided the bootstrap css inside my component.

Why is this happening? Essentially external css is bleeding into the component. I understand the view encapsulation concepts in Angular but this doesn't fit in.

Sounds a bit naive, but may be I am missing a point here!

EDIT

Basically I am referring to this:

https://developers.google.com/web/fundamentals/getting-started/primers/shadowdom

This says:

Scoped CSS: CSS defined inside shadow DOM is scoped to it. Style rules don't leak out and page styles don't bleed in.

like image 754
beNerd Avatar asked Mar 28 '17 13:03

beNerd


1 Answers

Shadow DOM is not used by default in Angular. By default it emulates via "surrogate ids", per the ViewEncapsulation documentation.

Emulated

Emulate Native scoping of styles by adding an attribute containing surrogate id to the Host Element and pre-processing the style rules provided via ViewMetadata or ViewMetadata, and adding the new Host Element attribute to all selectors.

This is the default option.

To enable Shadow DOM on supported browsers you must use ViewEncapsulation.Native

Native

Use the native encapsulation mechanism of the renderer.

For the DOM this means using Shadow DOM and creating a ShadowRoot for Component's Host Element.

For example:

import { ..., ViewEncapsulation } from '@angular/core';

@Component({
    selector: 'my-component',
    templateUrl: './my.component.html',
    styleUrls: ['./my.component.scss'],
    encapsulation: ViewEncapsulation.Native
})
export class AppComponent ...

In this Working Plunker #1, you'll notice that although global styles have been implemented in both index.html (embedded) and style.css, and an overriding style (with higher specificity) has been implemented in the parent, these do not bleed into the child when ViewEncapsulation.Native is enabled.

Note: I made the assumption that you're not using ViewEncapsulation.Native since it was not mentioned in the original question.

Specific selectors (class or id) are not carried down (as expected), although more "general" styles are. For example a font-family applied to body will bleed into the child (if the child does not override it) as I now understand that torazaburo was alluding to in his answer.

Working Plunker #2

like image 162
Steve Gomez Avatar answered Sep 22 '22 12:09

Steve Gomez