Search code examples
javascripthtmlcsscss-animationscss-animation-direction

How to animate a pop up on show and close using css?


I have a layout as follows,

enter image description here

container - to hold all the cards.

card - div for containing information.

In the above Image, the left one shows the initial rendering of the screen, When user clicks on any inner card, the corresponding card should popout/zoomout,

and when user click backs on pop up card, it should disappear and the first sceen should display.

The popup animation should be like that, it should start from the position of the card, we have clicked.

The popup close animation after second click(When popup is open), the animation should look like that, the popup should get minimized to the card clicked in the first step.

I have tried following code, but it is really animating..

let isOpen = false;

$(".child").on("click", function() {
  if (!isOpen) {
    $(".child").removeClass("active");
    $(this).addClass("active");
    isOpen = true;
  } else {
    $(this).removeClass("active");
    isOpen = false;
  }
})
* {
  box-sizing: border-box;
}

.parent {
  margin: 40px auto;
  width: 400px;
  height: 600px;
  border: 1px solid #3b3b3b;
  border-radius: 20px;
  padding: 20px 40px;
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
}

.child {
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px solid #000;
  border-radius: 40px;
  cursor: pointer;
  transition: all 0.5s ease-in;
}

.child.active {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 10;
  border: 1px solid red;
  background: #000;
  border-radius: 20px;
  color: #fff;
}

@keyframes zoomIn {
  0% {
    transform: scale(1.1);
  }
  50% {
    transform: scale(1.2);
  }
  100% {}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent">
  <div class="child">1</div>
  <div class="child">2</div>
  <div class="child">3</div>
  <div class="child">4</div>
</div>

Please help me to simulate the same.


Solution

  • You can try achieve this with by css variables calculation, position: absolute and a separate .active class for each element.

    let isOpen = false;
      
    $('.child').on('click', function() {
      if (!isOpen) {
        $('.child').removeClass('active');
        $(this).addClass('active');
        isOpen = true;
      } else {
        $(this).removeClass('active');
        isOpen = false;
      }
    });
    *,
    ::after,
    ::before {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    :root {
      --parent-width: 400px;
      --parent-height: 600px;
      --gap: 20px;
    }
    .parent {
      margin: 40px auto;
      width: var(--parent-width);
      height: var(--parent-height);
      border: 1px solid #3b3b3b;
      border-radius: 20px;
      position: relative;
    }
    
    .child {
      display: flex;
      justify-content: center;
      align-items: center;
      border: 1px solid #000;
      border-radius: 40px;
      cursor: pointer;
      transition: all 0.5s ease-in;
      position: absolute;
      height: calc((var(--parent-height) / 2) - (var(--gap) * 2));
      width: calc((var(--parent-width) / 2) - (var(--gap) * 3));
    }
    
    /* Init size */
    .child:nth-child(1) {
      top: var(--gap); /* padding top 20px */
      left: calc(var(--gap) * 2); /* padding left 40px */
    }
    .child:nth-child(2) {
      top: var(--gap);
      right: calc(var(--gap) * 2); /* padding right 40px */
    }
    .child:nth-child(3) {
      bottom: var(--gap); /* padding bottom 20px */
      left: calc(var(--gap) * 2); /* padding left 40px */
    }
    .child:nth-child(4) {
      bottom: var(--gap);
      right: calc(var(--gap) * 2);
    }
    
    /* Full size */
    .child:nth-child(1).active {
      top: 0;
      left: 0;
    }
    .child:nth-child(2).active {
      top: 0;
      right: 0;
    }
    .child:nth-child(3).active {
      bottom: 0;
      left: 0;
    }
    .child:nth-child(4).active {
      bottom: 0;
      right: 0;
    }
    
    .child.active {
      width: 100%;
      height: 100%;
      z-index: 10;
      border: 1px solid red;
      background: #000;
      border-radius: 20px;
      color: #fff;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="parent">
      <div class="child">1</div>
      <div class="child">2</div>
      <div class="child">3</div>
      <div class="child">4</div>
    </div>