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.
Related
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/
Here is the simple HTML I have. h1 is inside the shadow root but it's green. Is this behavior of color inheritance from parent elements outside shadow DOM expected? I'm wondering because the element selectors can't cross shadow boundaries (h1 styles are not applied to h1 inside the shadow root)
<head>
<style>
body { color: green }
h1 { color: red; }
</style>
</head>
<my-element>
#shadow-root
<h1>text is green</h1>
</my-element>
Ideally I'm looking for a part of a spec that defines this behavior.
Yes, this behavior is expected. From the spec:
The top-level elements of a shadow tree inherit from their host element.
In your case, the shadow host, my-element, inherits the color from the body element. The h1, being in the shadow root of my-element, inherits from my-element.
There exists a shadowHost and shadowRoot.
shadowRoot is what is attached to an element to give a shadow DOM.
shadowHost is what that shadow root is attached to.
Aparently when you define something flat in the html page it gets attached to body element shadowroot.
Same that say it is attached to shadowDOM of body, or with body as shadowHost.
I guess it is default behaviour as the 'default shadowRoot'. Where you are writing 'text is green' since body is supposed to be the root element for page content. While html tag describes document language. And head defines metadata content.
So green style is being correctly inherited.
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
On an asp control I have an html element that has a css style applied to it using a ::before pseudo element.
Sometimes depending on some variables that are determined in the code behind of the control I don't want that ::before style to be applied.
How can I accomplish this, since the ::before element is not an actual element on the page?
Thanks
I have a text input that is wrapped inside a div. I want to change a css attribute of the :after of the parent div when the input is focused. How can I do this in CSS?
<div class="dataInputTextContainer">
<input class="dataInputText" />
</div>
I tried this but it did not work:
.dataInputText:FOCUS ~ .dataInputTextContainer:after{
background-color: red;
}
Simply put, you cant
(sorry)
CSS works in terms of DOM decendancy, in that rules can only be constructed for elements which appear subsequently in the DOM. As such, you cannot select a parent, or even previous sibling.
What I would tend to suggest is that you sit down, take a step back and work out what you are trying to accomplish. 99% of the time either someone else out there has done it, or you can do it with a minor change to either your CSS or HTML.
Incidentally, a solution would not be to try and style :before or :after on the input, it is a replaced element so such elements do not apply. Why not simply add a label for the input and style it?
If you didn't apply style on :after of the parent but rather put a tag at the same level than the input, you could have used this syntax to apply style of the sibling tag.