How to use parent CSS from Shadow DOM - html

I have css from parent application that I want to use inside a web-component made by shadow dom. I don't want to copy css from parent aplication to web-component, but right now, the web-component can't see the parent application css, how can I do that?
parent app:
<style>
.pretty-button {
color: green
}
</style>
<body>
<button class="pretty-button">Got It</button>
<custom-element></custom-element>
</body>
web-component made by shadow dom:
<!--doesn't work because the shadow dom can't use parent css class-->
<body>
<button class="pretty-button">Got it from shadow dom</button>
</body>

Shadow DOM is protected from outside CSS. This is by design.
TL;DR:
If you want the outside CSS to affect DOM inside the shadowRoot of a custom element then you need to either:
Use a <slot> or
Copy the CSS into the shadowDOM
Here are three answers I have given on similar questions:
I have an element that i have declared as a shadow dom but the style is affecting the other elelemts
Why does my Web Component CSS not show? I am not using shadowDOM
slot selector limit in webcomponent

Related

Is it possible to style the shadow root container itself?

Wondering if it's possible to style the shadow root container? I have these attached to a parent custom element, and would like the custom element to always carry a margin: 5px.
Instead of adding this to the document's CSS, I would like to encapsulate this into the template attached to the component. But shadow root isn't quite an HTMLElement, so is the only way to add a <div> inside the template that acts as the container, and style that <div> instead?
The closest thing is probably using the :host CSS selector. Using :root inside the shadow DOM does not get to a document as there is none inside the shadow DOM, and the selector is not allowed to ascend out of the shadow DOM encapsulation.
Hint: if your host doesn't have display: inline-block it may not apply background or border as you expected.

Why does this globally defined css rule affect styling inside of the shadow DOM?

I created an web-component with shadow mode 'open', which is used like this:
<scu-switch checked="true" value="switch1">
<span id="scu-switch-label">Switch On</span>
</scu-switch>
and looks like this:
Than I added the button to a webpage with the following global CSS:
text-align: center;
and now the button style is broken:
When I inspect the button I can see, that the global style was applied to the span (and notice that it is not part of slot content) inside of the shadow root.
The shadow DOM is supposed to isolate style from the rest of the web page.
Why was this text-align: center applied here, even though it was defined outside of the Shadow DOM?
One of the great features of the Shadow DOM in Web Components is that styles are encapsulated to the component - you can style your component without worrying about any specifier (id, class, etc.) conflicts or styles 'leaking out' to other elements on the page.
This often leads to the belief that the reverse is true - that styles outside of the component won't cross the Shadow boundary and 'leak in' to your component. However this is only partly true.
While specifiers do not leak in to your component (e.g. a color applied to an p element in a style rule outside of your component won't effect any p elements in your Shadow DOM, although the rule will be applied to your Light DOM, or slotted content),
inheritable styles applied to any elements containing your component will be applied to both your Shadow and Light DOM.
Source: https://lamplightdev.com/blog/2019/03/26/why-is-my-web-component-inheriting-styles/

How to style deep inside shadow trees

I have a problem with styling deep shadow trees. How can i apply some styles into shadow-dom ?
Here is i tried:
<link rel="import" href="../../bower_components/polymer/lib/elements/custom-style.html">
<custom-style>
<style is="custom-style">
vaadin-text-field [part='input-field']{
display: none;
}
</style>
</custom-style>
But its not working. Any advice ?
My understanding is that you can't, see:
https://www.polymer-project.org/2.0/docs/devguide/style-shadow-dom
"The HTML elements in your template become children in your custom element's shadow DOM. Shadow DOM provides a mechanism for encapsulation, meaning that elements inside the shadow DOM don't match selectors outside the shadow DOM."
Instead you need to extend the webcomponent, making custom version of it with your styles, the linked documentation gives information on that too.
you can use vaadin-themable-mixin to style parts elements.
But please note that once theme is loaded, it's will become global, so that all vaadin control in your website is styled by your theam.
read more at:
https://github.com/vaadin/vaadin-themable-mixin/wiki/1.-Style-Scopes

How can I prevent an element from being styled by light DOM styling?

I am trying to wrap my head around the light DOM and shadow DOM concepts.
What I am figuring out to do here is how to move the light dom part, inside the shadow dom so it does not get styled by the .foo selector...
I got this
<polymer-element name="my-element" constructor="" attributes="" noscript>
<template>
- <content></content> -
</template>
</polymer-element>
And my element is used like so:
<my-element>
<div class="foo">Shadow</div>
</my-element>
Now what I understand is that the div inside my-element gets tossed into the light dom (And gets styled by .foo), and <my-element></my-element> is what gets put inside the shadow DOM.
But, how can I put the div inside the shadow dom as well? (in effect hiding it from .foo)
example:
https://jsfiddle.net/mLT5G/52/
edit: A more real world example would be something along the lines of
<cards>
<card>
<h3>Title</h3>
<p>Body</p>
<card>
<cards>
From what I understand now, in essence I would be making 2 custom components here.
So, one for cards, which imports card
However the H3 and P will always take on the default styling of the page it's been put into? (If not overridden...)
Would I need to make another custom component? So instead of the H3 I create card-title and the p would be inserted by <content></content>
I realise I can do it like that, but I am wondering if that is the way to go.
You could use the ::content selector to try to override any styles that the page may have applied: http://jsbin.com/muyapu/2/edit
Or you could use the new all property to reset styles, however it's only supported in Chrome and Firefox. http://jsbin.com/daxaf/2/edit

Page doesn't render extended Polymer element

I am trying to extend the Polymer core-selector but it doesn't render on the webpage.
When I place <shadow></shadow> inside the template-tags it does render.
I don't know for sure if that is the real problem. What is the purpose of the shadow-tags? I don't find information about that in the API documentation.
Here is the link to an example: http://jsbin.com/qucitiwe/3/edit?html,console
You can find some information on how to extend elements in the Extending other elements section of the Polymer documentation.
The shadow element renders the shadow DOM of the parent element (the DOM inside the parent's template element) at this exact location. So without the shadow element you won't see any DOM from the parent element.
In addition, a child element can wrap the parent's shadow DOM with its own content, for example:
<template>
<div>Title</div>
<shadow></shadow>
<div>Footer</div>
</template>