'Is there any solution to make this particular animation end to the right from the left (No need to go back) using CSS when hovering out?

.navigation{
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.sideNav{
  list-style: none;
}

.sideNav__item{
  margin-top: 2rem;
  padding: 1rem .8rem;
  background-color: teal;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
}

.sideNav__item::before{
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 0%;
  background-color: tomato;
}

.sideNav__item:hover::before{
  animation: hoverEffect .5s cubic-bezier(.51, .20, .32, 1) 0s normal 1 forwards running;
}

.sideNav__link{
  text-decoration: none;
  font-size: 1.5rem;
  color: #fff;
  z-index: 1;
}

@keyframes hoverEffect {
  from {width: 0;}
  to {width: 100%;}
}
<nav class="navigation">

  <ul class="sideNav">
    <li class="sideNav__item">
      <a href="#" class="sideNav__link">Home</a>
    </li>
    <li class="sideNav__item">
      <a href="#" class="sideNav__link">About</a>
    </li>
  </ul>
 
</nav>

Here I am targeting ::before pseudo-element for the animation. But I need to end the same animation to the right from the left when hovering out.

I did try this with the "transition" property also. But the "transition" is ending to the left from the right where it started (reverse). Actually, I couldn't solve this issue by using CSS. And I need to solve this issue by using only the CSS - not with Js. Is there any solution?



Solution 1:[1]

With the restrictions that you have (not using JS), I found this solution. I'm not sure that it is what you mean, but I put the code to see the result:

.navigation{
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.sideNav{
    list-style: none;
}

.sideNav__item{
    margin-top: 2rem;
    padding: 1rem .8rem;
    background-color: teal;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    overflow: hidden;
    transition: 2s background-color;
}

.sideNav__item::before{
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 0;
    z-index: 5;
    background-color: tomato;
}

.sideNav__item::after{
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 0;
    background-color: teal;
}

.sideNav__item:hover::before {
    animation: hoverEffect .5s cubic-bezier(.51, .20, .32, 1) 0s normal 1 forwards running;
}

.sideNav__item:not(:hover)::after {
    animation: hoverEffect2 .5s cubic-bezier(.51, .20, .32, 1) 0s normal 1 forwards running;
}

.sideNav__item:hover {
    background-color: transparent;
}

.sideNav__link{
    text-decoration: none;
    font-size: 1.5rem;
    color: #fff;
    z-index: 6;
}

@keyframes hoverEffect {
    from {width: 0;}
    to {width: 100%;}
}

@keyframes hoverEffect2 {
    from {width: 0;}
    to {width: 100%;}
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS animation</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>

<nav class="navigation">

    <ul class="sideNav">
        <li class="sideNav__item">
            <a href="#" class="sideNav__link">Home</a>
        </li>
    </ul>

</nav>

</body>
</html>

I have also another method that works smoother, but have a bug that is when the page is loaded for the first time (or at page refresh), it runs the hover animation. I also post the code of that here:

.navigation{
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.sideNav{
    list-style: none;
}

.sideNav__item{
    margin-top: 2rem;
    padding: 1rem .8rem;
    background-color: teal;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    overflow: hidden;
}

.sideNav__item::before{
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 0;
    z-index: 5;
    background-color: tomato;
}

.sideNav__item::after{
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 0;
    background-color: teal;
}

.sideNav__item:hover::before {
    animation: hoverEffect .5s cubic-bezier(.51, .20, .32, 1) 0s normal 1 forwards running;
}

.sideNav__item:not(:hover)::before {
    animation: hoverEffect3 .5s cubic-bezier(.51, .20, .32, 1) 0s normal 1 forwards running;
}

.sideNav__item:not(:hover)::after {
    animation: hoverEffect2 .5s cubic-bezier(.51, .20, .32, 1) 0s normal 1 forwards running;
}


.sideNav__link{
    text-decoration: none;
    font-size: 1.5rem;
    color: #fff;
    z-index: 6;
}

@keyframes hoverEffect {
    from {width: 0;}
    to {width: 100%;}
}

@keyframes hoverEffect2 {
    from {width: 0;}
    to {width: 100%;}
}

@keyframes hoverEffect3 {
    from
    {
        left: 0;
        width: 100%;
    }
    to
    {
        left: 100%;
        width: 100%;
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS animation</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>

<nav class="navigation">

    <ul class="sideNav">
        <li class="sideNav__item">
            <a href="#" class="sideNav__link">Home</a>
        </li>
    </ul>

</nav>

</body>
</html>

Solution 2:[2]

.navigation{
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.sideNav{
  list-style: none;
}

.sideNav__item{
  margin-top: 2rem;
  padding: 1rem .8rem;
  background-color: teal;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
}

.sideNav__item::before, .sideNav__item::after{
  content: "";
  display: block;
  position: absolute;
  top: 0;
  height: 100%;
  width: 0%;
  background-color: tomato; 
}

.sideNav__item::before{
  left: 0;
}

.sideNav__item::after{
  transition: width .5s ease;
  right:0;
}

.sideNav__item:hover::before{
  width: 100%;
  transition: width .5s ease;
}

.sideNav__item:hover::after{
  background-color: transparent;
  width: 100%;
  transition: width .2s .3s;
}

.sideNav__link{
  text-decoration: none;
  font-size: 1.5rem;
  color: #fff;
  z-index: 1;
}
<nav class="navigation">

  <ul class="sideNav">
    <li class="sideNav__item">
      <a href="#" class="sideNav__link">Home</a>
    </li>
    <li class="sideNav__item">
      <a href="#" class="sideNav__link">About</a>
    </li>
  </ul>
 
</nav>

I created a ::after pseudo element. And gave another transition.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Razik