Pure CSS transition snippet
Just a quick tutorial here for those who may need it:
I came across an issue where I was removing a child element within multiple child elements and wanted the parent to “smoothly” readjust its height by sliding up. After trying to add different animations for the parent, I decided to play around on JSFiddle and create some solution for this thing…which actually has nothing to do with the parent at all!
First, let’s look at the basic HTML here
###HTML
<div class="parent">
<div class="child1">
Child 1
</div>
<div class="child2">
Child 2
</div>
<div class="child3">
Child 3
</div>
</div>
<button class="test">
Remove Child 2
</button>
</button>
Basically we have a parent and child relationship. This can be divs, lis, spans, whatever, it shouldn’t really matter.
Then, we have some fairly simple CSS here; bear in mind for this demo/tutorial I decided to go with some static children/parents, but this also works dynamically, as long as you apply the proper styles.
For this demo, we are only going to remove the 2nd child, to show the demo.
###CSS
.parent{
border:1px solid red;
height:auto;
}
.child2{
transition: all 0.4s ease-in-out;
max-height:1em;
opacity:1;
}
As you can see, the .parent
class is pretty straightforward. The .child2
class has an “all” transition with an ease-in-out. It also has the max-height
property, which is set to 1em (aka the height of the text). This max-height
is actually important and the basis for the actual transition itself.
###JavaScript
var btn = document.querySelector('.test');
btn.addEventListener('click', removeEvent, false);
function removeEvent(){
var thisChild = document.querySelector('.child2');
thisChild.style.opacity = 0;
thisChild.style['max-height'] = 0;
}
Pretty straightforward: we are adding an Event listener to the button so that when it’s clicked, we call removeEvent
.
Inside removeEvent()
we see that we are:
- Setting
.child2
tothisChild
variable - adding styles of
opacity
(for the fancy fade) andmax-height
(for fancy “slide” animation
That’s it! When you remove .child2
the element will disappear (it won’t disappear completely from the DOM just yet).
##COOL, BUT CAN’T WE GET RID OF THE DOM NODE TOO?
Yes! Absolutely. JS has a built in event called transitionend
that will fire after the CSS transition is over. Kind of a callback for CSS; nice!
So if we want to add a “remove DOM node” feature, we can do that as well. We’ll add a transitionend
event listener and create a function that removes the DOM node. So in the JS, we’ll do something like this:
document.querySelector('.child2').addEventListener('transitionend', destroyDOMNode, false);
function destroyDOMNode(el){
el.target.parentNode.removeChild(e.target);
}
A simple one line function and we are done!
Check out the final JSFiddle here
BUT PATRICK, CAN’T WE JUST USE JQUERY FOR THIS INSTEAD?
Well yeah, you could. Personally, I prefer Vanilla JavaScript though and I’ll tell you a few reasons why:
- Performance: CSS transitions are generally faster with animation… well…sorta. The key here is simple animations like this are. More complex, GPU intensive animations may not be.
- Simpler code: Although jQuery certainly comes with a lot of animation options, it’s often cumbersome to keep up with and to get everything just right. CSS transitions are as easy as using
transitionend
events and adding/removing classes with the CSStransition
property. - It’s definitely the future: As IE9 support wanes, CSS
transition
is becoming a browser default (YESSS) and it just makes more sense to use CSS as intended rather than constantly use JS animations.
Although these are not hard and fast rules (big surprise in web dev, right?), they’re good guidelines to follow. I’m sure dozens of people will tell me I’m wrong and know nothing, but I’m somewhat experienced in both JS and CSS animations, so bring it on ;).