Элемент не исчезает полностью при hover transition
Создал меню-навигацию:
.nav-item::before,
.nav-item::after {
content: "";
width: 0;
height: 3px;
background-color: #ff0036;
display: block;
margin: 0 auto;
margin-bottom: 25px;
margin-top: -3px;
transition: width 0.5s ease-out;
}
.nav-item::after {
margin-top: 25px;
margin-bottom: -3px;
}
.nav-item:hover::before,
.nav-item:hover::after {
width: 65%;
}
Моя задача добавить hover эффект при котором будет плавно появляться верхняя и нижняя граница элемента меню. Это я реализовал через псевдо-элементы before и after.
И вроде бы всё работает, но есть одно НО:
Вот так выглядит активный :hover. А вот если водить мышкой туда-сюда, то с разной вероятностью может появиться вот это на месте предыдущего активного элемента:
Маленький пиксель от before и after так и не сжался до width: 0. Почему так и как исправить?
Ответы (2 шт):
Достаточно переписать transition на animation что бы можно было добавить затемнение в конце:
.nav-items .nav-item:hover::before,
.nav-items .nav-item:hover::after {
animation: forw 0.5s ease-out both;
}
.nav-items .nav-item::before,
.nav-items .nav-item::after {
animation: rev 0.5s ease-out both;
}
@keyframes forw {
0% {
width: 0;
}
100% {
width: 65%
}
}
@keyframes rev {
0% {
width: 65%;
}
99% {
opacity: 1;
}
100% {
width: 0;
opacity: 0;
}
}
Не анимируйте свойство width, анимируйте transform.
Когда вы анимируете такие свойства, как, типа: width, height, padding, margin браузер перерисовывают страницу браузера, что весьма затратно
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Roboto', sans-serif;
}
nav {
display: flex;
}
nav > *:not(:last-child) {
margin-right: 10px;
}
nav a {
text-transform: uppercase;
}
a {
color: black;
text-decoration: none;
cursor: pointer;
display: inline-block;
position: relative;
padding: 10px 0;
font-size: 26px;
}
a::before, a::after {
display: block;
content: '';
position: absolute;
top: 0;
width: 100%;
height: 2px;
background-color: red;
transform-origin: left;
transform: scaleX(0);
transition: transform 0.2s linear;
}
a::after {
transform-origin: right;
top: auto;
bottom: 0;
}
a:hover::before, a:hover::after {
transform: scaleX(1);
}
<nav>
<a>Home</a>
<a>Home</a>
<a>Home</a>
</nav>
Пример с вашей реализацией анимации из центра:
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Roboto', sans-serif;
}
nav {
display: flex;
}
nav > *:not(:last-child) {
margin-right: 10px;
}
nav a {
text-transform: uppercase;
}
a {
color: black;
text-decoration: none;
cursor: pointer;
display: inline-block;
position: relative;
padding: 10px 0;
font-size: 26px;
}
a::before, a::after {
display: block;
content: '';
position: absolute;
top: 0;
width: 100%;
height: 2px;
background-color: red;
transform-origin: center;
transform: scaleX(0);
transition: transform 0.2s linear;
}
a::after {
top: auto;
bottom: 0;
}
a:hover::before {
transform: scaleX(0.6);
}
a:hover::after {
transform: scaleX(0.8);
}
<nav>
<a>Home</a>
<a>Home</a>
<a>Home</a>
</nav>

