悬停时显示内容(不影响卡片高度)
P粉289775043
P粉289775043 2024-03-27 20:29:28
0
1
442

我有一个块,其中包含悬停时显示的内容。效果的工作方式应该是:

  • .hoverCard 默认显示基础内容(.hoverCard__showOnHover 中的内容被隐藏) 用户将鼠标悬停在 .hoverCard 上,此时 .hoverCard__showOnHover 显示其内容,并且 .hoverCard__body 向上转换(赋予其“打开”效果)
  • 可以在我的演示中看到上述内容的视觉效果,但我无法让动画完美地工作。

我遇到的问题是:

  • 使用 visibility:hiddenopacity:0height:0 仍然为 .hoverCard__showOnHover 保留空间。这意味着,如果默认情况下,.hoverCard__body 的底部填充量为 40px,而 .hoverCard__showOnHover 的高度为 100px,则无需用户将鼠标悬停在 .hoverCard 上即可看到 140px 的空间
  • 我知道可以防止空间预留的唯一方法是使用 display: none。但是,当我将鼠标悬停在卡片上时,我需要为其提供一个显示属性来展示内容,这会给卡片带来跳跃效果(因为悬停时会引入高度)。除此之外,我的卡片的高度也会增长(我想要内容显示并向上打开的效果,而不是像演示中那样增长 .hoverCard)
  • 为了尝试解决上述问题,我尝试使用 GSAP 逐渐赋予 .hoverCard__showOnHover 高度。但运气不好,因为它仍然存在上述问题

有什么办法可以解决这个问题吗?不一定要使用 GSAP,我只是尝试过 GSAP 来尝试解决上述问题。

const hoverCard = document.querySelector('.hoverCard');
const hoverCardBodyShowOnHover = document.querySelector('.hoverCard__showOnHover');

hoverCard.addEventListener('mouseenter', function() {
  gsap.to(hoverCardBodyShowOnHover, { duration: 0.5, display: 'block', height: 'auto', ease: 'power4.out' });
});

hoverCard.addEventListener('mouseleave', function() {
  gsap.to(hoverCardBodyShowOnHover, { duration: 0.5, height: 0, ease: 'power4.out', onComplete: function() {
    this.targets()[0].style.display = 'none';
  }});
});
:root {
  --black: #000000;
  --white: #ffffff;
  --yellow: #FFE775;
}

/* general */
body {
  font-family: "Poppins", sans-serif;
  background-color: var(--white);
  color: var(--black);
}

section {
  margin: 100px 0 300px 0;
}

