Question

My project will display a sunny field and a check box that says "make it rain". Upon clicking the button the sun sets, and clouds come in, and there will be animated CSS rain. I'm using a checked pseudo class to start the rain animation and the rotation of the sun.

How can I reverse the animation for the unchecked state?

The order the page should work in is as follows:

  1. Page loads, default unchecked state of button, sun should be up
  2. User clicks button, pseudo class:checked gets activated and the animation starts
  3. User clicks button again, thus unchecking the button and the animation should reverse to it's original state.

Right now, it just resets the whole page when the button gets unchecked. Is there a way to reverse the animation to it's original state without using any JavaScript? This project is CSS only.

.sky {
  height: 70%;
  width: 100%;
  position: absolute;
  z-index: 1;
  background: #e4f5fc;
  /* Old browsers */
  background: -moz-linear-gradient(top, #e4f5fc 0%, #bfe8f9 33%, #9fd8ef 86%);
  /* FF3.6+ */
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #e4f5fc), color-stop(33%, #bfe8f9), color-stop(86%, #9fd8ef));
  /* Chrome,Safari4+ */
  background: -webkit-linear-gradient(top, #e4f5fc 0%, #bfe8f9 33%, #9fd8ef 86%);
  /* Chrome10+,Safari5.1+ */
  background: -o-linear-gradient(top, #e4f5fc 0%, #bfe8f9 33%, #9fd8ef 86%);
  /* Opera 11.10+ */
  background: -ms-linear-gradient(top, #e4f5fc 0%, #bfe8f9 33%, #9fd8ef 86%);
  /* IE10+ */
  background: linear-gradient(to bottom, #e4f5fc 0%, #bfe8f9 33%, #9fd8ef 86%);
  /* W3C */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#e4f5fc', endColorstr='#9fd8ef', GradientType=0);
  /* IE6-9 */
}

.rainsun {
  position: absolute;
  margin: 35px 45%;
  width: 15.74803%;
  /*--300px--*/
  color: white;
  text-align: center;
  text-shadow: 0 1px 0 rgba(0, 0, 0, .5);
  font-size: 2.5em;
  cursor: pointer;
  z-index: 5;
}

.rainsun:after {
  position: absolute;
  display: block;
  padding: 10px 0;
  width: 100%;
  /*--300px--*/
  border: 1px solid #76011b;
  border-radius: 8px;
  background: linear-gradient(to bottom, rgba(169, 3, 41, 1) 0%, rgba(143, 2, 34, 1) 44%, rgba(109, 0, 25, 1) 100%);
  box-shadow: 0px 0px 10px rgba(19, 93, 158, .6);
  content: "Make it Rain";
  z-index: 5;
}

.rainsun:checked:after {
  background: linear-gradient(to bottom, rgba(109, 0, 25, 1) 0%, rgba(143, 2, 34, 1) 61%, rgba(169, 3, 41, 1) 100%);
  content: "Make it Shine";
}

.sun_path {
  border: 1px dashed black;
  width: 44.094488%;
  height: 100%;
  position: absolute;
  z-index: 2;
  border-radius: 50%;
  margin-left: 10%;
  margin-top: 10%;
}

.sun {
  width: 30%;
  height: 30%;
  background-color: yellow;
  border: 8px solid orange;
  border-radius: 50%;
  box-shadow: 0 0 128px red;
  margin: auto;
  margin-top: -15%;
}

.grass {
  height: 30%;
  width: 100%;
  position: absolute;
  bottom: 0;
  z-index: 3;
  background: #9dd53a;
  /* Old browsers */
  background: -moz-linear-gradient(top, #9dd53a 0%, #a1d54f 23%, #80c217 70%, #7cbc0a 100%);
  /* FF3.6+ */
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #9dd53a), color-stop(23%, #a1d54f), color-stop(70%, #80c217), color-stop(100%, #7cbc0a));
  /* Chrome,Safari4+ */
  background: -webkit-linear-gradient(top, #9dd53a 0%, #a1d54f 23%, #80c217 70%, #7cbc0a 100%);
  /* Chrome10+,Safari5.1+ */
  background: -o-linear-gradient(top, #9dd53a 0%, #a1d54f 23%, #80c217 70%, #7cbc0a 100%);
  /* Opera 11.10+ */
  background: -ms-linear-gradient(top, #9dd53a 0%, #a1d54f 23%, #80c217 70%, #7cbc0a 100%);
  /* IE10+ */
  background: linear-gradient(to bottom, #9dd53a 0%, #a1d54f 23%, #80c217 70%, #7cbc0a 100%);
  /* W3C */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#9dd53a', endColorstr='#7cbc0a', GradientType=0);
  /* IE6-9 */
}


/*animations*/

.rainsun:checked~.sun_path {
  -webkit-animation: spin-right 3s 1 forwards;
  -moz-animation: spin-right 3s 1 forwards;
  animation: spin-right 3s 1 forwards;
}


/* keyframes */

@-webkit-keyframes spin-right {
  100% {
    -webkit-transform: rotate(180deg);
  }
}

@-moz-keyframes spin-right {
  100% {
    -webkit-transform: rotate(180deg);
  }
}
<input class="rainsun" type="checkbox">
<div class="sky">
</div>
<!--end sky-->
<div class="sun_path">
  <div class="sun"></div>
</div>
<!--end sun_path-->
<div class="grass">
</div>
<!--end grass-->

Was it helpful?

Solution

Instead of using keyframes, try a transform and set transition: transform. Here's an example of what I'm talking about:

.rainsun ~ .sun_path {
  -webkit-transition: -webkit-transform 3s;
  -moz-transition: -moz-transform 3s;
  transition: transform 3s;
}

.rainsun:checked ~ .sun_path {
  -webkit-transform: rotate(180deg);
  -moz-transform: rotate(180deg);
  transform: rotate(180deg);
}

Codepen Fork: Demo

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top