首页 > 解决方案 > 强制过渡以完成悬停 CSS

问题描述

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

这个 gif 显示了完整的过渡,然后是不受欢迎的行为。

行为

@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>

有没有办法强制过渡完成?

非常感谢 - 奥利

标签: htmlcss

解决方案


通过添加以下代码的纯 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>


推荐阅读