skip to Main Content

i have a problem, when i hover on .wrapper__shopcart element its child element .wrapper__shopcart-modal will show up with animation:

@keyframes Growth{
     from{
           transform: scale(0);
           opacity: 0;
     }
     to {
           transform: scale(1);
           opacity: 1;
     }
}

and when the hover is over i want it to disappear with the animation:

@keyframes Shrink{
     from {
          transform: scale(1);
          opacity: 1;
     }
     to {
          transform: scale(0);
          opacity: 0;
     }
}

but I don’t know how.
I wish an efficient css method for this problem

2

Answers


  1. If you want this to happen on hover you need to use a transition, not a keyframe animation. See the below example.

    Also keep in mind that when it shrinks down to scale(0) that you really cannot "hover" over nothing any more so that animations might look odd if you move your mouse around.

    #container {
      display: flex;
    }
    
    .grow-shrink {
      background: #EEE;
      border: 1px solid lightblue;
      padding: 10px 15px;
      
      opacity: 1;
      transform: scale(1);
      
      /*Tell this element which properties to animate if something changes
      We are saying all properties will animate when changed for 0.3 seconds*/
      transition: all 0.3s;
    }
    
    .grow-shrink:hover {
      transform: scale(0);
      opacity: 0;
    }
    <div id="container">
      <div class="grow-shrink">one</div>
      <div class="grow-shrink">two</div>
      <div class="grow-shrink">three</div>
      <div class="grow-shrink">four</div>
      <div class="grow-shrink">five</div>
    </div>

    Here’s a way around that jerky animation though. Each element has a wrapping element. We hover over that one and only scale down the inner one.

    #container {
      display: flex;
    }
    
    .grow-shrink-wrapper .grow-shrink {
      background: #EEE;
      border: 1px solid lightblue;
      padding: 10px 15px;
      
      opacity: 1;
      transform: scale(1);
      
      /*Tell this element which properties to animate if something changes
      We are saying all properties will animate when changed for 0.3 seconds*/
      transition: all 0.3s;
    }
    
    .grow-shrink-wrapper:hover .grow-shrink {
      transform: scale(0);
      opacity: 0;
    }
    <div id="container">
      <div class="grow-shrink-wrapper">
        <div class="grow-shrink">one</div>
      </div>
      <div class="grow-shrink-wrapper">
        <div class="grow-shrink">two</div>
      </div>
      <div class="grow-shrink-wrapper">
        <div class="grow-shrink">three</div>
      </div>
      <div class="grow-shrink-wrapper">
        <div class="grow-shrink">four</div>
      </div>
      <div class="grow-shrink-wrapper">
        <div class="grow-shrink">five</div>
      </div>
    </div>
    Login or Signup to reply.
  2. @keyframes are explicit set of instructions which will be executed once the page loads, and the animation properties dictates specific timing and frequency. So you’ll need a small amount of JavaScript to prevent the default state animation from running on page-load (the shrinking part) (see Example A).

    transitions just dictates timing so it doesn’t start executing any animation on page-load. It’s triggered by an actual change of the style(s) it’s bound to so JavaScript isn’t needed (see Example B).

    Example A

    setTimeout(() => document.querySelector(".modal").style.visibility = "visible", 1200);
    @keyframes shrink {
      from {
        transform: scale(1.0);
        opacity: 1.0;
      }
      to {
        transform: scale(0.0);
        opacity: 0.0;
      }
    }
    
    @keyframes grow {
      from {
        transform: scale(0.0);
        opacity: 0.0;
      }
      to {
        transform: scale(1.0);
        opacity: 1.0;
      }
    }
    
    :root {
      font: 2ch/1.15 "Segoe UI";
    }
    
    .box {
      list-style: none;
      position: relative /* Make it's borders to which absolute elements 
      will reference their positions from */;
      width: 50vw;
      margin: 20px auto;
      padding: 10vw;
      background: #fff;
      cursor: pointer;
    }
    
    .icon {
      position: absolute /* Position itself to the top left corner of .box */;
      top: 0;
      left: 0;
      width: 35vw;
      background: #fff;
    }
    
    .icon figcaption {
      font-weight: 900;
      font-size: 1.15rem;
      font-variant: small-caps;
      letter-spacing: 1.5px;
      text-align: center;
    }
    
    .icon img {
      object-fit: contain;
      object-position: center;
      width: 100%;
    }
    
    .modal {
      position: absolute /* Position itself to the top left corner of .box */;
      top: 0;
      left: 0;
      z-index: 1 /* Position itself "over" .icon */;
      width: 60vw;
      padding: 8px;
      border-radius: 8px;
      background: lightblue;
      transform-origin: center /* It will start and end it's animation witin
      it's "center" */;
      animation: shrink 0.7s ease-in-out /* [name of keyframes]
      [duration] [timing function] */;
      box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
      visibility: hidden /* Needs to be invisible at page-load so that
      the shrink animation isn't initially seen. */;
      opacity: 0.0 /* Stay invisible until either .box is hovered over */;
      pointer-events: none /* Any clicking or hovering will be ignored */;
    }
      
    .box:hover .modal {
       animation: grow 0.7s ease-in-out forwards /* [name of keyframes]
      [duration] [timing function] [fill mode] 
      Hovering over .box will trigger .modal to grow. 
      If .box is no longer hovered over, .modal will 
      revert back to default (shrink to nothing) */;
    }
    
    .modal thead th:first-of-type,
    .modal td,
    .modal tfoot th {
      padding: 2.5px 5px;
      text-align: left;
    }
    
    .modal tbody td:nth-child(n+2) {
      text-align: center;
    }
    
    .modal tr td:last-of-type {
      text-align: right;
    }
    
    .modal tfoot tr:last-of-type td {
      font-weight: 900;
    }
    
    .modal tbody tr:last-of-type td {
      padding-bottom: 6px;
      border-bottom: 1px solid black;
    }
    <!--
      .box contains .icon and .modal which both position themselves in
      relation to the borders of .box.
    -->
    <menu class="box">
      <!--
        .icon is always visible so it can serve as a visual cue to the user.
      -->
      <figure class="icon">
        <figcaption>Shopping Cart</figcaption>
        <img src="https://i.ibb.co/NF2RWXB/cart.png">
      </figure>
      <!-- 
        By default .modal is microscopic. Once .box is hovered over .modal
        grow to full size. It will maintain full size until .box is no longer hovered over.
      -->  
      <table class="modal">
        <thead>
          <tr>
            <th>Item</th>
            <th>Each</th>
            <th>Qty</th>
            <th>Price</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>Sweater</td>
            <td>32.99</td>
            <td>2</td>
            <td>65.98</td>
          </tr>
          <tr>
            <td>Shoes</td>
            <td>89.99</td>
            <td>1</td>
            <td>89.99</td>
          </tr>
          <tr>
            <td>T-shirt</td>
            <td>12.99</td>
            <td>5</td>
            <td>64.95</td>
          </tr>
        </tbody>
        <tfoot>
          <tr>
            <th colspan="3">Sub-total</th>
            <td>240.25</td>
            <tr>
              <th colspan="3">Tax 8.75%</th>
              <td>19.33</td>
            </tr>
            <tr>
              <th colspan="3">Grand Total</th>
              <td>259.58</td>
            </tr>
        </tfoot>
      </table>
    </menu>

    Example B

    :root {
      font: 2ch/1.15 "Segoe UI";
    }
    
    .box {
      list-style: none;
      position: relative /* Make it's borders to which absolute elements 
      will reference their positions from */;
      width: 50vw;
      margin: 20px auto;
      padding: 10vw;
      background: #fff;
      cursor: pointer;
    }
    
    .icon {
      position: absolute /* Position itself to the top left corner of .box */;
      top: 0;
      left: 0;
      width: 35vw;
      background: #fff;
    }
    
    .icon figcaption {
      font-weight: 900;
      font-size: 1.15rem;
      font-variant: small-caps;
      letter-spacing: 1.5px;
      text-align: center;
    }
    
    .icon img {
      object-fit: contain;
      object-position: center;
      width: 100%;
    }
    
    .modal {
      position: absolute /* Position itself to the top left corner of .box */;
      top: 0;
      left: 0;
      z-index: 1 /* Position itself "over" .icon */;
      width: 60vw;
      padding: 8px;
      border-radius: 8px;
      background: lightblue;
      transform: scale(0.0) /* It is microscopic by default */;
      transform-origin: center /* It will start and end it's animation witin
      it's "center" */;
      transition: transform 0.7s ease-in-out /* [name of property]
      [duration] [timing function] */;
      box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
    }
      
    .box:hover .modal,
    .modal:hover {
      transform: scale(1.0) /* Hovering over .box or .modal will trigger 
      .modal to grow. If neither of them are hovered over, .modal will 
      revert back to default (shrink to nothing) */;
    }
    
    .modal thead th:first-of-type,
    .modal td,
    .modal tfoot th {
      padding: 2.5px 5px;
      text-align: left;
    }
    
    .modal tbody td:nth-child(n+2) {
      text-align: center;
    }
    
    .modal tr td:last-of-type {
      text-align: right;
    }
    
    .modal tfoot tr:last-of-type td {
      font-weight: 900;
    }
    
    .modal tbody tr:last-of-type td {
      padding-bottom: 6px;
      border-bottom: 1px solid black;
    }
    <!--
      .box contains .icon and .modal which both position themselves in
      relation to the borders of .box.
    -->
    <menu class="box">
      <!--
        .icon is always visible so it can serve as a visual cue to the user.
      -->
      <figure class="icon">
        <figcaption>Shopping Cart</figcaption>
        <img src="https://i.ibb.co/NF2RWXB/cart.png">
      </figure>
      <!-- 
        By default .modal is microscopic. Once .box is hovered over .modal
        grow to full size. It will maintain full size until neither .box or .modal 
        is hovered over.
      -->  
      <table class="modal">
        <thead>
          <tr>
            <th>Item</th>
            <th>Each</th>
            <th>Qty</th>
            <th>Price</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>Sweater</td>
            <td>32.99</td>
            <td>2</td>
            <td>65.98</td>
          </tr>
          <tr>
            <td>Shoes</td>
            <td>89.99</td>
            <td>1</td>
            <td>89.99</td>
          </tr>
          <tr>
            <td>T-shirt</td>
            <td>12.99</td>
            <td>5</td>
            <td>64.95</td>
          </tr>
        </tbody>
        <tfoot>
          <tr>
            <th colspan="3">Sub-total</th>
            <td>240.25</td>
            <tr>
              <th colspan="3">Tax 8.75%</th>
              <td>19.33</td>
            </tr>
            <tr>
              <th colspan="3">Grand Total</th>
              <td>259.58</td>
            </tr>
        </tfoot>
      </table>
    </menu>

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search