skip to Main Content

I’m trying to set opacity of HSLA background color dynamically using CSS variables.
First I created a variable --color for color, which has --alpha variable in it as alpha. It works, but I am not able to override the --alpha variable at element level. The --alpha: .5 on h1 tag is applied to the element, but i am not seeing the transparency on the element.

REPL here: https://svelte.dev/repl/d4e15ba129324149915c2e124eeecb76?version=3.59.1

<script>
    let name = 'world';
</script>

<h1 style="--alpha: .5">Hello {name}!</h1>

<style>
    :global(:root) {
        --alpha: 1;
        --color: hsla(225, 50%, 50%, var(--alpha));
    }
    h1 {
        background-color: var(--color);
    }
</style>

2

Answers


  1. I am not sure what’s the best approach for you as I don’t know what you are trying to do but one solution would be setting the CSS variable using Javascript:

    <script>
        let alpha = 0.5;
        let root = document.querySelector(":root")
        $: root.style.setProperty('--alpha', alpha);
    </script>
    

    Now whenever you change the alpha value the root.style.setProperty('--alpha', alpha); will rerun achieving what I think you want.

    Login or Signup to reply.
  2. Because the variable is defined on a different element, higher in the tree, the change to --alpha will not affect --color as that is resolved at a different level with a different --alpha value.

    One way around that would be to define the variables on all elements in the component (would not recommend using :global if it can be avoided, if some children in another component rely on this it may be necessary though).

    * { 
      --alpha: 1;
      --color: hsla(225, 50%, 50%, var(--alpha));
    }
    

    For scoped styles the selector is turned into just a class selector in the form .svelte-[hash] but for global styles it might be best to avoid this approach if it negatively impacts performance.

    A more optimized way if you need :global would be to move just the color declaration to a special class which then needs to be applied on elements where the --color is being referenced (in this case the h1 or any child components):

    :global(.custom-color) {
      --color: hsla(225, 50%, 50%, var(--alpha));
    }
    

    If you extract all other color components (hue, saturation, lightness) and drop --color altogether, you could avoid this situation, though you also would always have to spell out a lengthy hsla definition everywhere.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search