悬停时强制结束 CSS 过渡
Force end CSS transition on hover
默认情况下,如果您停止将鼠标悬停在某个元素上,则所有属性的转换也会停止。简单示例:
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>
尝试运行指针从列表的顶部快速指向底部,元素几乎不会移动。我想实现过渡时的行为,一旦开始,就会结束。我正在寻找纯粹的 CSS 解决方案。
不确定这是否可以仅通过 css
实现,我会为此使用 Javascript
并在转换完成后收听。
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>
如前所述,纯 CSS
无法做到这一点
但是这里有一个 hack 需要嵌套并且不适用于多个兄弟姐妹并且如果鼠标移出文档。
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>
一个简单的 CSS 解决方案是考虑一个伪元素,该元素将在过渡期间覆盖整个屏幕以允许它结束:
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>
默认情况下,如果您停止将鼠标悬停在某个元素上,则所有属性的转换也会停止。简单示例:
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>
尝试运行指针从列表的顶部快速指向底部,元素几乎不会移动。我想实现过渡时的行为,一旦开始,就会结束。我正在寻找纯粹的 CSS 解决方案。
不确定这是否可以仅通过 css
实现,我会为此使用 Javascript
并在转换完成后收听。
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>
如前所述,纯 CSS
无法做到这一点但是这里有一个 hack 需要嵌套并且不适用于多个兄弟姐妹并且如果鼠标移出文档。
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>
一个简单的 CSS 解决方案是考虑一个伪元素,该元素将在过渡期间覆盖整个屏幕以允许它结束:
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>