Trigger CSS transition on appended element
The cause of not animating the newly added element is batching reflows by browsers.
When element is added, reflow is needed. The same applies to adding the class. However when you do both in single javascript round, browser takes its chance to optimize out the first one. In that case, there is only single (initial and final at the same time) style value, so no transition is going to happen.
The setTimeout
trick works, because it delays the class addition to another javascript round, so there are two values present to the rendering engine, that needs to be calculated, as there is point in time, when the first one is presented to the user.
There is another exception of the batching rule. Browser need to calculate the immediate value, if you are trying to access it. One of these values is offsetWidth
. When you are accessing it, the reflow is triggered. Another one is done separately during the actual display. Again, we have two different style values, so we can interpolate them in time.
This is really one of very few occasion, when this behaviour is desirable. Most of the time accessing the reflow-causing properties in between DOM modifications can cause serious slowdown.
The preferred solution may vary from person to person, but for me, the access of offsetWidth
(or getComputedStyle()
) is the best. There are cases, when setTimeout
is fired without styles recalculation in between. This is rare case, mostly on loaded sites, but it happens. Then you won't get your animation. By accessing any calculated style, you are forcing the browser to actually calculate it.
css transitions on new elements
requestAnimationFrame()
(https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame) appears to work across Firefox, Chrome and Safari. A more reliable, logical solution that setTimeout()
. For older browsers (IE8), it will require a Polyfill (naturally, the transition won't occur, but the CSS will still change).
CSS-transition on elements added dynamically via JavaScript
CSS3 transition-delay event will be fired for elements after being live.
Here you have set height to 0 but still "li" element is not in DOM(so its not live).
so after assigining height to 0px make it live.
ie
document.body.appendChild(dynamic_gallery)
The "li" is live now,and transition-duration:.4s event has been registered.
Now increase the height to 400px by assigning the class,
dynamic_gallery.className += " gallery-exp";
You will see smooth animation.
EDIT:Most browser needs time to make element live so we need a timeout of 0 seconds to make it work.
hence it should be
setTimeout(function(){
dyna_gallery.className += " gallery-exp";},0)
instead of
dyna_gallery.className += " gallery-exp";
Fiddle: http://jsfiddle.net/zYLmw/
css transitions pushing elements
If you want the border to grow, you can trick it by using css3 box-shadow
with blur set to 0 instead of using border
, because shadow does not cause the element itself to grow.
li:hover{
background-color:red;
box-shadow: 10px 10px 0 10px black;
border-bottom-right-radius:10px;
border-top-left-radius:10px;
}
(Note that it is probably a hack and not the most correct way to solve your problem. It sort of works though.)
Vertical space between items can be achieved by setting display
to inline-block
and setting margin-bottom
:
li{
display:inline-block;
margin-bottom:2em;
transition: all 2s;
position:relative;
margin-right:3em;
padding-top:10px;
padding-right:30px;
padding-left:4px;
}
updated jsFiddle
Smoother CSS transitions on element
You can create a list with keyframes by javascript and creates a new animation based on the list. In this way you will avoid setInterval and the browser will animate your element by himself.
If you want even more smoother movement you should use less random values and provide keyframe list with smother positions.
function getRandomInteger(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
const range = 200;
const steps = 50;
const keyframes = Array.apply(null, Array(50)).map(() => {
return {
transform: `translate(${getRandomInteger(-range, range)}%, ${getRandomInteger(-range, range)}%)`
};
});
document.querySelector('.dot').animate(keyframes, {
duration: steps * 500, // 0.5 sec for keyframe
direction: 'alternate',
fill: 'both',
iterations: Infinity
});
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
overflow: hidden;
height: 100%;
}
body {
display: flex;
justify-content: center;
align-items: center;
background-color: #eee;
}
.dot {
border-style: none;
border-radius: 50%;
width: 2.5rem;
height: 2.5rem;
background-color: rgba( 0, 0, 0, 0.5);
}
<hr class='dot'>
CSS Transition apply to Elements being pushed
It can't transition from an undefined starting point.
You must either
Specify an initial height on your .search-wrapper
http://jsfiddle.net/5h69j6uq/
Or, if your content must be dynamically sized, set the updated height by using the min-height: 100px
property rather than the height: 100px
property. min-height
has a default value of 0 and will thus transition from that defined default value to 100px
http://jsfiddle.net/8t1beeLo/
Related Topics
Performance of CSS Transitions VS. Js Animation Packages
Using JavaScript to Edit CSS Gradient
How to Import Variables from JavaScript to SASS or Vice Versa
Get Element's Custom CSS Properties (-Mystyle) Using JavaScript
Detect CSS Transitions Using JavaScript (And Without Modernizr)
Access CSS File Contents via JavaScript
Get the Size of a CSS Background Image Using JavaScript
How to Check If CSS Value Is Supported by the Browser
Google Maps Not Rendering Completely on Page
Override Styles in a Shadow-Root Element
Setting Minimum Size Limit for a Window Minimization of Browser
Change Background Image in Body
CSS Selector for Targeting Only Immediate Children and Not Other Identical Descendants
How to Determine If ::Before Is Applied to an Element