I have an element that will show some animation upon initial page load. After that, the element should be hidden and never show again.
This element is wrapped inside a parent container. Some user interactions may hide the parent container (display:none or hidden attribute). Every time after the parent container is re-shown, the element is animated again, which I would like to prevent. Why is the element re-animated every time it is re-shown? Any CSS rule to disable this behavior?
Here is an example. Once you hover over the link and hover out, the element is animated again.
Is it possible to prevent it through pure CSS, not involving any Javascript? How?
If the goal is for the animated element to basically be gone and not overlap anything after the animation is complete, you can take out the forwards state of your animation, and make the inherent height of your .block element 0px. Then set the 0% and 100% keyframes to the height you want (100px), and after the animation is done the block will be gone, for all intents and purposes, having a height of 0 and no clickable area.
#keyframes drop {
0% {
transform: translateY(-150%);
opacity: 0;
height: 100px;
}
15% {
transform: translateY(10%);
}
20% {
transform: translateY(-10%);
}
25% {
transform: translateY(0);
opacity: 1;
}
100% {
transform: translateY(1);
opacity: 1;
height: 100px;
}
}
.block{
width:100px;height:0px;background:black;
animation: 1.3s 2 alternate drop;
}
Related
I have a div that has 2 buttons. If a button is pressed, I want to slide that div off screen to the left, fading out. Once off screen and hidden, update the content of the div, then move the div to the other side of the screen and slide if back in from the right.
I've tried to achieve this by detecting when a button is pressed, then updating the classes on the div to trigger a transition:
.exit-active {
transform: translateX(-200%);
opacity: 0;
transition: transform .5s ease-in,opacity .25s linear;
}
I then tried to use something like this to wait for this to finish before translating the div on the X axis by 400%:
$('.exit-active').on('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', function() { //do something });
And then in the do something bit, I'd update the content in the div, and then I was trying to remove my exit-active class, and update it with an entry-active class which would transition the div back into view from the right, fading back in.
I can get the first part working by sliding the div out to the left, fading out, and updating the content of the div, but I can't figure out how to shift the div whilst opacity is set to 0 over to the right of the screen and bring it back in with a similar effect. Any help would be appreciated.
One thing I have noted is that I can't seem to nest the js above inside a similar statement e.g. whilst waiting for a transition to complete, trigger another and wait for that one to complete too.
You could achieve this using setTimeouts and changing your classes within your timeouts. Just make sure the timeouts are set in a way that the intervals accommodate the transition duration/s of your transforms.
On the click, move the element off the screen, then run your first timeout. Within the timeout, change the class and textContent of your event target. The class will set opacity to 0 and move the element past the right fold of the screen. Then in the next timeout, set a new class, keeping the other class present so the transform will set when you bring it back to translateX(0). We run two transitions, one for opacity and the other for transform.
const click = document.querySelectorAll('.click')
function moveEl(e){
e.target.classList.add('move')
setTimeout(()=>{
e.target.classList.remove('move')
e.target.classList.add('right')
e.target.textContent = 'I have been clicked!'
}, 1000)
setTimeout(()=>{
e.target.classList.add('left')
}, 2000)
}
click.forEach(clicks => {
clicks.addEventListener('click', moveEl)
})
body {
overflow-x: hidden;
}
.click {
height: 90vh;
display: flex;
align-items: center;
justify-content: start;
}
.move {
transform: translateX(-400px);
transition: transform .5s ease-in-out;
}
.right {
opacity: 0;
transform: translateX(100vw);
transition: transform 1s ease-in-out;
align-items: center;
}
.left {
opacity: 1;
transform: translateX(0);
transition:
transform .5s ease-in-out,
opacity .5s linear;
display: flex;
align-items: center;
}
<div class="click">Click me</div>
So I have got a list of <div> elements.
I use JavaScript to change the contents of this list by inserting or removing elements according to filters, put in by users.
When inserting/creating a new <div> element, I use #keyframe animations to change the opacity from zero to one and give a little fade in from the left.
#keyframes fade-in-left {
0% {
opacity: 0;
transform: translateX(-20px);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
Everything is working perfectly fine but there is one crucial design problem:
What I want now, is a scale up animation. I can easily do that but the problem is that when inserting a new element, the elements in the list after it snap to the position at which they would be when the inserted <div> has completed scaling to 1.
The problem here is obviously the following: Changing the scale of a transform does not affect the positioning of the other elements. I would have to change the height. But I cannot do that, there is padding, margin etc.
So can anyone please tell me a solution to this problem? Thank you.
Various elements of the webpage have a background transition on them changing from color to color:
#-moz-keyframes backgroundTransition /* Firefox */ {
0% {background-color:#ff7b7b;}
33% {background-color:#7fceff;}
66% {background-color:#80e880;}
100% {background-color:#ff7b7b;}
}
#-webkit-keyframes backgroundTransition /* Safari and Chrome */{
0% {background-color:#ff7b7b;}
33% {background-color:#7fceff;}
66% {background-color:#80e880;}
100% {background-color:#ff7b7b;}
}
However, if an element is display: none and then displayed later through javascript, the color isn't consistent with the other elements, it starts the loop from the 0% color.
Is there a way to keep the transition universal? Thank you for your time.
Have you tried hiding the elements by making their opacity:0 and then setting it to 1 to unhide them? That should allow the background color to transition with all the other elements, but keep the element invisible.
Byh the way, the keyframes CSS directive is well supported by all major browsers at this point. There is no longer a need to use vendor prefixes with it.
document.querySelector("button").addEventListener("click", function(){
document.querySelector(".hidden").classList.remove("hidden");
});
div {
width:50px;
height:50px;
background-color:black;
border:1px solid black;
animation-duration: 8s;
animation-name: backgroundTransition;
}
/* The hidden elements will not take up space in the
normal document flow and will not be visible because
the will be 100% transparent. Simply removing this
class when its time to see the element(s) puts them
back into the normal flow and their background will
be the same as all the other div elements. */
.hidden { opacity:0; position:absolute; }
#keyframes backgroundTransition{
0% {background-color:#ff7b7b;}
33% {background-color:#7fceff;}
66% {background-color:#80e880;}
100% {background-color:#ff7b7b;}
}
<div></div>
<div class="hidden"></div>
<div></div>
<button>Click me during the animation to reveal the hidden div,<br>which will have its color in sync with the other div elements</button>
I don't think you can handle it using visibility css attribute or you cant cuz whenever it gets rendered it will start from 0
Transitions didn't work for element not rendered by browser, but work's for element 'hided' ;) try antoher option to hide your element:
opacity: 0
height:0; width:0;
z-index: <val>
I'm actually expecting the answer to this to be a simple and straight "NO", but I have to ask, maybe someone even already did a dirty workaround.
I made a character using CSS3 only and added an animation that slowly shakes his head. This can be seen as the idle animation. Now I added a specific talk animation (actually seperate, it's aplied to a different <div>) where he holds still and one where he shakes his head strongly. I apply the class .shakehead to the wrapper element via JavaScript at certain events.
#keyframes head-swing {
0% {
transform: rotate(-2deg);
}
50% {
transform: rotate(2deg);
}
100% {
transform: rotate(-2deg);
}
}
.head {
animation: head-swing 7s infinite ease-in-out;
}
.shake .head {
animation: head-swing 1s infinite ease-in-out;
}
Now, when I simply suddenly apply the class to the wrapper, the probability of changing in the middle of the animation and creating an ugly break is pretty high, so the best thing to do would be crossfading both animations. I want to avoid to wait for the animation end via JS, because seven seconds is a little much to wait for.
(my usecase)
If you don't know what I mean, watch this Unity3D tutorial for a minute.
Is such a crossfade in any way possible? (Probably NO)
A crossfade is possible with the opacity poperty. You can use multiple poperties in the same keyframe animation (and I'm pretty surprised that a lot of people don't know that), so don't be afraid to write height changes with of you opacity changes!.
You should also put your "moving mouth" into the same div than you first, at the exact same position and do your crossfade a bit like this.
#keyframes crossfade1 { /*applied on the "first" mouth (still)*/
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#keyframes crossfade2 { /*applied on the "second" mouth (moving) [the height is an exemple]*/
0% {
opacity: 0;
height: 3px /*the mouth is closed*/
}
50% {
opacity: 1;
height: 20px /*the mouth is open*/
}
100% {
opacity: 0;
height: 20px /*the mouth is closed*/
}
}
Put the duration as the same for the two keyframe animation and voilĂ ! You have your perfect crossfade without even using javascript!
What do you think?
I'm developing an cordova app with 3 "pages". The "pages" are divs with a fixed height and the with of 100%. (see div1, div2, div3 in the picture)
I'm currently using jquery show and hide functions with a slide but the performance on mobile phones is very bad. So I thought of using css, I cant get an idea of how to make is so you can swipe the current visible div to sort of snap the next div in place.
Maybe this picture wil clear my story up: picture
I hope someone can push me in the right direction css and javascript wise..
You should still use jQuery Mobile to detect swipe left/right events on each div, but instead of animating div's position, you should add/remove class for the previous/active/next DIV. Classes should look something like this:
.container {
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 100vh;
transition: all 0.6s cubic-bezier(0.250, 0.460, 0.450, 0.940); // this will add nice inertia effect upon switching DIVs
}
.container.previous {
transform: translateX(-100%);
}
.container.active {
transform: translateX(0%);
}
.container.next {
transform: translateX(-100%);
}