1

I am creating some custom web components. One of the components is a light/dark theme switcher. However, this relies on a specific stylesheet being loaded.

I would like to output a warning if the correct stylesheet has not been loaded.

But, users have several different ways of loading stylesheets (e.g. link tag, @import statement, etc) and so it is not guaranteed that they will have loaded the correct sheet.

The stylesheet that is needed has some pretty specific custom variables and named styles in it. So I would like to know if there is any way from JavaScript (inside my web component), to check whether one of those variables or style names exists in the stylesheets loaded to the current page.

Julian Knight
  • 4,716
  • 2
  • 29
  • 42
  • Does this answer your question? [Accessing a CSS custom property (aka CSS variable) through JavaScript](https://stackoverflow.com/questions/36088655/accessing-a-css-custom-property-aka-css-variable-through-javascript) – RedRex May 07 '22 at 14:58
  • Can you add any details, about your "*[mcve]*" code? What properties are you looking for? The basic answer to your question is "yes, almost certainly," but we can't offer advice until you show us what you're doing, and explain what you want to do. – David Thomas May 07 '22 at 15:25
  • 1
    @RedRex - Thanks for that. `window.getComputedStyle(document.documentElement, null).getPropertyValue('--light-saturation')` does work, even from within a web component module. Better still is this: `window.getComputedStyle(this, null).getPropertyValue('--light-saturation')` from within the web component module. – Julian Knight May 07 '22 at 15:36
  • @DavidThomas, thanks for responding. I am looking for ANY of my custom variables (e.g. `--light-saturation` from within the web component module. I will probably add a var with a more explicit name to avoid a name clash. – Julian Knight May 07 '22 at 15:40
  • Looking at your previous comment, it seems that you've solved your own problem already. So, well done; please post that as an answer to the question, and edit your question to include sufficient information that any other person reading it might be able to devise the same, an alternate, or better approach. – David Thomas May 07 '22 at 15:42
  • :-) I was going to give @RedRex a bit of time to see if they wanted to post an answer first since they found the right clue. But yes, if not, I will post an answer and mark it as correct. – Julian Knight May 07 '22 at 15:46
  • Its on the ``window`` Object and you are not querying a pseudo element, so ``getComputedStyle(this).getPropertyValue('--light-saturation')`` will do. – Danny '365CSI' Engelman May 07 '22 at 16:09
  • Thanks Danny, noted. When working with ECMA modules in the browser, you tend to get super paranoid about scope! – Julian Knight May 07 '22 at 16:19

1 Answers1

1

Many thanks to RedRex for giving me the pointer. Custom variables are accessible but not from the document.style. You have to use getComputedStyle.

So, in my web component Class, I have a connectedCallback function that runs whenever an instance of the component is added to the page.

    connectedCallback() {

        // Is the correct stylesheet loaded?
        if ( !getComputedStyle(this).getPropertyValue('--uib-css').includes('uib-brand') )
            console.warn('[uib-theme-changer] WARNING: It appears that you are not using uibuilder\'s uib-brand.css stylesheet. This component may not work as expected.')

    } // ---- end of connectedCallback ---- //

In the CSS file, I have

:root, :root.light {
    color-scheme: light dark;

    /* Create a checkable var - helps web components know if this stylesheet is loaded.
     * NOTE: no space between : and text! */
    --uib-css:uib-brand;
}

Perhaps worth noting that web components are designed to limit the interaction between the light-DOM CSS and the shadowDom CSS. However, custom variables are designed to flow into your component.

 

Footnote: For the curious, I am writing some custom web components that will play nice with Node-RED and node-red-contrib-uibuilder.

Julian Knight
  • 4,716
  • 2
  • 29
  • 42
  • Make it more failsave with ``if(!getComputedStyle(this).getPropertyValue('--uib-css').includes('uib-brand'))`` – Danny '365CSI' Engelman May 07 '22 at 16:45
  • 1
    As for your Web Components; code can be optimized: [Web Components #102](https://dev.to/dannyengelman/web-component-102-the-5-lessons-after-learning-web-components-101-h9p) – Danny '365CSI' Engelman May 07 '22 at 16:48
  • Thanks Danny. The components very much a work in progress and I've a load to push back to GitHub with already a lot of learning. I'll read through your post for more ideas. Begun to realise how much I'm taking on! – Julian Knight May 08 '22 at 19:00
  • @Danny'365CSI'Engelman: PS: Looks like it was your twinkle example I "borrowed" to get started with web components! Thanks :-) – Julian Knight May 08 '22 at 19:09
  • 1
    Hi @JulianKnight sorry, I was away for a while. Thank you for your detailed answer. – RedRex May 09 '22 at 04:20