Suryakiran Allu
Suryakiran Allu

Reputation: 43

How do I style ShadowDOM elements using external CSS in Firefox?

I'm trying to build a custom HTML element. The problem is that I'm not able to apply styles to the Shadow DOM elements provided using external CSS. The code is working in Chrome but not in Firefox.

var proto = Object.create(HTMLElement.prototype);

proto.createdCallback = function() {

    console.log('Element creation started...');

    var inputTextElement = document.createElement('input');
    inputTextElement.type = 'text';
    inputTextElement.className = 'simpleElem';

    // Shadow DOM root
    var shadowRoot = this.createShadowRoot();

    shadowRoot.appendChild(inputTextElement);

    console.log('Element creation ended...');

};

var SimpleElement = document.registerElement('simple-element', { prototype: proto });
simple-element {
}

simple-element::shadow  .simpleElem {
    height: 30px;
    margin: 0px;
    padding: 0px;
    width: 180px;
}
<!doctype html>
<html>
    <head>
        <title>HTML5 | Custom Elements</title>
        <link type="text/css" rel="stylesheet" href="simple-elem.css">
        <script type="text/javascript" src="simple-elem.js"></script>
    </head>
    <body>
        <simple-element></simple-element>
    </body>
</html>

Not able to figure out what is wrong with Firefox.

Upvotes: 4

Views: 2541

Answers (3)

G&#225;bor Imre
G&#225;bor Imre

Reputation: 6299

Update: FF Shadow DOM support has arrived.

Firefox has no Shadow DOM support yet, see CanIUse.com. I recommend sticking to Chrome. EDIT: FF Nightly has some support, it can be enabled manually.

Upvotes: 2

TylerH
TylerH

Reputation: 21097

While Shadow DOM in general has been supported in Firefox for a while now (invalidating the two other answers), with Firefox 72 you can now target custom/Shadow DOM elements via the part attribute and ::part() pseudo-element, respectively:

//this JS boilerplate adapted from MDN
let template = document.getElementById("simple-element");
globalThis.customElements.define(template.id, class extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: "open" });
    this.shadowRoot.appendChild(template.content);
  }
});
simple-element::part(shadow) {
    height: 30px;
    margin: 0;
    padding: 0;
    width: 180px;
    background: green;
}
<template id="simple-element">
    <div part="shadow">Hi</div>
</template>

<simple-element></simple-element>

Obviously this code looks a lot different from what your question code looks like because the Shadow DOM spec/implementations have changed quite a lot since 2014.

Upvotes: 2

CletusW
CletusW

Reputation: 3980

As noted by Gábor Imre, Shadow DOM is not enabled by default in Firefox because it is still under development. You can, however, use a polyfill to get pretty good Shadow DOM behavior in all browsers that don't support it.. If you do, you'll then need to use polyfill-next-selector to obtain the behavior you want.

Upvotes: 2

Related Questions