Use a remote stylesheet inside a template tag (with shadow dom)
I came across the same problem recently. What I ended up doing was using:
<template id="templateContent">
<style> @import "css/generalStyle.css"; </style>
</template>
Additional info: This worked just fine except that now I'm having some cache issues as Chrome does not seem to reload those resources after a hard reload.
Hide and Show elements inside shadow dom
Because shadow dom elements are isolated from outside styling.
You can link a stylesheet or use the visbility property to show/hide your shadow elements.
Note that inherited properties can go through the shadow boundary.
How can I contain the styles of a Chrome Extension content script?
I think you should use the Shadow DOM API. It is good practice for those cases when you just need to append your UI component to a webpage.
https://developers.google.com/web/fundamentals/getting-started/primers/shadowdom
Overriding externally-defined styles in a web component
The <slot>
is intentionally designed to allow the outer code to style the content placed into it. This is a great feature when used correctly.
But if you want better control of what shows in the web component then you need to copy cloned copies of the content from this.childNodes
into the shadow DOM. Then you have 100% control over the CSS.
OK. You really only have 90% control because the person using your component can still set the style
attribute.
customElements.define("my-nav", class extends HTMLElement { constructor() { super();
const template = document.querySelector("template#my-nav").content; this.attachShadow({ mode: "open" }) .appendChild(template.cloneNode(true)); } connectedCallback() { var container = this.shadowRoot.querySelector('.links-container'); var children = this.childNodes; if (children.length > 0 && container) { while(container.firstChild) { container.removeChild(container.firstChild); } for (var i = 0; i < children.length; i++) { container.appendChild(children[i].cloneNode(true)); } } } });
a { color: red;}
<template id="my-nav"> <style> .links-container a { color: lime; font-weight: bold; margin-right: 20px; } </style>
<div class="links-container"> </div></template>
<p>I want these links to be green:</p><my-nav> <a href="#">Link 1</a> <a href="#">Link 2</a> <a href="#" style="color: red">Link 3</a></my-nav>
Load external CSS into component
See also https://angular.io/docs/ts/latest/guide/component-styles.html
View encapsulation
To allow external styles to affect the content of components you can change view encapsulation (that's what prevents styles to "bleed into" components).
@Component({
selector: 'some-component',
template: '<div></div>',
styleUrls: [
'http://example.com/external.css',
'app/local.css'
],
encapsulation: ViewEncapsulation.None,
})
export class SomeComponent {}
View encapsulation fulfills a purpose. The better way is to add styles directly to the component they should affect. ViewEncapsulation
is set per component and may come handy in some situations.
"shadow piercing"
You can also use shadow piercing CSS combinator ::ng-deep
(>>>
and /deep/
are deprecated) to build selectors that cross component boundaries like
:host ::ng-deep .ng-invalid {
border-bottom: solid 3px red;
}
- update
::slotted
is now supported by all new browsers and can be used with `ViewEncapsulation.ShadowDom
https://developer.mozilla.org/en-US/docs/Web/CSS/::slotted
which styles all tags with a class ng-invalid
in the current component or any descendant with a red underline no matter if encapsulation is None
or Emulated
. It depends on browser support whether /deep/
works with Native
(as far as I know this is not supported by any browser anymore).
Note
The shadow piercing CSS combinators are similar to the ones from the shadow DOM spec where they are deprecated since quite a while.
With the default ViewEncapsulation.Emulated
Angulars own /deep/
and ::shadow
implementation are used and they will work even when Chrome removes native support.
With ViewEncapsulation.Native
Angular uses Chromes shadow DOM CSS combinators (only Chrome supported them at all anyway AFAIK). If Chrome finally removes them, then they won't work in Angular as well (again ViewEncapsulation.Native
only).
Global styles
Styles added globally (index.html
) don't consider component boundaries. Such styles are not rewritten by Angular2 and ViewEncapsulation.Emulated
doesn't apply to them. Only if ViewEncapsulation.Native
is set and the browser has native shadow DOM support, then global styles can't bleed in.
See also this related issue https://github.com/angular/angular/issues/5390
Related Topics
Change Color of Svg Spritesheet Sprite with CSS
HTML Picture or Srcset for Responsive Images
Center Text in HTML Number Input
Can You Overlay a Transparent Div on an Image
Prevent Paragraph from Increasing The Width of a Floated Parent
Make an Image to Fit Its Parent Dimensions
Simulating Position: Fixed in Ie6 with a Div of 100% Height
Left Align Text and Right Align Image in CSS
CSS: Placing Divs Left/Center/Right Inside Header
Div at Bottom of Window and Adaptable Height Div
Placeholder Font-Size Bigger Than 16Px
Radio Button Show/Hide Content
Insert Ruby in HTML Class=" " Property
Div Gets Misplaced on Text Insertion and Text Goes Out of Div
Force Div Element to Stay in Same Place, When Page Is Scrolled
Do I Still Need to Include Type="Value" in HTML5