/* card */
.hoverCard {
  margin-bottom: 15px;
  width: 100%;
  border-radius: 8px;
  overflow: hidden;
  background-color: var(--black);
  color: var(--white);
  border: 1px solid var(--black);
}
.hoverCard * {
  transition: all 0.5s ease;
}
.hoverCard:hover .hoverCard__body {
  transform: translateY(-75px);
}
.hoverCard:hover .hoverCard__body .hoverCard__showOnHover {
  opacity: 1;
  visibility: visible;
  display: block;
  height: auto;
  transform: translateY(75px);
}
.hoverCard__header {
  height: 350px;
  background-color: var(--yellow);
}
.hoverCard__showOnHover {
  display: none;
  height: 0;
  overflow: hidden;
}
.hoverCard__body {
  width: 100%;
  padding: 30px 30px 40px 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.3/gsap.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css" rel="stylesheet">

<section>
  <div class="container">
    <div class="row">

      <div class="col-12 col-md-6">
        <article class="hoverCard position-relative">
          <div class="hoverCard__header">
            <!-- img here -->
          </div>
          <div class="hoverCard__body">
            <div class="hoverCard__body-text">Subheader</div>
            <div class="hoverCard__showOnHover">
              <p>This will show on hover Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
            </div>
          </div>
        </article>
      </div>

       <div class="col-12 col-md-6">
        <article class="hoverCard position-relative">
          <div class="hoverCard__header">
             <!-- img here -->
           </div>
          <div class="hoverCard__body">
            <div class="hoverCard__body-text">Subheader 2</div>
            <div class="hoverCard__showOnHover">
              <p>This will show on hover</p>
            </div>
          </div>
        </article>
      </div>


      
    </div>
  </div>
</section>

以下是该卡的默认版本的视觉效果(见右卡)以及悬停交互的工作原理(左卡):

注意卡片高度没有增加。相反,主体向上移动(在卡片内)以显示内容。

编辑:

基于 Kooilnc 的回答:

:root {
  --black: #000000;
  --white: #ffffff;
  --yellow: #FFE775;
}

/* general */
body {
  background-color: var(--white);
  color: var(--black);
}

section {
  margin: 100px 0 300px 0;
}

/* card */
.hoverCard {
  margin-bottom: 15px;
  width: 100%;
  border-radius: 8px;
  overflow: hidden;
  background-color: var(--black);
  color: var(--white);
  border: 1px solid var(--black);
  position: relative; /* added */ 
}
.hoverCard * {
  transition: all 0.5s ease;
}
.hoverCard:hover .hoverCard__body {
  transform: translateY(-75px);
}
.hoverCard:hover .hoverCard__body .hoverCard__showOnHover {
  /* opacity: 1;
  visibility: visible;
  display: block;
  height: */ auto;
  overflow: initial; /* added */ 
  height: auto; /* added */ 
  max-height: 100px; /* added */ 
  transform: translateY(75px);
}
.hoverCard__header {
  height: 200px;
  background-color: var(--yellow);
}
.hoverCard__showOnHover {
  overflow: hidden;
  max-height: 0; /* added */ 
  transition: max-height 0.5s ease-in-out; /* added */ 
  overflow: hidden;  /* added */ 
}
.hoverCard__body {
  width: 100%;
  padding: 30px 30px 40px 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.3/gsap.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css" rel="stylesheet">

<section>
  <div class="container">
    <div class="row">

      <div class="col-6">
        <article class="hoverCard position-relative">
          <div class="hoverCard__header">
            <!-- img here -->
          </div>
          <div class="hoverCard__body">
            <div class="hoverCard__body-text">Subheader</div>
            <div class="hoverCard__showOnHover">
              <p>This will show on hover Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
            </div>
          </div>
        </article>
      </div>

       <div class="col-6">
        <article class="hoverCard position-relative">
          <div class="hoverCard__header">
             <!-- img here -->
           </div>
          <div class="hoverCard__body">
            <div class="hoverCard__body-text">Subheader 2</div>
            <div class="hoverCard__showOnHover">
              <p>This will show on hover</p>
            </div>
          </div>
        </article>
      </div>


      
    </div>
  </div>
</section>

另外,我们需要为 max-height: 100px; 定义一个数字吗?如果内容大小未知并且需要动态怎么办?

编辑2

最新方法:

:root{
  --white: #FFFFFF;
  --black: #000000;
  --yellow: #FFE775;
}

section{
  padding: 150px 0;
}

.hoverCard {
  margin-bottom: 15px;
  width: 100%;
  border-radius: 8px;
  overflow: hidden;
  padding-bottom: 180px; // seems I need this to maintain height
  background-color: var(--black);
  color: var(--white);
  border: 1px solid var(--black);
  
  /* only on non touch devices
  ================================== */

  @media (hover: hover) {
    * {
      transition: all 0.5s ease;
    }

    &:hover {
      .hoverCard__body {
        transform: translateY(-75px);
      }
      .hoverCard__showOnHover {
        display: block;
        max-height: none;
        overflow: visible;
      }
    }
  }

  &__showOnHover {
    display: none;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.5s ease-in-out;
  }

  /* only on touch devices
  ================================== */

  @media (pointer: coarse) {
    &__showOnHover {
      margin-bottom: 30px;
    }
  }

  /* =============================== */

  &__header {
    height: 350px;
    background-color: var(--yellow);
  }

  &__body {
    position: absolute;
    bottom: 0;
    width: 100%;
    padding: 30px 30px 0px 30px;
    color: var(--white);
    background-color: var(--black);

    &-text {
      margin-bottom: 60px;
    }

  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.3/gsap.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css" rel="stylesheet">

<section>
  <div class="container">
    <div class="row">

      <div class="col-6">
        <article class="hoverCard position-relative">
          <div class="hoverCard__header">
            <!-- img here -->
          </div>
          <div class="hoverCard__body">
            <div class="hoverCard__body-text">Subheader</div>
            <div class="hoverCard__showOnHover">
              <p>This will show on hover Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
            </div>
          </div>
        </article>
      </div>

       <div class="col-6">
        <article class="hoverCard position-relative">
          <div class="hoverCard__header">
             <!-- img here -->
           </div>
          <div class="hoverCard__body">
            <div class="hoverCard__body-text">Subheader 2</div>
            <div class="hoverCard__showOnHover">
              <p>This will show on hover</p>
            </div>
          </div>
        </article>
      </div>


      
    </div>
  </div>
</section>

通过以上内容:

  • 这会导致 .hoverCard__body 上方出现不必要的空格(应仅填充顶部 30px)。
  • 入口动画跳跃(内容刚刚出现,翻译不流畅)
  • 退出动画高度也快速跳下(因为display none属性生效)

P粉289775043
P粉289775043

全部回复(1)
P粉760675452

技巧是将要显示的文本设置为 max-height: 0 overflow: hide。这是一个最小可重现示例

body {
  margin: 1rem;
  font-family: system-ui, sans-serif;
}

.item {
  position: relative;
  overflow: hidden;
  margin-right: 0.8rem;
  width: 150px;
  float: left;
  border: 1px solid #777;
  border-radius: 3px;
}

.item.first {
  background: url("https://upload.wikimedia.org/wikipedia/commons/d/d0/Queen_Clementia_of_Hungary.jpg") no-repeat top left;
  background-size: cover;
  height: 150px;
}

.collapsible {
  height: inherit;
  width: inherit;
  position: absolute;
  bottom: 0;
}

.collapsible .header {
  background-color: #EEE;
  color: #000;
  text-align: center;
  font-weight: bold;
  font-size: 0.9rem;
  cursor: pointer;
  bottom: 0;
  width: 100%;
  position: absolute;
  opacity: 0.8;
}

.item .collapsible .collapsibleTxt {
  max-height: 0;
  text-align: left;
  font-size: initial;
  color: #444;
  overflow: hidden;
  padding: 4px;
  font-weight: normal;
  transition: max-height 0.5s ease-in-out;
}

.header:hover  .collapsibleTxt {
  overflow: initial;
  height: auto;
  max-height: 100px;
}
Who's that?
It's Clementia of Hungary!
Find out more
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板