LNinja
LNinja

Reputation: 45

how can i get transitions on css to work checkbox

I am trying to add a transition effect to an element on my website. This element is set to display:none, but is set to display:block when a checkbox is clicked (the checkbox is a separate element). What i want to do is make it so that when the checkbox is checked, the element gets set to display:block, and also shows a transition, instead of it popping up. Here is my code:

.category-text {
  width: 82%;
  padding-top: 5px;
  padding-left: 8px;
  font-family: 'Burbank', sans-serif;
  font-size: 30px;
  color: #F4D03F;
}

.desc-toggle {
  position: absolute;
  top: 5px;
  left: 84.4%;
  width: 73px;
  padding: 5px;
  font-family: 'Burbank', sans-serif;
  font-size: 20px;
  color: blue;
  cursor: pointer;
  z-index: 2;
  border: solid #ffffff 2px;
}

#toggle-1 {
  display: none;
}

input[type=checkbox]:checked ~ .category-description {
  position: absolute;
  display: block;
  -webkit-transition: height 0.5s ease-in;
  -moz-transition: height 0.5s ease-in;
  -ms-transition: height 0.5s ease-in;
  -o-transition: height 0.5s ease-in;
  transition: height 0.5s ease-in;
}
  <label class="desc-toggle" for="toggle-1">Description</label>
  <input type="checkbox" id="toggle-1">
  <div class="category-description">
    <p class="category-text">text</p>
  </div>

Upvotes: 3

Views: 7980

Answers (2)

tao
tao

Reputation: 90103

In CSS, a property is animatable if its value can be continuously transitioned from one value to another over a determined period of time.

display property is not animatable. The browser cannot technically determine values between two values of display (i.e: an element can't be half way betwen display:none and display:block).

What you want to do instead is display the element at all times and transition it from an "invisible" state (in which it doesn't interfere with other elements at all) to a "visible" state, in which it is rendered as requested.

In order to animate a property, it has to have an initial value that gets changed to another value based on some condition (in your case input:checked ~). Instead of instantly changing between values, the browser will perform a gradual transition, according to animation properties of the animated property.

Example:

.category-text {
  font-size: 30px;
  color: #F4D03F;
}

.desc-toggle {
  font-size: 20px;
  cursor: pointer;
}

#toggle-1 {
  display: none;
}

.category-description {
  height: 0px;                         /* we start animation from 0px */
  overflow: hidden;                    /* without this the contents will be 
                                        * visible regardless of height */
  transition: height 0.5s ease-in;     /* transition has to be defined on base state of element */
  background-color: #f5f5f5;           /* make transition easier to observe */
}
input[type=checkbox]:checked ~ .category-description {
  height: 100px;                       /* change height when input is checked */
}
<label class="desc-toggle" for="toggle-1">Description</label>
<input type="checkbox" id="toggle-1">
<div class="category-description">
  <p class="category-text">text</p>
</div>
<p>Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt, explicabo.

A few points to note:

  • the transition has to be defined on the more general selector; If you only define inside on input:checked ~ * state, your element will only have a transition when following a checked input and will not have one when the input is not checked (hence, it will not animate when the input is unchecked).
  • the transition has to be made between two animatable values (most browsers cannot animate from some value to auto or initial, even though those values could be calculated by browser and translated into a physical value). However, libraries such as velocity.js can help with that (they do the calculation for you and request the browser to animate between the actual values).

Upvotes: 2

Joey Breithaupt
Joey Breithaupt

Reputation: 95

I made a new snippet to unclutter the code a bit, is this the effect you're going for?

.content {
  height: 300px;
  max-height: 0px;
  width: 300px;
  background: blue;
  transition: max-height .3s ease-in-out;
}
#check {
  display: none;
}
#check:checked ~ .content {
  max-height: 300px;
}
<label id="click" for="check">Click Me</label>
<input type="checkbox" id="check">
<div class="content"></div>

Upvotes: 1

Related Questions