Why Does My Web Component CSS Not Show? I Am Not Using Shadowdom

Why does my Web Component CSS not show? I am not using shadowDOM

If you are creating a component that does NOT use ShadowDOM that you may still need to add your CSS into a shadowRoot. If someone else places your component into their shadowDOM, then you must add your CSS to their shadowRoot. You can do this with the following code:

const myStyle = document.createElement('style');myStyle.setAttribute('component', 'my-el');myStyle.textContent = `    button {  padding: 8px 20px;}.happy-btn {  background-color: pink;}
.sad-btn { background-color: #007; color: white;}`;
function addCss(el, selector, styleEl) { // Check to see if we have been placed into a shadow root. // If we have then add our CSS into that shadow root. let doc; try { doc = el.getRootNode(); if (doc === document) { doc = document.head; } } catch(_ex) { doc = document.head; } // Shadow DOM isn't supported.
if (!doc.querySelector(selector)) { doc.appendChild(styleEl.cloneNode(true)); }}
class MyEl extends HTMLElement { constructor() { super(); addCss(this, 'style[component="my-el"]', myStyle); } connectedCallback() { this.innerHTML = `<div class="spaced"><button class="happy-btn">I'm Happy</button></div> <div class="spaced"><button class="sad-btn">I'm Sad</button></div>`; }}customElements.define('my-el', MyEl);
class TheirEl extends HTMLElement { constructor() { super(); this.attachShadow({mode:'open'}); this.shadowRoot.innerHTML = `<hr/><my-el></my-el><hr/><my-el></my-el><hr/>`; }}customElements.define('their-el', TheirEl);
<their-el></their-el>

HTML web component does not use shadow DOM style

While this question already has an accepted answer, moving a slot's children to the shadowRoot isn't desirable for most use cases.

What you probably want to do is to use the ::slotted() selector.

Just bear in mind that styles applied to a slot's children through the ::slotted() selector only act as "default" styles and can still be overridden by using styles in light DOM.

For example, check this edited version of your snippet:

As you can see, this time my-el tries to apply both a color and a text-decoration style to anchor (<a>) children in any of it's slots.

However, in light dom, we have a a.special selector that overrides the color, so the <a class="special"> will be red, not green

class MyEl extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: "open" });
}

connectedCallback() {
const template = `
<style>
::slotted(a) {
color: green;
text-decoration: none;
}
</style>
<slot></slot>`;
this.shadow.innerHTML = template;
}
}

window.customElements.define("my-el", MyEl);
a.special {
color: red
}
  <my-el>
<a href="example.com">Item1</a>
<a class="special" href="example.com">Item2</a>
</my-el>

Outside stylesheet css not work in the shadow dom (HTML Web Component)

Here's some basic about 'Shadow Dom'!

My problem above was didn't know inside of shadow dom, element can't see any code outside of the container. the best soultion i found so far was code below:

Simplely create a link tag to the style sheet just like what we did in nomal html.

const linkElem = document.createElement('link');
linkElem.setAttribute('rel', 'stylesheet');
linkElem.setAttribute('href', 'style.css');

shadow.appendChild(linkElem);

shadow dom style not showing

If you define a SVG element with createElement, you should set the specific SVG namespace which is http://www.w3.org/2000/svg.

You must then use createElementNS() method:

this.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');

Slots does not work on a html web component without shadow dom

Yes, <slot> only works in shadowDOM

Slotted content is reflected lightDOM content

See: ::slotted CSS selector for nested children in shadowDOM slot

A Web Component without shadowDOM only has innerHTML

If you do this.innerHTML= on such a Web Component it replaces the innerHTML, just like on any other HTML tag

with shadowDOM:

<hello-world>
<b slot="none">Mighty</b>
<span slot="title">Web Components</span>
Hello!
</hello-world>

<script>
customElements.define("hello-world", class extends HTMLElement {
constructor() {
super()
.attachShadow({mode:"open"})
.innerHTML = `<div><slot></slot><slot name="title">Foo Bar</slot></div>`;
this.onclick = (evt) => this.querySelector('b').slot = "title";
}
});
</script>

CSS is not fully applying on a shadow DOM using slot

Default value for CCS property color is inherit.

Default style for CSS property background-color is transparent (won't inherit from its parent element).

Default custom element display property is inline (= phrasing content) and therefore won't settle background properties to its children.

In your code, the "Test" text is in a <p> element, that won't inherit from the :host background color, but will be transparent and therefore will display the background color of the main page, which is white.

See the live example below for a complete use case.

const template = document.createElement('template')template.innerHTML = `  <style>    :host  {      background-color: var(--my-bg);      color: var(--my-text);    }  </style>  <slot></slot>  <hr>  Text in Shadow DOM root  <p>Text in Paragraph in Shadow DOM <span>and child Span</span></p>  <span>Text in Span in Shadow DOM <p>and child Paragraph</p></span>`class MyElement extends HTMLElement {  constructor() {    super()    this.attachShadow({mode: 'open'})        .appendChild(template.content.cloneNode(true)) }}window.customElements.define('my-element', MyElement)
body {  background-color: lightblue;}
my-element { --my-bg: green; --my-text: red;}
<my-element myStyling>  Text in Light DOM root  <p>Text in Paragraph in Light DOM  <span>and Child Span</span></p>  <span>Text in Span in Light DOM <p>and child Paragraph</p></span></my-element>

CSS property 'cursor' not working with :host selector

Runs fine:

  customElements.define("my-element", class extends HTMLElement {
connectedCallback() { // so attributes can be queried
this
.attachShadow({mode:"open"})
.innerHTML = `<style>
:host {
display: inline-block;
}
:host([disabled]) {
cursor: not-allowed !important;
background: pink !important;
color: grey !important;
}
</style>
<h1><my-element
${this.hasAttribute("disabled")?"disabled":""}></h1>`;
}
})
<style>
my-element{
cursor: pointer;
background: lightgreen;
color: green;
}
</style>

<my-element></my-element>
<my-element disabled></my-element>


Related Topics



Leave a reply



Submit