This is the 21st day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Hi, I’m Banxia 👴, a sand sculptor who has just started writing. If you like my article, you can pay attention to ➕ like 👍 pay attention to the public number: Banxia words front end, learn more front-end knowledge! Click me to explore a new world!

preface

As for button, no matter the style or animation, various gods share their own ideas, and in button animation, the effect of border scrolling is the best, IN my opinion. Although it is button’s animation, in fact, this animation effect is not limited to button. In the frame scrolling animation, there are mainly the following three kinds,

The premise

These three border scrolling animations,

  1. I use the pseudo-elements ::after and ::before to achieve, of course, can not use the pseudo-elements, set a layer of div, but I personally think it is more complicated, and more consideration.

  2. The border of the button is not a border, but a box-shadow. This ensures that the width and height of the button are the same as those of the :after/before button. If you use border, the scrolling border will be inside if you’re not careful. Something like this:

border: 0;
box-shadow: inset 0 0 0 2px #409EFF;
Copy the code

unilateral

As shown above, when the mouse is placed on the button, it will start from one corner, go around, and finally return to the starting corner. This animation happens to be a circle, and it happens to use after and before. This might seem a bit difficult, but it’s actually quite simple: all you have to do is control the width and height of after from 0 to 100 to 100%.

Initial state: After and before are both width and height 0, and border is transparent,

  button::before,
  button::after {
      box-sizing: inherit;
      content: "";
      position: absolute;
      width: 0;
      height: 0;
      border: 2px solid transparent;
}
Copy the code

How to ensure that around a circle, the positioning of two pseudo-elements must be different, and around the animation, is responsible for one half, the lower right corner is the dividing line.

button::before {
top: 0;
left: 0;
}
button::after {
bottom: 0;
right: 0;

}
Copy the code

Since the border changes side by side, we mainly set the animation delay.

button:hover::before, button:hover::after { width: 100%; height: 100%; } button:hover::before { border-top-color: #60daaa; border-right-color: #60daaa; Transition: width 0.25s, height 0.25s 0.25s; } button:hover::after { border-bottom-color: #60daaa; border-left-color: #60daaa; Transition: border-color 0s 0.5s, width 0.4s 0.5s, height 0.4s 0.4s; }Copy the code

bilateral

This animation is an upgrade of the last one, but I think it’s simpler at the code level.

We only need to change two places to unify the positioning of both

button::after,
button::before 
{
top: 0;
left: 0;
}
Copy the code

Change the following animation to increase the height and then the width.

button:hover::after { border-bottom-color: #60daaa; border-left-color: #60daaa; Transition: height 0.25s, width 0.25s 0.25s; }Copy the code

Quadrilateral diffusion

At first glance, it looks troublesome, because all four edges spread out from the middle point to both sides. The first thing that comes to mind is the transform-origin: center; , this property can change the position of the element, so now we’re solving another problem, spreading out to both sides. I originally thought width from 0 to 100%, but this transform-origin: center; I don’t think it’s working. I vaguely remember adding an attribute that would work, but I just can’t remember! So I go to another property, scale*, as long as I set it to 0 at the beginning and 1 at the end.

I split the top and bottom, and the effect is as follows:

button::before { border-top: 2px solid #60daaa; border-bottom: 2px solid #60daaa; transform: scale3d(0, 1, 1); } button:hover::before { transform: scale3d(1, 1, 1); The transition: 0.5 s transform; }Copy the code

The complete code