CSS transition to initially hidden element

I would like to make a css transition to an element that has display: none . Consider the following code:

 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>CSS Transition From Hidden</title> <style type="text/css"> div { -webkit-transition-property: all; -webkit-transition-duration: 2s; } div.hidden { display: none; opacity: 0; } div.from { opacity: 0; } </style> <script type="text/javascript"> function loaded() { var e = document.getElementById("foo"); e.className = "from"; window.webkitRequestAnimationFrame(function(t) { e.className = null; }); } </script> </head> <body onload="loaded()"> <div id="foo" class="hidden"> My test div </div> </body> </html> 

I would like to switch from class="div.hidden" to class="" , that is, from display: none; opacity: 0; display: none; opacity: 0; before display: block; opacity: 1; display: block; opacity: 1; However, in chrome (at least), an object that has display: none is not animated. The element immediately goes to its final state.

My job for this is to first set the element to display: block; opacity: 0; display: block; opacity: 0; and then do the transition in the next frame (using requestAnimationFrame() . It's awkward and I can't find an explanation of this behavior in spec . I know that I could use the visibility attribute, but I don't want to use it because I don't want to put a hidden element.

So the questions are: is this the correct behavior or error? If this is the correct behavior, is there a better way to write code? Please note that I am not asking if there are any libraries that can do this, I want to know if there is a better way to do this directly in the DOM.

+4
source share
6 answers

Regarding the question of whether there is a specification, there is an interesting stream in the list of www-style@w3.org here . I have not read all of this, but it seems that they do not start the animation from none and that the transition specification should also clarify this.

Update . I asked the mailing list, and I got this link to the minutes of the working group meeting where it was decided that the transition should not occur if the initial state is display: none .

To ensure that the transition is complete, you must ensure that the value of the animated property is calculated before it is set to its new target. Values ​​are generally not calculated if the display is set to none. Here is a working example:

 <!DOCTYPE HTML> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>Fade</title> <style> .hidden { display: none } .start { opacity: 0 } .transition { opacity: 1; -webkit-transition: opacity 1s } </style> </head> <body> <div id='div' class="hidden">Test</div> <script> var elem = document.getElementById('div'); function ontransitionend(event) { elem.className = null; elem.removeEventListener('transitionend', ontransitionend); } elem.addEventListener('transitionend', ontransitionend); elem.className = 'start'; window.getComputedStyle(elem).opacity; elem.className = 'transition'; </script> </body> </html> 

Note that you need to access the opacity property. It is not enough to call getComputedStyle() !

+7
source

You do not have to relay transitionend callbacks.
To show with the transition to the opacity property (or others) a hidden element that initially has display:none , just use the built-in style to set display:block , then delete your CSS .hidden class to animate the element as you wish:

CSS

 #foo { display: none; opacity: 1; /*optional, other ending properties...*/ transition: opacity 1s; } .hidden { opacity: 0; /*optional, other starting properties...*/ } 

HTML:

 <div id="foo" class="hidden"> My test div </div> 

finally, the javascript part to show the element with the transition:

 var elem = document.getElementById('foo'); elem.style.display = 'block'; elem.classList.remove('hidden'); 
+2
source

There are several css properties that cannot be increased in small steps (what is the display value of 25% of the path between none and block ?), Especially those that have non-numeric values. The workaround you describe is pretty much the standard way to deal with this. For example, jQuery uses something similar in its fadeIn and fadeOut .

If you want to animate the transition from the occupied space to the standard layout, you can go to the height and width properties.

+1
source

Display: no one means you can reach an element, but first you need to make sure that the element has been rendered. you can use a ready-made function in jquery or implement it in javascript to make sure the element exists. you can do this using: javascript (use a timer to increase opacity) or jquery as shown below

 <html> <head> <meta charset="utf-8"> <title>CSS Transition From Hidden</title> <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script> <script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script> <style type="text/css"> div.hidden { display: none; opacity: 0; } </style> <script type="text/javascript"> $.ready = function () { $("#foo").fadeIn(2000); } </script> </head> <body> <div id="foo" class="hidden"> My test div </div> </body> </html> 
+1
source

I have the same problem and I don't think this should be considered acceptable browser behavior. The problem is not that someone is trying to animate the actual display property. This means that you cannot have an element with the display: none, update the property to a string or any other, and then activate the opacity, for example, even if you set a timeout within 10 seconds after updating the display.

My workaround now sets width and height to 0, overflows into hidden ones, updates these values, and THEN updates animation attributes. At least it behaves more like a display without hiding visibility.

+1
source

display: none activate animation. This is a shame, and I think it should be considered by browsers. I ran into a problem before setting z-index to -1, which hides the element, and if it is absolutely positioned, it also removes it from the static layout. In fact, you can switch to z-index (although in reality it does not look like an animation), therefore, it will not ruin the opacity animation.

This worked for me in my application, although I eventually had to use JavaScript to continue, and set the display property from none to block, because I ended up having to use the fading element in the overflow: auto element, which when it there were nn hidden, created scrollbars at undesirable times.

0
source

Source: https://habr.com/ru/post/1446909/


All Articles