CSS Hax: Doing transitions with Display: None;

I want to preface this post and say I have’t quite figured out the “perfect” solution to this yet but I thought I would share what I have learned so far from my experimentation.

Initially, I thought the problem would be a “quick fix” (but then I am always reminded there isn’t such a thing”). I have tabs in on my personal site that show difference information based on what tab is clicked. I wanted the tabs to transition in rather than just display by adding an active class through css. So naturally, I decided to use CSS transitions via jQuery .addClass. Quick and easy right?

Nope. 😦

It turns out you can’t put a transition on display. So after some stack overflow searching, people recommended that I play around with the opacity and height. First you reduce the opacity to 0 and then you change the height to 0. This does work but then you have a different problem. Even with height 0, you get a tiny bit of white space. This isn’t too much of a problem with one tab and most people would never notice. However when you have more, the white space get progressively larger. However, display none would solve this problem yet you can’t do a transition on it.

My current solution?

Info Tab
.info {
clear: both;
height: auto;
padding: 0 8px;
overflow: hidden;
display: block;
border: 1px solid #EEEEEE;
-webkit-border-radius: 0px 7px 7px 7px;
-moz-border-radius: 0px 7px 7px 7px;
-khtml-border-radius: 0px 7px 7px 7px;
border-radius: 0px 7px 7px 7px;
-webkit-box-shadow: 0px 2px 2px #DDDDDD;
-moz-box-shadow: 0px 2px 2px #DDDDDD;
box-shadow: 0px 2px 2px #DDDDDD;
background: #FFF;
height: auto;
padding: 8px;
}

Display None Class
.hidden{
display: none
}

Opacity 0 Class
.vis_hidden {
opacity: 0;
-webkit-transition: opacity, 0.01s linear;
-moz-transition: opacity, 0.01s linear;
-o-transition: opacity, 0.01s linear;
-ms-transition: opacity, 0.01s linear;
transition: opacity, 0.01s linear;
}

Opacity 1 Class
.active{
opacity: 1;
-webkit-transition: opacity, 0.7s linear .3s;
-moz-transition: opacity, 0.7s linear .3s;
-o-transition: opacity, 0.7s linear .3s;
-ms-transition: opacity, 0.7s linear .3s;
transition: opacity, 0.7s linear .3s;
}

JavaScript Logic


////////////////////
//JavaScript Logic//
////////////////////
$('.project_btn').each(function(index) {
$(this).on('click', function(){
$(this).addClass('selected')
$('.project_btn').not(this).removeClass('selected')
var tab = ($('.project.info').eq(index))
var otherTabs = ($('.project.info').not(tab))
console.log(index)
if (otherTabs.hasClass('active')){
otherTabs.removeClass('active');
otherTabs.addClass('vis_hidden');
setTimeout(function(){
otherTabs.addClass('hidden');
},20)
}
if (tab.hasClass('hidden')){
tab.removeClass('hidden');
setTimeout(function(){
tab.removeClass('vis_hidden')
tab.addClass('active')
}, 50)
}
//Closes active tab
else{
// tab.addClass('vis_hidden');
// tab.removeClass('active');
// tab.one('transitionend',function(event){
// tab.addClass('hidden');
// });
}
});
});

This essentially added delays on Display:None for the divs I want to hide so that it is able to transition first. The only problem I am having now is trying to keep the page from “jumping” for a split second as the other elements on the page fill the space the div once had only to then move back down once the new div is added.

I am thinking that if I can keep a div there to keep the space occupied or add a container div I can solve the problem. Has anyone else encountered this problem? How did you approach it?

Leave a comment