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.