'How can I change CSS variable on button click?

How can I make CSS change the button's box-shadow from var('--out') to var('--in') on button click, and when you click it again it'll change back to --out?

I tried doing it but whenever I click the button it just removes the whole shadow.

HTML + JS:

<body>
<section>
<button class="color_1">

</button>

<script>
    const btn = document.querySelector('button')
    const state = '--out'
    btn.addEventListener('click', _ =>{
        document.documentElement.style.setProperty(state, '--in')
    })
</script>

</section>
</body>

CSS:

:root{
    --in: inset 25px 25px 60px rgba(0,0,0,.5);
    --out: inset -25px -25px 60px rgba(0,0,0,.5);
}
.color_1{
    background-color: blue;
    border-radius: 200px;
    height: 300px;
    width: 300px;
    box-shadow: var(--out);
}


Solution 1:[1]

You need to use the :root selector with document.querySelector instead of document.documentElement to change the css variable. You also need to change the css to use a new --state variable that you can toggle between --in and --out with the JS code. You will also need to use getProperty to get the value of the --in or --out css variable before changing it. The following code in the script tag should fix your problem:

const btn = document.querySelector('button')
const state = '--in'
btn.addEventListener('click', _ =>{
    var root = document.querySelector(":root")
    root.style.setProperty("--state", root.style.getProperty(state))
})

And also using the following in your style tag:

:root{
    --in: inset 25px 25px 60px rgba(0,0,0,.5);
    --out: inset -25px -25px 60px rgba(0,0,0,.5);
    --state: var(--out);
}
.color_1{
    background-color: blue;
    border-radius: 200px;
    height: 300px;
    width: 300px;
    box-shadow: var(--state);
}

Solution 2:[2]

Ok here's what I got for you!

  1. It was removing --out value and setting it to --in looked like this (--out: --in;). Which is why we were seeing the box-shadow being removed

  2. This code: document.documentElement - was not targeting your button background - change it to: btn.style.boxShadow

const btn = document.querySelector('button');
   const state = '--out'
   btn.addEventListener('click', _ =>{
       document.documentElement.style.boxShadow = 'var(--in)';
   })

Solution 3:[3]

You can define two possible states and toogle between them.

<body>
    <style>
        :root{
            --in: inset 25px 25px 60px rgba(0,0,0,.5);
            --out: inset -25px -25px 60px rgba(0,0,0,.5);
            --one: blue;
            --two: red;
        }
        .color_1{
            background-color: var(--one);
            border-radius: 200px;
            height: 300px;
            width: 300px;
            box-shadow: var(--in);
        }

        .color_2{
            background-color: var(--two);
            border-radius: 200px;
            height: 300px;
            width: 300px;
            box-shadow: var(--out);
        }
    </style>
    
<section>
<button class="color_1">

</button>

<script>
    const btn = document.querySelector('button')
    const state = '--out'
    btn.addEventListener('click', _ =>{
        states = ['color_1', 'color_2']
        actualClassName = btn.classList[0]
        btn.classList.remove(actualClassName)
        if (actualClassName === states[0]){
            btn.classList.add(states[1])
        } 
        else{
            btn.classList.add(states[0])
        }
    })
</script>

</section>
</body>

Demo

Finally, the best solution would be toogle only the state you desire, like this:

<body>
    <style>
        :root{
            --in: inset 25px 25px 60px rgba(0,0,0,.5);
            --out: inset -25px -25px 60px rgba(0,0,0,.5);
            --one: blue;
            --two: red;
        }

        .color_1{
            background-color: blue;
            border-radius: 200px;
            height: 300px;
            width: 300px;
        }

        .state1{
            box-shadow: var(--out);
        }
        
        .state2{
            box-shadow: var(--in);
        }
    </style>
    
<section>
<button class="color_1 state1">

</button>

<script>
    const btn = document.querySelector('button')
    const state = '--out'
    btn.addEventListener('click', _ =>{
        btn.classList.toggle('state2');
    });
</script>

</section>
</body>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Cristik
Solution 3