4

By default, if you stop hovering over an element, the transitioning of any properties will stop as well. Simple example:

li {
  position: relative;
  transition: 1s;
  left: 0;
}

li:hover {
  left: 20px;
}
<ul>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
</ul>

Try running the pointer from the top to the bottom of the list quickly, and the elements will hardly move. I want to achieve the behaviour when transition, once started, will be brought to the end. I'm looking for pure CSS solution.

1
  • 1
    I don't think it is possible to achieve this purely with css, I added an example using a combination with javascript Commented May 31, 2021 at 18:34

3 Answers 3

2

Not sure this can be achieved with css only, I would use Javascript for this and listen when the transition has been completed.

let listItems = document.querySelectorAll('li');

listItems.forEach(listItem=>{
  listItem.addEventListener('mouseover', function() {
    this.classList.add('slide-left');
  });
  
  listItem.addEventListener('transitionend', function() {
    this.classList.remove('slide-left');
  });
})
li {
  position: relative;
  transition: 1s;
  left: 0;
}

li:hover, .slide-left {
  left: 20px;
}
<ul>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
</ul>

1

As stated before, this is not possible with Pure CSS

However here's a hack that requires nesting and doesn't work with multiple siblings and if the mouse moves out of the document.

body {
  overflow: hidden;
}

[ctr] {
  display: inline-block;
}

[box] {
  width: 80px;
  height: 80px;
  background: red;
  position: relative;
  transition: 1s;
  left: 0;
}

[ctr]:hover {
  left: 20px;
  width: 9999px;
  height: 9999px;
  animation: resetctr 1s 1s linear forwards;
}

[ctr]:hover>[box] {
  left: 20px;
  animation: resetbox 1s 1s forwards;
}

@keyframes resetbox {
  from {
    left: 20px;
  }
  to {
    left: 0;
  }
}

@keyframes resetctr {
  to {
    width: auto;
    height: auto;
  }
}
<div ctr>
  <div box></div>
</div>

1

an easy CSS solution is to consider a pseudo element that will cover the whole screen during the transition to allow it to end:

li {
  position: relative;
  transition: 2s;
  left: 0;
}

li:hover {
  left: 20px;
}

li:before {
  content:"";
  position:fixed;
  inset:0 0 100%;
  z-index:999;
}
li:hover:before {
  animation:h 1s;
}

@keyframes h{
  0%,98% {inset:0;}
}
<ul>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
</ul>

1
  • May not be an issue for OP's case, but if the animation uses transforms to move the element you'd need this hack to be moved to a container: jsfiddle.net/gzsh2L46 But one big issue with this solution is that it will still stop when the user stops hovering the page.
    – Kaiido
    Commented Oct 28, 2021 at 1:44

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