Override styles in a shadow-root element
Because of the isolation of styles, which is a feature of Shadow DOM, you cannot define a global CSS rule that will be applied in the Shadow DOM scope.
It could be possible with CSS variables but they should be implemented explicitly in the shadowed component (which is not the case with this 3rd party library).
A workaround is to inject the line of style in the shadow DOM directly.
//host is the element that holds the shadow root:
var style = document.createElement( 'style' )
style.innerHTML = '.the-class-name { property-name: my-value; }'
host.shadowRoot.appendChild( style )
NB: it will work only if the Shadow DOM mode
is set to 'open'
.
2019 update for Chrome 73+ and Opera 60+
Now it is possible to instantiate a CSSStyleSheet object directly and to affect it to a Shadow DOM or a document:
var sheet = new CSSStyleSheet
sheet.replaceSync( `.color { color: pink }`)
host.shadowRoot.adoptedStyleSheets = [ sheet ]
How to change css of an element in shadow Dom when the main dom contains a class
You can use :host-context()
CSS fonction in the Shadow DOM style.
:host-context(.parent-div) .child-div{
display:none
}
document.querySelector( '#shadow_host' )
.attachShadow( { mode: 'open' } )
.innerHTML = `
<style>
:host-context(.parent-div) .child-div {
display:none
}
</style>
<div class="child-div">some random things</div>
`
<div class="parent-div">
<div id="shadow_host">
</div>
</div>
In Shadow DOM, override CSS body *
Most of the information needed to answer this can be found in this related answer. In summary: A document-wide style without !important
will always override a shadow dom style without !important
, if they apply to the same element.
(And in this case, they do apply to the same element: slotted elements exist outside the shadow dom, so *
rules in the document stylesheet can find them.)
You've already found two workarounds to this. I'll list them here for completeness:
Use !important:
This is ugly, but it does work. Not only does !important
override any and all non-!important
rules, but it also overrides any !important
rules coming from the document-wide stylesheet!
Reduce the body *
rule to just body
:
This way, the rule won't apply directly to every element - it will only apply directly to body
, and affect every other element via inheritance. Inherited rules can be overridden by anything, since they're only a fallback in case nothing else applies.
Modifying custom elements' style in shadow root
In order to style the element that hosts the Shadow DOM, here <custom-calculator>
, you must use de :host
pseudo-class (instead of custom-calculator
which is unknown inside the Shadow DOM).
:host {
display:inline-block;
background-color:grey;
width:100%;
height:100vh;
vertical-align:top;
}
Because the Shadow DOM will replace/recover the normal DOM tree (here <output-screen>
), you'll have to use <slot>
to insert/reveal it in the Shadow DOM.
calc.shadowRoot.innerHTML = `
<style>
...
</style>
<slot></slot>`
Then, in order to style what is revealed by/in the <slot>
element, you mus use the ::slotted()
pseudo-element:
::slotted( output-screen ){
display:inline-block;
background-color:orange;
width:50%;
height:100vh;
}
Live example:
var calc = document.querySelector('#calculator')
calc.attachShadow({mode: 'open'});
calc.shadowRoot.innerHTML = `
<style>
:host {
display:inline-block;
background-color:grey;
width:100%;
height:100vh;
vertical-align:top;
}
::slotted( output-screen ){
display:inline-block;
background-color:orange;
width:50%;
height:100vh;
}
</style>
<slot></slot>`;
<custom-calculator id="calculator">
<output-screen></output-screen>
</custom-calculator>
Related Topics
Managing Jquery Plugin Dependency in Webpack
Jquery Scroll() Detect When User Stops Scrolling
Delete Firebase Data Older Than 2 Hours
Can't Access Object Property, Even Though It Shows Up in a Console Log
How to Show a Running Progress Bar While Page Is Loading
Html5 Video - Percentage Loaded
Webkit-Transform Overwrites Z-Index Ordering in Chrome 13
Bootstrap Modal: Background Jumps to Top on Toggle
Add a Transform Value to the Current Transforms That Are Already on the Element
Reading Non-Inline CSS Style Info from JavaScript
How to Have a Host and Container Read/Write the Same Files with Docker
Get Contenteditable Caret Position
Window Is Not Defined in Next.Js React App