Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding/removing classes defined in shadow DOM

I have made a pretty basic web component. I'm adding and removing classes with JavaScript written inside the custom element constructor.

Why is it that when I move the classes from the stylesheet of the document to the stylesheet inside the custom element's shadow DOM, my javascript is no longer able to add or remove them?

class BgAnim extends HTMLElement {
        constructor() {
            super()

            this.attachShadow({
                mode: 'open'
            })
            this.shadowRoot.innerHTML =
                `
<style>

:host {
background-image: linear-gradient(#0fe0e0 0%, #0fe0e0 50%, transparent 50%, transparent 100%);
background-size: 100% 200%;
background-repeat: no-repeat;
background-position: 0 100%;
padding: 4px;
}
</style>

<span><slot></slot></span>
`

            this.addEventListener('mouseenter', function () {
                this.classList.add('transition')
                this.classList.add('bg-position0')
            })
            this.addEventListener('mouseleave', function () {
                this.classList.add('bg-position-negative')
                var that = this
                setTimeout(function () {
                    that.classList.remove('transition')
                    that.classList.remove('bg-position0')
                    that.classList.remove('bg-position-negative')
                }, 510)
            })
        }
    }

    customElements.define('bg-anim', BgAnim)

The styles that I want to add and remove with my javascript are

    .transition {
        transition: background-position .5s ease-in;
    }

    .bg-position0 {
        background-position: 0 0%;
    }

    .bg-position-negative {
        background-position: 0 -100%;
    }

When they're in the shadow DOM my JS doesn't work:

this.shadowRoot.innerHTML =
                `
<style>
    .transition {
    transition: background-position .5s ease-in;
}

.bg-position0 {
    background-position: 0 0%;
}

.bg-position-negative {
    background-position: 0 -100%;
}

:host {
background-image: linear-gradient(#0fe0e0 0%, #0fe0e0 50%, transparent 50%, transparent 100%);
background-size: 100% 200%;
background-repeat: no-repeat;
background-position: 0 100%;
padding: 4px;
}
</style>
<span><slot></slot></span>
`
like image 936
Ollie Williams Avatar asked Sep 01 '25 06:09

Ollie Williams


1 Answers

To make your styles work in a Shadow DOM, you should use :host([selector]):

:host(.transition) {
    transition: background-position .5s ease-in;
}

:host(.bg-position0) {
    background-position: 0 0%;
}

:host(.bg-position-negative) {
    background-position: 0 -100%;
}
like image 86
Supersharp Avatar answered Sep 02 '25 19:09

Supersharp