search

Home  >  Q&A  >  body text

Show content on hover (does not affect card height)

I have a block that contains content that displays on hover. The way the effect should work is:

The problem I encountered is:

Is there any way to solve this problem? Not necessarily using GSAP, I just tried GSAP to try to solve the above problem.

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>

Here’s what the default version of the card looks like visually (shown on the right card) and how the hover interaction works (left card):

Note that the height of the card does not increase. Instead, the body moves up (within the card) to reveal the content.

edit:

Based on Kooilnc’s answer:

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

Also, do we need to define a number for max-height: 100px;? What if the content size is unknown and needs to be dynamic?

Edit 2

Latest method:

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

Pass the above content:

P粉289775043P粉289775043272 days ago456

reply all(1)I'll reply

  • P粉760675452

    P粉7606754522024-03-28 11:47:55

    The

    trick is to set the text to be displayed to max-height: 0 and overflow: hide. This is a minimal reproducible example.

    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

    reply
    0
  • Cancelreply