Adrian
Adrian

Reputation: 79

CSS selector for child of shadow root

<curie-image id="DynamicImage1">
    #shadow-root
        <img alt="No Image" style="width:100%;height:100%" src="data:image;base64, ...">
</curie-image>

I am trying to access the img element above to set its object-fit attribute. I do not have access to the underlying JavaScript, so cannot set the part attribute of the shadow root's children, and so Styling children of shadow dom ::part element will not work in my case. Also, I believe using the :host() selector will not work in this case, as the selector needs to be "evaluated in the context of a shadow tree" in order to work.

Given these constraints, is there any CSS selector which will select a child of my shadow root, from a context outside of the shadow root?

For some reason, a simple selector for img in the global CSS file does select the img element in this shadow root, even though it supposedly should match all such elements, even if they are within a shadow root - see CSS and resulting style below (note that the object-fit attribute has not been set for the img element).

...
img { 
  object-fit: none;
}

enter image description here

Upvotes: 4

Views: 3910

Answers (1)

Since it is an open shadowRoot, you have JavaScript access with

.querySelector("curie-image").shadowRoot.querySelector("img").style.objectFit="none"

But that is ductaping styles.

Dive to all <img>

You could dive into all IMGs with:

(will not dive into closed shadowRoots)

const shadowDive = (
  el,
  selector,
  match = (el, root) => {
    if(root.localName == "curie-image"){
      el.style.ObjectFit="none";
    }
  },
  root = el.shadowRoot || el
) => {
  root.querySelector(selector) && match(root.querySelector(selector), root);
  [...root.querySelectorAll("*")].map(el => shadowDive(el, selector, match));
}

shadowDive(document.body, 'img[style]' );

disclaimer: untested code snippet


Preferable you will want to change the curie-image source code and introduce HTML <slot> and CSS ::part (you can also dynamically wack on with JS)

Note:

Web Components can do Client Side, what no Framework can with a Component:

customElements.define( "curied-image" , 
  class extends customElements.get("curie-image") {

  connectedCallback(){
    super.connectedCallback(); // call original <curie-image> connectedCallback
    
    // now do what you want with 'this' <curied-image> Web Component here

  }

});

See my Dev.To posts:

note: You can extend closed Web Components; but you can still not access its shadowRoot.

Upvotes: 1

Related Questions