javascriptcssgradientlinear-gradientsradial-gradients

gradient tranisition on click


I am looking to transition gradients as part of a dark mode on my website. So on click and not on hover. Also my gradients are a little more complex than two-color linear gradients that previous posts seem to cover but I will figure out new ones if something can be done to transition them on click.

radial-gradient( circle farthest-corner at -4% -12.9%,  rgba(74,98,110,1) 0.3%, rgba(30,33,48,1) 90.2% )
        
linear-gradient( 68.4deg,  rgba(248,182,204,1) 0.5%, rgba(192,198,230,1) 49%, rgba(225,246,240,1) 99.8% )

I tried basically every CSS trick from every post here but they all seem to rely on :hover


Solution

  • background-image has animation type discrete, which means it will jump from the initial value to the new value (though some browsers will animate gradually between CSS keyframes, but not all).

    One way round this is to gradually fade out the first background and gradually fade in the second background.

    This snippet does this by adding before and after pseudo elements to the body element.

    When a button is clicked it sets opacity of the before to 0 and the opacity of the after to 1. The effect is rendered gradual by the addition of a transition property - opacity is an animatable property.

    <style>
      body {
        width: 100vw;
        height: 100vh;
      }
      
      body::before,
      body::after {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: -1;
        transition: opacity 5s linear;
      }
      
      body::before {
        background-image: radial-gradient( circle farthest-corner at -4% -12.9%, rgba(74, 98, 110, 1) 0.3%, rgba(30, 33, 48, 1) 90.2%);
        opacity: 1;
      }
      
      body.change::before {
        opacity: 0;
      }
      
      body::after {
        opacity: 0;
        background-image: linear-gradient( 68.4deg, rgba(248, 182, 204, 1) 0.5%, rgba(192, 198, 230, 1) 49%, rgba(225, 246, 240, 1) 99.8%);
      }
      
      body.change::after {
        opacity: 1;
      }
    </style>
    
    <body><button onclick="document.body.classList.add('change');">click me</button></body>