简体   繁体   中英

Why doesn't any css transtion work if elemnt is made display block from none?

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:

  1. Why don't transition work when opacity is changed directly with display propert? Why does transtion work when there is some delay between display block and opacity:1?
  2. If I put a delay of 0 seconds even then transition works correctly. why?

  3. 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?

To answer your headline question, not all CSS properties are animatable.

  • display is not animatable
  • opacity is animatable

Further 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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM