强制转换以在悬停 CSS 上完成

Force transition to complete on hover CSS

提问人:doliphin 提问时间:11/28/2020 更新时间:11/28/2020 访问量:1397

问:

我创建了一个按钮。当用户将鼠标悬停在它上面时,一个小的红色箭头会在它下面淡入。
转换时间为400ms。当我将鼠标悬停在按钮上不到 400 毫秒时,我希望红色箭头在淡出之前完成其完全过渡。

这个 gif 显示了完整的过渡,然后是不需要的行为。

Behaviour

@import url('https://fonts.googleapis.com/css2?family=M+PLUS+1p&display=swap');

:root {
    --init-bubble-padding: 0px;
    --bubble-padding: 10px;
    --triangle-height: 12px;
    --transition-delay: 0ms;
    --transition-time: 400ms;
}

* {
    font-family: 'M PLUS 1p', Verdana, Geneva, Tahoma, sans-serif;
    z-index: 100;
}


.popup-button-ctr {
    display: inline-block;
    position: relative;
    outline: 0px solid red;
}

.button-ctr button {
    background-color: rgba(30, 30, 30, 1);
    border: none;
    border-radius: 5px;
    outline: 0px solid rgb(90, 90, 90);
    font-weight: 900;
    color: rgb(205, 205, 205);
    padding: 8px 10px 8px 10px;
}

.button-ctr button:hover {
    color: white;
    cursor: pointer;
    background-color: rgba(50, 50, 50, 1);
}

.triangle-up,
.triangle-right,
.triangle-down,
.triangle-left {
    pointer-events: none;
    display: relative;
    position: absolute;
    text-shadow: 1px 1px 10px rgba(21, 36, 63, 0.4);
    z-index: 50;
    color: rgba(255, 0, 0, 1);
    background-color: transparent;

    opacity: 0;
    visibility: hidden;   
    transform: scale(0);
    transition: var(--transition-time) ease-in-out;
    transition-delay: var(--transition-delay);
    transition-property: opacity, visibility, transform, top, right, bottom, left;
}

.popup-posr-up,
.popup-posr-right,
.popup-posr-down,
.popup-posr-left {
    width: 0; height: 0;
    z-index: 150;
    position: absolute;
}

.popup-posr-down {
    left: 50%;
}

