Reputation: 7589
Consider the following scenario:
$(".tab").click(function() {
var position = $(this).index(".tabs .tab");
$(".content > div").removeClass("showing").removeClass("active");
$(".content > div").eq(position).addClass("active");
// active class makes display bock then without any delay opacity is changed by showing class
$(".content > div").eq(position).addClass("showing");
});
.tabs {
float: left;
background: #ccc;
margin-bottom: 10px;
}
.tab {
float: left;
border-right: 2px solid white;
padding: 15px;
}
.content {
float: left;
width: 100%;
}
.content > div {
padding: 15px;
background: #999;
transition: opacity 2s ease-out;
opacity: 0;
display: none;
}
.content > .active {
display: block;
}
.content .showing {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tabs">
<div class="tab1 tab">Tab1</div>
<div class="tab2 tab">Tab2</div>
<div class="tab3 tab">Tab3</div>
</div>
<div class="content">
<div class="content1">
Content 1
</div>
<div class="content2">
content 2
</div>
<div class="content3">
content 3
</div>
</div>
Now when I click on any tab opacity is not transitioned. But if put a little delay between adding active
and showing
classes Then the tabs are transitioned well as:
$(".tab").click(function() {
var position = $(this).index(".tabs .tab");
$(".content > div").removeClass("showing").removeClass("active");
$(".content > div").eq(position).addClass("active").delay(10).queue(function(){
$(".content > div").eq(position).addClass("showing");
});
});
.tabs {
float: left;
background: #ccc;
margin-bottom: 10px;
}
.tab {
float: left;
border-right: 2px solid white;
padding: 15px;
}
.content {
float: left;
width: 100%;
}
.content > div {
padding: 15px;
background: #999;
transition: opacity 2s ease-out;
opacity: 0;
display: none;
}
.content > .active {
display: block;
}
.content .showing {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tabs">
<div class="tab1 tab">Tab1</div>
<div class="tab2 tab">Tab2</div>
<div class="tab3 tab">Tab3</div>
</div>
<div class="content">
<div class="content1">
Content 1
</div>
<div class="content2">
content 2
</div>
<div class="content3">
content 3
</div>
</div>
Now after adding a delay from the point where content is displayed block the transitions work well. My questions are:
If I put a delay of 0 seconds even then transition works correctly. why?
In my second example if I quickly click tabs then the showing
class no longer adds. why? And why does adding dequeue
to $(".content > div").eq(position).addClass("showing");
solve this problem?
Upvotes: 1
Views: 91
Reputation: 29453
To answer your headline question, not all CSS properties are animatable.
display
is not animatableopacity
is animatableFurther Reading:
CSS Animated Properties by Mozilla Developer Network
For the sake of demonstration, here is an example of tabbed content fade-in and fade-out just using the CSS pseudo-class :target
(obviating the need for any scripting in jQuery or javascript):
.tabbed-content {
position: relative;
}
a[class^="tab"] {
display: inline-block;
float: left;
height: 60px;
line-height: 60px;
margin-bottom: 10px;
padding: 0 15px;
color: #000;
background-color: #ccc;
border-right: 2px solid white;
text-decoration: none;
transition: background-color 1s ease-out;
}
div[id^="content"] {
position: absolute;
top: 62px;
left: 0;
width: 100%;
padding: 15px;
text-align: center;
font-size: 72px;
opacity: 0;
box-sizing: border-box;
transition: opacity 2s ease-out;
}
.tab1:hover,
#content1 {
color: rgb(255,255,255);
background-color: rgb(255,0,0);
}
.tab2:hover,
#content2 {
color: rgb(255,255,255);
background-color: rgb(0,127,0);
}
.tab3:hover,
#content3 {
color: rgb(0,0,0);
background-color: rgb(255,255,0);
}
div[id^="content"]:target {
opacity: 1;
}
<div class="tabbed-content">
<a href="#content1" class="tab1">Tab1</a>
<a href="#content2" class="tab2">Tab2</a>
<a href="#content3" class="tab3">Tab3</a>
<div id="content1">
Content 1
</div>
<div id="content2">
Content 2
</div>
<div id="content3">
Content 3
</div>
</div>
Upvotes: 2