Link to github.com/XboxYan/not…

A button, “button,” is probably one of the most common components of a web page. If you come across one of these, would you be tempted to make more of it?

Usually the first response to this effect is to use canvas, as in the following example

Of course, canvas implementation also has certain threshold, and the actual use of a little bit of trouble (all JS implementation), here to try CSS implementation.

Generate particles

Aside from the JS scheme, there are HTML and CSS implementations. Don’t mention HTML, just write a lot of tags

<button>
    button
    <i></i>
    <i></i>
    <i></i>
    <i></i>
    <i></i>.</button>
Copy the code

In general, I don’t like this. It’s too many tags, the structure is ugly, and it can have other effects on the existing page (in many cases, it’s not easy to change the original HTML structure).

So let’s look at the CSS implementation, mainly is two ways, in fact is to think about what properties can be infinite overlay, one is box-shadow, and one is background-image (CSS3 supports infinite overlay).

1.box-shadow

Let’s take a look at the box-shadow approach, which uses pseudo-element generation to avoid using extra tags.

.button::before{
  position: absolute;
  content: ' ';
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background-color: #ff0081;
  box-shadow: 10px 10px #ff0081.15px 0px 0 2px #ff0081.20px 15px 0 3px #ff0081. ;/* Infinite stack */
}
Copy the code

The effect is still there, but it takes a little more time to debug. Here, the position and size of the particles are determined based on the offset and expansion.

However, the offset here is only px units, which is not very adaptive to the size of the button, so the second method is used here

2.background-image

Background-image in CSS3 can be infinitely superimposed, similar to

.myclass {
  background: background1, background2, / *... * / backgroundN;
}
Copy the code

Here, we can adopt radial gradient destruction-gradient to realize multiple small dots.

.button::before{
  position: absolute;
  content: ' ';
  left: -2em;
  right: -2em;
  top: -2em;
  bottom: -2em;
  pointer-events: none;
  background-repeat: no-repeat;
  background-image: radial-gradient(circle, #ff0081 20%, transparent 0), 
  radial-gradient(circle, #ff0081 20%, transparent 0),
  radial-gradient(circle, #ff0081 20%, transparent 0), 
  radial-gradient(circle, #ff0081 20%, transparent 0), ... ;background-size: 10% 10%.20% 20%.15% 15%. ;background-position: 18% 40%.20% 31%.30% 30%. ; }Copy the code

Here, the size and position of the origin are controlled mainly by background-size and background-position, which seems quite complicated. In fact, as long as the background-size and background-position correspond to the background-image position. The actual development may be a little difficult to debug, but you can fine-tune the real-time preview directly in the console by clicking the left, right, up, down keyboard (consider a visual tool).

This creates a simple particle effect.

move

While background-image does not support CSS animation, the other two background-size and background-position animations do. Therefore, CSS Transition and ANIMATION can be used.

The animation is very simple, it is the process of particles spreading out from the center and gradually disappearing.

transition

Let’s start with: Hover Interaction

.button::before{
  transition:.75s background-position ease-in-out,75s background-size ease-in-out;
}
.button:hover::before{
  background-position: 5% 44%, -5% 20%.7% 5%. ;background-size: 0% 0%;
}
Copy the code

Of course, this setting is definitely not ideal. When the mouse leaves, it will shrink back. The effect is as follows

We need the mouse to leave without shrinking back. How do we do that?

Simple, just set transition under :hover, which means that there is only transition when the mouse is over, and no transition when the mouse is away

.button:hover::before{
  background-position: 5% 44%, -5% 20%.7% 5%. ;background-size: 0% 0%;
  transition:.75s background-position ease-in-out,75s background-size ease-in-out;
}
Copy the code

Does that make you feel a little better? Check it out here.

What if we want to make a particle animation when we click? That’s where the active pseudo-class comes in.

If we follow the :hover logic, then

.button:active::before{
  background-position: 5% 44%, -5% 20%.7% 5%. ;background-size: 0% 0%;
  transition:.75s background-position ease-in-out,75s background-size ease-in-out;
}
Copy the code

Unfortunately, it only works when the mouse is held down, but it doesn’t work when the mouse is raised, so we need to change the Angle. Think of it this way: the default is divergent, and then when you click it, it will converge, and when you lift it, it will revert to the divergent state. At the same time, when you click it, you need to cancel the transition effect, as follows

.button::before {
    / *... * /
    background-position: 5% 44%. ;/* Diffuse state */
    background-size: 0% 0%;
    transition: background-position .5s ease-in-out, background-size .75s ease-in-out;
}

.button:active::before {
  transition:0s;/** Notice to cancel the transition **/
  background-size: 10% 10%.20% 20%. ;background-position: 18% 40%.20% 31%. ; }Copy the code

You can check out the demo

Why do you need transition: 0S in: Active? You can try the effect without adding, as follows

animation

Animation and Transition implementation principle is similar, the advantage is that you can make more detailed animation, here take :active mode for example.

.button::before{
  / *... * /
  animation: bubbles ease-in-out .75s forwards;
}
.button:active::before {
  animation: none; /* Cancel animation */
  background-size: 0;
}
@keyframes bubbles {
  0% {
    background-position: 18% 40%. ; 50%} {background-position: 10% 44%. ; 100%} {background-position: 5% 44%. ;background-size: 0% 0%; }}Copy the code

You can view the source code here.

The only downside might be that the initialization animation executes itself once.

summary

You can just copy the CSS and throw it directly into a project, whether it’s a native project or a React project. You don’t need to tie any events to it, and you don’t need to do any extra logic processing to enhance the existing experience. Imagine if this is a “buy” button, will trigger what do you buy a few times more, anyway, I’m sure I will be attracted, ha ~ remains some shortcomings, such as the positioning of the above, is many workload, suggest the function after the completion of a project as a whole to finely grind, also can try to do some visual tools to reduce the workload, to the end.