.popup-button-ctr .triangle-down {
    transform: rotate(0deg) translateX(-50%);  
    top: var(--init-bubble-padding); 
}
.popup-button-ctr:hover .triangle-down { 
    transform: rotate(0deg) translateX(-50%);
    opacity: 1;
    visibility: visible;   
    transition: var(--transition-time) ease-in-out;
    transition-delay: var(--transition-delay);
    top: var(--bubble-padding);
<div class="popup-button-ctr">

<div class="button-ctr">
    <button>
        <div style="font-size: 30px">
            Emoji Button
        </div>
        This button has emojis 😛 <br />
        Let's ROCK 🤘 🤠 🎸
    </button>
</div>

<div class="popup-posr-down">
    <div class="triangle-down">
        ▲
    </div> 
</div>

</div>

有什么方法可以强制完成转换?

非常感谢 - Oli

html css (英语

评论

2赞 agrm 11/28/2020
据我所知,过渡和动画的问题是一样的——没有办法强制整个动画使用纯 CSS 运行。不过,有一些解决方法。使用 Javascript 向元素添加一个类,以触发 CSS 转换,然后在转换完成后删除该类。查看此答案
2赞 Aleksandar 11/28/2020
不能用纯css完成

答:

0赞 s.kuznetsov 11/28/2020 #1

在我的解决方案中,我建议通过 、 来制作动画。jqueryhover

$('.popup-button-ctr').hover(function(){
    $('.triangle-down').css("transform", "rotate(0deg) translateX(-50%)");
        $('.triangle-down').css('opacity', '1');
        $('.triangle-down').css('visibility', 'visible'); 
        $('.triangle-down').css('transition', '400ms');
        $('.triangle-down').css('transition-delay', '0s');
        $('.triangle-down').css('top', '10px');
 }, function() {
     setTimeout(function() {
$('.triangle-down').css("transform", "rotate() translateX()");
        $('.triangle-down').css('opacity', '');
        $('.triangle-down').css('visibility', ''); 
        $('.triangle-down').css('transition', '');
        $('.triangle-down').css('transition-delay', '');
        $('.triangle-down').css('top', '');
}, 400);
 });
@import url('https://fonts.googleapis.com/css2?family=M+PLUS+1p&display=swap');

:root {
    --init-bubble-padding: 0px;
    --bubble-padding: 10px;
    --triangle-height: 12px;
    --transition-delay: 0ms;
    --transition-time: 400ms;
}

* {
    font-family: 'M PLUS 1p', Verdana, Geneva, Tahoma, sans-serif;
    z-index: 100;
}


.popup-button-ctr {
    display: inline-block;
    position: relative;
    outline: 0px solid red;
}

.button-ctr button {
    background-color: rgba(30, 30, 30, 1);
    border: none;
    border-radius: 5px;
    outline: 0px solid rgb(90, 90, 90);
    font-weight: 900;
    color: rgb(205, 205, 205);
    padding: 8px 10px 8px 10px;
}

.button-ctr button:hover {
    color: white;
    cursor: pointer;
    background-color: rgba(50, 50, 50, 1);
}

.triangle-up,
.triangle-right,
.triangle-down,
.triangle-left {
    pointer-events: none;
    display: relative;
    position: absolute;
    text-shadow: 1px 1px 10px rgba(21, 36, 63, 0.4);
    z-index: 50;
    color: rgba(255, 0, 0, 1);
    background-color: transparent;

    opacity: 0;
    visibility: hidden;   
    transform: scale(0);
    transition: var(--transition-time) ease-in-out;
    transition-delay: var(--transition-delay);
    transition-property: opacity, visibility, transform, top, right, bottom, left;
}

.popup-posr-up,
.popup-posr-right,
.popup-posr-down,
.popup-posr-left {
    width: 0; height: 0;
    z-index: 150;
    position: absolute;
}

.popup-posr-down {
    left: 50%;
}

.popup-button-ctr .triangle-down {
    transform: rotate(0deg) translateX(-50%);  
    top: var(--init-bubble-padding); 
}
/*.popup-button-ctr:hover .triangle-down { 
    transform: rotate(0deg) translateX(-50%);
    opacity: 1;
    visibility: visible;   
    transition: var(--transition-time) ease-in-out;
    transition-delay: var(--transition-delay);
    top: var(--bubble-padding);*/
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="popup-button-ctr">

<div class="button-ctr">
    <button>
        <div style="font-size: 30px">
            Emoji Button
        </div>
        This button has emojis 😛 <br />
        Let's ROCK 🤘 🤠 🎸
    </button>
</div>

<div class="popup-posr-down">
    <div class="triangle-down">
        ▲
    </div> 
</div>

</div>

0赞 Praneet Dixit 11/28/2020 #2

如果您正在寻找一个 vanillajs 解决方案,而不使用任何库,例如 jQuery -

mouseoverEventListeners 用于在悬停时将具有所需 CSS 的类添加到三角形中,并在移除鼠标光标 400 毫秒后删除相同的类,从而留出足够的时间进行过渡。mouseout.visible

document.querySelector('.popup-button-ctr').addEventListener("mouseover", function(){
    document.querySelector('.triangle-down').classList.add("visible");
});


document.querySelector('.popup-button-ctr').addEventListener("mouseout", function(){
    setTimeout(function() {
      document.querySelector('.triangle-down').classList.remove("visible");
    }, 400);
});
@import url('https://fonts.googleapis.com/css2?family=M+PLUS+1p&display=swap');

:root {
    --init-bubble-padding: 0px;
    --bubble-padding: 10px;
    --triangle-height: 12px;
    --transition-delay: 0ms;
    --transition-time: 400ms;
}

* {
    font-family: 'M PLUS 1p', Verdana, Geneva, Tahoma, sans-serif;
    z-index: 100;
}


.popup-button-ctr {
    display: inline-block;
    position: relative;
    outline: 0px solid red;
}

.button-ctr button {
    background-color: rgba(30, 30, 30, 1);
    border: none;
    border-radius: 5px;
    outline: 0px solid rgb(90, 90, 90);
    font-weight: 900;
    color: rgb(205, 205, 205);
    padding: 8px 10px 8px 10px;
}

.button-ctr button:hover {
    color: white;
    cursor: pointer;
    background-color: rgba(50, 50, 50, 1);
}

.triangle-up,
.triangle-right,
.triangle-down,
.triangle-left {
    pointer-events: none;
    display: relative;
    position: absolute;
    text-shadow: 1px 1px 10px rgba(21, 36, 63, 0.4);
    z-index: 50;
    color: rgba(255, 0, 0, 1);
    background-color: transparent;

    opacity: 0;
    visibility: hidden;   
    transform: scale(0);
    transition: var(--transition-time) ease-in-out;
    transition-delay: var(--transition-delay);
    transition-property: opacity, visibility, transform, top, right, bottom, left;
}

.popup-posr-up,
.popup-posr-right,
.popup-posr-down,
.popup-posr-left {
    width: 0; height: 0;
    z-index: 150;
    position: absolute;
}

.popup-posr-down {
    left: 50%;
}

.popup-button-ctr .triangle-down {
    transform: rotate(0deg) translateX(-50%);  
    top: var(--init-bubble-padding); 
}

.visible{
  transform : rotate(0deg) translateX(-50%);
  opacity : 1;
  visibility : visible; 
  transition : 400ms;
  transition-delay : 0s;
  top : 10px;
}
<div class="popup-button-ctr">
    <div class="button-ctr">
        <button>
            <div style="font-size: 30px">
                Emoji Button
            </div>
            This button has emojis 😛 <br />
            Let's ROCK 🤘 🤠 🎸
        </button>
    </div>

    <div class="popup-posr-down">
        <div class="triangle-down">
            ▲
        </div> 
    </div>
</div>

4赞 Temani Afif 11/28/2020 #3

通过添加以下代码来提供仅限 CSS 的解决方案:

.popup-button-ctr:hover::before {
  content:"";
  position:fixed;
  top:0;
  left:0;
  right:0;
  bottom:0;
  animation:h calc(var(--transition-time) + var(--transition-delay)) forwards;
}
@keyframes h {
  99.9% {bottom:0;}
  100% {bottom:100%}
}

这将增加整个屏幕的可悬停区域,以确保您将保持悬停效果直到过渡结束。

@import url('https://fonts.googleapis.com/css2?family=M+PLUS+1p&display=swap');
:root {
  --init-bubble-padding: 0px;
  --bubble-padding: 10px;
  --triangle-height: 12px;
  --transition-delay: 0ms;
  --transition-time: 400ms;
}

* {
  font-family: 'M PLUS 1p', Verdana, Geneva, Tahoma, sans-serif;
  z-index: 100;
}

.popup-button-ctr {
  display: inline-block;
  position: relative;
  outline: 0px solid red;
}

.button-ctr button {
  background-color: rgba(30, 30, 30, 1);
  border: none;
  border-radius: 5px;
  outline: 0px solid rgb(90, 90, 90);
  font-weight: 900;
  color: rgb(205, 205, 205);
  padding: 8px 10px 8px 10px;
}

.button-ctr button:hover {
  color: white;
  cursor: pointer;
  background-color: rgba(50, 50, 50, 1);
}

.triangle-up,
.triangle-right,
.triangle-down,
.triangle-left {
  pointer-events: none;
  display: relative;
  position: absolute;
  text-shadow: 1px 1px 10px rgba(21, 36, 63, 0.4);
  z-index: 50;
  color: rgba(255, 0, 0, 1);
  background-color: transparent;
  opacity: 0;
  visibility: hidden;
  transform: scale(0);
  transition: var(--transition-time) ease-in-out;
  transition-delay: var(--transition-delay);
  transition-property: opacity, visibility, transform, top, right, bottom, left;
}

.popup-posr-up,
.popup-posr-right,
.popup-posr-down,
.popup-posr-left {
  width: 0;
  height: 0;
  z-index: 150;
  position: absolute;
}

.popup-posr-down {
  left: 50%;
}

.popup-button-ctr .triangle-down {
  transform: rotate(0deg) translateX(-50%);
  top: var(--init-bubble-padding);
}

.popup-button-ctr:hover .triangle-down {
  transform: rotate(0deg) translateX(-50%);
  opacity: 1;
  visibility: visible;
  transition: var(--transition-time) ease-in-out;
  transition-delay: var(--transition-delay);
  top: var(--bubble-padding);
}

.popup-button-ctr:hover::before {
  content:"";
  position:fixed;
  top:0;
  left:0;
  right:0;
  bottom:0;
  animation:h calc(var(--transition-time) + var(--transition-delay)) forwards;
}
@keyframes h {
  99.9% {bottom:0;}
  100% {bottom:100%}
}
<div class="popup-button-ctr">

  <div class="button-ctr">
    <button>
        <div style="font-size: 30px">
            Emoji Button
        </div>
        This button has emojis 😛 <br />
        Let's ROCK 🤘 🤠 🎸
    </button>
  </div>

  <div class="popup-posr-down">
    <div class="triangle-down">
      ▲
    </div>
  </div>

</div>