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
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:
Now whenever you change the alpha value the
root.style.setProperty('--alpha', alpha);
will rerun achieving what I think you want.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).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 theh1
or any child components):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 lengthyhsla
definition everywhere.