Notification texts go here Contact Us Buy Now!

How to target the Nth element in a webcomponent shadowDOM with CSS ::part()

Unfortunately, the ::part() pseudo-element doesn't support targeting elements based on their position in the shadow DOM tree. From the W3C CSS Shadow Parts specification:

The ::part() pseudo-element can take additional pseudo-classes after it, such as x-button::part(label):hover, but never matches the structural pseudo-classes or any other pseudo-classes that match based on tree information rather than local element information.

All the selectors you tried to use are either not pseudo-classes or are pseudo-classes that rely on tree information instead of local element information.

Fortunately, part names behave similarly to HTML classes. Multiple elements can have the same part name, and a single element can have multiple part names. (This is also mentioned in the CSS Shadow Parts spec.)

Therefore, you can use multiple part names, such as input input-1.

customElements.define("web-component",
        class extends HTMLElement {
            constructor() {
                super();
                this.attachShadow({mode: "open"});
                this.size = this.getAttribute('size');
                this.template = document.createElement("template");
                this.template.innerHTML = '<style>'
                +':host {white-space: nowrap}'
                +'input {text-align:center;width: 3ch;height: 3ch}'
                +'input:not(:last-child){margin-right:.5ch}'
                +'</style>'
                this.render();
            }

            render() {
            
                this.shadowRoot.appendChild(this.template.content.cloneNode(true));

                for (let i = 0; i < this.size; i++) {
                    const input = document.createElement('input');
                    input.setAttribute('part','input input-'+(i+1));
                    input.type = "text";
                    this.shadowRoot.appendChild(input);
                }
            }
        }
    );
web-component::part(input input-1)  {
  background: #ff00ff;
}

web-component::part(input) {
  border: 2px solid orange;
}
<web-component size="6" id="shadow-dom-host"></web-component>

With this approach, you can target specific elements in the shadow DOM using CSS ::part() selectors.

However, it's important to note that the ::part() pseudo-element is still relatively new and may not be supported by all browsers. Therefore, it's a good idea to use a polyfill if you need to support older browsers.

Another potential issue to consider is that the ::part() selector can only target elements that have a part attribute. If an element doesn't have a part attribute, it will not be selectable using ::part().

To ensure that all the elements in your shadow DOM can be targeted using ::part(), you should consistently add the part attribute to all the elements that you want to style.

Post a Comment

Cookie Consent
We serve cookies on this site to analyze traffic, remember your preferences, and optimize your experience.
Oops!
It seems there is something wrong with your internet connection. Please connect to the internet and start browsing again.
AdBlock Detected!
We have detected that you are using adblocking plugin in your browser.
The revenue we earn by the advertisements is used to manage this website, we request you to whitelist our website in your adblocking plugin.
Site is Blocked
Sorry! This site is not available in your country.