Вы можете использовать вставную красную тень, чтобы скрыть ее. Кроме того, в этом случае лучше использовать переход. Переход будет работать, когда вы прекратите зависание элемента, даже в середине анимации.
.button {
margin-top: 50px;
padding: 10px 50px;
border: unset;
border-radius: 5px;
background: linear-gradient(to left, red 0, red 77%, yellow 100%);
background-size: 200%;
color: transparent;
box-shadow: inset 0 0 0 200px transparent;
transition: box-shadow 4s ease-out;
}
.button:hover {
box-shadow: inset 0 0 0 200px red;
}
<button class="button">xxxxxx</button>
И если вы действительно хотите использовать анимацию (проверьте, что произойдет, когда вы прекратите зависание элемента):
.button {
margin-top: 50px;
padding: 10px 50px;
border: unset;
border-radius: 5px;
background: linear-gradient(to left, red 0, red 77%, yellow 100%);
background-size: 200%;
color: transparent;
transition: box-shadow 4s ease-out;
}
button:hover {
animation: ex 4s ease-out;
}
@keyframes ex {
from {
box-shadow: inset 0 0 0 200px transparent;
}
to {
box-shadow: inset 0 0 0 200px red;
}
}
<button class="button">xxxxxx</button>