skip to Main Content

I’m currently working on a hover animation and aiming to achieve the following effect:
Link to expected animation

I’ve created a Code Sandbox to demonstrate my current approach.

Assets used in this animation can be found here.

I’m open to any suggestions or improvements on the hover animation. Any insights would be greatly appreciated. Thank you!

I am having hard time controlling the cycle of the animation.

<div class="wrapper">
  <div class="card">
    <div class="wrap"></div>
  </div>
</div>

body {
  background: #000;
}

.wrapper {
  width: 400px;
  height: 200px;
  margin: auto;
}
.card {
  z-index: 1;
  height: 200px;
  position: relative;
  background: #2c2c2c;
  border-radius: 8px;
  cursor: pointer;
}

.card::before {
  content: "";
  position: absolute;
  left: -2px;
  top: -2px;
  background-image: url("./bg-2.png");
  background-size: 100% 100%;
  background-repeat: no-repeat;
  width: calc(100% + 4px);
  height: calc(100% + 4px);
  z-index: -1;
  transition: all 0.5s ease-in-out;
  clip-path: inset(0 0 0 0);
}

.card:hover::before {
  animation: clippath 0.9s linear forwards;
}

.card:not(:hover)::before {
  clip-path: inset(0 0 0 0);
  transition: all 0.5s ease-in-out;
  background-image: url("./bg-1.png");
}

.wrap {
  background: #2c2c2c;
  border-radius: 8px;
  height: 200px;
}

@keyframes clippath {
  0%,
  100% {
    -webkit-clip-path: inset(0 0 0 0);
    clip-path: inset(0 0 0 0);
  }
  25% {
    -webkit-clip-path: inset(0 98% 0 0);
    clip-path: inset(0 0 0 98%);
  }
  50% {
    -webkit-clip-path: inset(98% 0 0 0);
    clip-path: inset(98% 0 0 0);
  }
  75% {
    -webkit-clip-path: inset(0 0 0 98%);
    clip-path: inset(0 98% 0 0);
  }
}

2

Answers


  1. You can achieve this with css using background gradient and animating the same on hover.

    * {
       box-sizing: border-box;
    }
    
    body {
       background: #000;
       padding: 40px;
    }
    
    .wrapper {
       width: 400px;
       height: 200px;
       margin: auto;
    }
    .card {
       z-index: 1;
       height: 200px;
       position: relative;
       background: #2c2c2c;
       border-radius: 8px;
       cursor: pointer;
       overflow: hidden;
    
       &:hover:before {
          transform: rotate(180deg);
       }
    
       &::after {
          content: "";
          position: absolute;
          background: #2c2c2c;
          border-radius: 8px;
          left: 2px;
          right: 2px;
          top: 2px;
          bottom: 2px;
       }
    
       &::before {
          content: "";
          position: absolute;
          left: -2px;
          top: -2px;
          background-repeat: no-repeat;
          width: calc(100% + 4px);
          height: calc(100% + 4px);
          z-index: -1;
          transition: all 0.5s ease-in-out;
          background: rgb(255, 255, 255);
          background: linear-gradient(
             142deg,
             rgba(255, 255, 255, 1) 0%,
             rgba(44, 44, 44, 1) 20%,
             rgba(44, 44, 44, 1) 80%,
             rgba(255, 255, 255, 1) 100%
          );
          border-radius: 8px;
       }
    }
    <div class="wrapper">
       <div class="card">
          <div class="wrap"></div>
       </div>
    </div>
    Login or Signup to reply.
  2. You can have a faded border effect using background linear gradient. Set two gradients up, one to overlap the other. The top one is the button colour. The bottom one is the effect you’re trying to achieve. Position the backgrounds using padding box and border box respectively so that the background with the fade goes all the way to the border edge.

    You can then use the fairly recent @property rule to animate the background. This isn’t fully supported yet but has pretty good coverage apart from Firefox. It cut out a lot of CSS though. See below.

    body {
      background: black;
    }
    
    @property --angle {
      syntax: '<angle>';
      inherits: false;
      initial-value: 135deg;
    }
    
    .button {
      width: 20rem;
      height: 12rem;
      border-radius: 2rem;
      background-color: #2c2c2c;
      padding: 0.75rem;
      color: white;
      background: linear-gradient(0deg, #2c2c2c, #2c2c2c), 
                  linear-gradient(var(--angle), gray 10%, transparent 30%, transparent 70%, gray 100%);
      border: 0.5rem solid transparent;
      background-clip: padding-box,
                       border-box;
      background-origin: padding-box,
                         border-box;
      transition: --angle 250ms;
    }
    
    .button:hover {
      --angle: 45deg;
    }
    <div class='button'>Some text</div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search