3

I am trying to create a sort of loading animation, with 3 bars that are below eachother that all have seperate keyframes.

The 3 bars are div elements, located inside a parent div.

<div id="menu">
    <div id="menubox1"></div>
    <div id="menubox2"></div>
    <div id="menubox3"></div>
</div>

The animation properties are assigned to the individual menubox ids.

#menubox1:after {
    content: '';
    position: absolute;
    bottom: 0px;
    transform: translateY(-50%);
    border-top: 1px solid #FFDADA;

    animation: menukeyframes1;
    animation-duration: 2000ms;
    animation-iteration-count: infinite;
    animation-timing-function: ease-in-out;
    animation-play-state: inherit;
}

@keyframes menukeyframes1 {
     0% { width: 100%; left:0;}
     ...
}

My goal is to play the animation while the cursor is hovering over the parent div.

My attempt was to play around with animation-play-state which was set to running or paused, depending if the parent div was hovered.

The problem is that the animation is immediatly paused, before the animation is complete, which looks kind of bad if it stops mid-motion.

Is there a good fix for this, preferrably without JavaScript/jQuery, and across all browsers?

7
  • I don't think so. I'm assuming this is the abrupt ending you don't want? codepen.io/mcoker/pen/vZBXgY Sounds like you want to trigger paused using the animationend event in the browser, which requires js. Commented Jun 1, 2017 at 14:11
  • @MichaelCoker This is exactly what I currently have. What would be the easiest and cleanest way to achieve my goal with js though?
    – dwycxt
    Commented Jun 1, 2017 at 14:15
  • 2
    jsfiddle.net/sSYYE/55. This is a slightly updated version from this answer stackoverflow.com/questions/7694323/…. Commented Jun 1, 2017 at 14:23
  • @WizardCoder Thats looking good! Does it require me switching my bars from ids to classes or is there another way?
    – dwycxt
    Commented Jun 1, 2017 at 14:26
  • jsfiddle.net/sSYYE/56 I have updated the fiddle to make it more relevant to your code. Commented Jun 1, 2017 at 14:29

2 Answers 2

1

As you see it can't be done with just CSS at this moment, and as good jquery answers are already referenced, it's worth to mention that it could be solved in few lines of vanillaJS:

var dur = 2000;
document.querySelectorAll('.smooth').forEach(el=>{
  var t;
  el.addEventListener('mouseover',_=>{t = performance.now();el.style.animationPlayState = 'running'})
  el.addEventListener('mouseout',_=>window.setTimeout(()=>el.style.animationPlayState = 'paused',dur-(performance.now()-t)%dur));
})

working pen

non-es6: BABEL

3
  • Is there anything special about your code? It throws me some errors, such as esversion 6 is needed for => arrow or _ is not defined.
    – dwycxt
    Commented Jun 1, 2017 at 15:14
  • It's es6, if you can't use it it's easy to transpile, even online: BABEL Commented Jun 1, 2017 at 15:22
  • Plus 1 for using vanilla js. Very fancy. Commented Jun 1, 2017 at 15:59
0

You can always fade out the animated divs using transitions. Something like this might work for you:

#menubox1 {
  opacity: 0;
  transition: opacity .5s linear;
}

#menu:hover {
  #menubox1 {
    opacity: 1;
    transition: opacity .5s linear;
  }
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.