Search code examples
javascriptcssfocusshadow-domcustom-element

Can't find CSS selector to style Shadow DOM delegated focus


EDIT 1+

Ok, sorry for the wild goose chase. this appears to be a straight forward CSS issue. In the light DOM: -

#disTick::part(endo) {
    box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,1); */
    background: linear-gradient(to top, #165273 0%, #33a1de 100%);
}   
#disTick::part(endo):hover, /* We overrode the Tick box-shadow above so now must also control highlighting. */
#disTick::part(endo):focus {
    box-shadow: 0 0 0.2em black;
}

The box-shadow for #disTick::part(endo) is overridden by the #disTick::part(endo):hover but not the #disTick::part(endo):focus

IOW, If I comment out the first rule then the focus rule works fine.

How can that be right?

EDIT 1-

I have added the delegatesFocus attribute to my custom element's Shadow DOM like: -

    this.#shadowRoot = this.attachShadow({ mode: 'open', delegatesFocus: true });

It certainly looks like it works because you can see the traditional Outline focus-styling on my "Disable Toggle" tickbox.

Now I want to use CSS to turn off the default outline and add my own Focus styling. To this end I added the following to test_toggle.html :-

#disTick:focus {
    outline: none;
    box-shadow: 0 0 0.2em black;
}

Problem is, it doesn't do anything :-(

As you can see #disTick is the host (I think) and I've added the CSS all around both the Shadow and Light DOM and just can't get it to take effect.

Please advise what CSS Selector I need to find the element(s) that have been delegated for Focus.


Solution

  • custom-element::part():focus works. For example:

    #disTick::part(endo):focus {
      outline: 5px solid yellow
    }
    

    But the targeted element must be focusable.

    Here endo is a <span>. You can make it focusable by adding a tabindex attribute.

    In the custom element definition:

    span.tabindex = 1
    

    Then, on a click event, call focus().