懸停時顯示內容(不影響卡片高度)
P粉289775043
P粉289775043 2024-03-27 20:29:28
0
1
450

我有一個區塊,其中包含懸停時顯示的內容。效果的工作方式應該是:

  • .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
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板