24
头图

In the web, most buttons may be unremarkable, and sometimes in order to emphasize the special brand or satisfy special functions, it may be necessary to add a little click animation to the button. For example, friends who have used Ant Design should be able to find that there will be a very subtle water wave animation when clicking the button

Kapture 2022-02-10 at 18.55.48

This is very unique, seeing such a button will naturally contact Ant Design.

The animation process is actually not complicated. I took a look at the official implementation. It is achieved by dynamically changing the properties through js. When clicking, the properties are changed and the animation is triggered. When the animation ends, the properties are restored (the restoration is to ensure the next time. Click still has animation), as follows

image-20220211184419600

Seems a little troublesome? In fact, this effect can also be achieved with pure CSS, and it can also achieve other more interesting effects

Kapture 2022-02-11 at 20.02.15

Let's take a look together~

1. CSS transition animation

Usually there are two ideas for implementing animation in CSS, transition and animation . Generally speaking, simple ones that need active triggering ( :hover , :active or dynamic switching of class names, etc.) can be implemented with transition , and others can be implemented with animation .

Back to this example, the animation is simple enough, only two changes, and it needs to be triggered actively (here is a click, you can think of :active ), so the priority is to use transition to achieve.

Observing the entire animation, it is actually the superposition of two effects.

  1. The shadows keep growing
  2. Transparency is declining

Then, the two states of this animation (transition) can be represented like this

/* 初始状态 */
button{
  opacity: .4;
  transition: .3s;
}
/* 扩散状态 */
button{
  box-shadow: 0 0 0 6px var(--primary-color);
  opacity: 0;
}

Well, the styles of the two states are written, how to trigger the click?

Second, CSS click animation

First improve the basic style, assuming the HTML structure is as follows

<button class="button">Default</button>

Just beautify

:root{
  --primary-color: royalblue;
}
.button{
  padding: 5px 16px;
  color: #000000d9;
  border: 1px solid #d9d9d9;
  background-color: transparent;
  border-radius: 2px;
  line-height: 1.4;
  box-shadow: 0 2px #00000004;
  cursor: pointer;
  transition: .3s;
}
.button:hover{
  color: var(--primary-color);
  border-color: currentColor;
}

Then add the shadow diffusion animation. In order to facilitate the control of transparency, the ::after pseudo-class is used to render separately here.

.button::after{
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  opacity: 0.4;
  transition: .3s;
}

If the transition animation is triggered by :active according to the normal idea, it may be implemented like this

.button:active::after{
  box-shadow: 0 0 0 6px var(--primary-color);
  opacity: 0;
}

The effect is as follows:

Kapture 2022-02-10 at 20.35.12

Hmm, doesn't seem right? Then look down

3. CSS transition reset

Why does the above phenomenon occur? :active is mentioned here. :active only works when the mouse is pressed, usually when a button is clicked, it is a light click, not a long press, if you add animation on :active , then when the mouse is lifted, the animation is generally not end, so it will cause the animation to stop immediately when the mouse is lifted. If it is transition , there will also be a "fallback" transition effect.

So, is there any way to animate only when the mouse is raised?

My implementation is like this, assuming that there is a shadow (transparency of 0) by default, the shadow is quickly removed at :active ("quickly" here means cancels the transition animation pressed down), and then because the default is There is a transition, so when the mouse is lifted, the shadow will fall back to the shadowed state, which can ensure that there is no animation when pressed, and lift it up to trigger the transition animation.

The whole process is actually like this:

image-20220214104311207

It is also very simple to cancel the transition animation, just set the duration to 0, the code implementation is like this

.button::after{
  /*其他样式*/
  opacity: 0;
  box-shadow: 0 0 0 6px var(--primary-color);
  transition: .3s;
}
/*点击*/
.button:active::after{
  box-shadow: none;
  opacity: 0.4;
  transition: 0s; /*取消过渡*/
}

Then, the magic effect came out!

Kapture 2022-02-10 at 20.56.07

This achieves almost the same click effect as Ant Design

4. Other dynamic cases

The above actually provides an idea, as long as it is this kind of click animation, it can be implemented in this way. For example, a refresh button like this, turn it when it needs to be clicked

Kapture 2022-02-10 at 21.14.32

It is very easy to use this way of thinking. This example is simpler than the above one. After all, only the rotation changes, but no transparency changes. The core code is as follows

.icon{
    transform: rotate(360deg);
    transition: .5s;
}
.button:active .icon{
    transform: rotate(0);
    transition: 0s;
}

The complete code can be accessed at ant design button (codepen.io) , with more demos integrated

Kapture 2022-02-10 at 21.18.41

Another example is such a click particle dynamic effect, the principle is the same

Kapture 2022-02-11 at 14.08.54

In the previous article CSS implements a particle animation button has been mentioned, I will not say more here, the complete code can be accessed button-active (codepen.io)

5. More complex animations

As mentioned earlier, simple animations can be achieved with transition transition , then a little more complicated, such as the button below "Q bomb Q bomb"

Kapture 2022-02-11 at 14.13.25

This kind of animation, simple transition is powerless, it must be realized with the help of animation , the principle is still similar

First define an animation keyframe

@keyframes tada {
    from {
        transform: scale3d(1, 1, 1)
    }
    10%, 20% {
        transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg)
    }
    30%, 50%, 70%, 90% {
        transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg)
    }
    40%, 60%, 80% {
        transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg)
    }
    to {
        transform: scale3d(1, 1, 1)
    }
}
This animation comes from tada in Animate.css , just copy it directly

then make the button move

.button{
  animation: tada 1s;
}

Reset the animation on click, reset the animation directly, animation may be better understood, so that the animation will be rerun when lifted

.button:active{
  animation: none;
}

This is achieved, is it unexpectedly easy?

However, there is a small flaw. Every time the page is refreshed, the button will automatically perform an animation (because the animation is automatically executed), as follows

Kapture 2022-02-11 at 14.20.28

So, how can I avoid the animation not executing the first time it comes in?

Here is a little trick, you can set the animation duration to 0 by default, so that after the first animation is executed, it will end immediately, and then restore the default animation duration at hover , Since the animation has ended, changing the animation duration will not work. will trigger the animation to run again, so the implementation is

.button{
  animation: jump 0s;
}
.button:hover{
  animation-duration: 1s;
}
.button:active{
  animation: none;
}

This way refresh the page and there will be no more animations

Kapture 2022-02-11 at 14.28.44

Next, with animate.css you can replace any animation, like

Kapture 2022-02-11 at 19.59.00

The complete code can be accessed at button-jump (codepen.io) , with more demos integrated

Kapture 2022-02-11 at 20.02.15

6. Summary and Explanation

The above are a few routines and some cases about CSS click animation. In fact, the animation is executed by default, and it is enough to reset it when clicked. Overall, the code is very simple, but it may not be very smooth to understand. The following summarizes the implementation points:

  1. Simple animations use transitions, others use animations
  2. The transition can be reset by setting the duration to 0
  3. animation can be reset by setting none
  4. Reset the animation when :active, after clicking it will run the animation again
  5. Complex animations can take advantage of existing animation libraries such as anmate.css
  6. Set the animation duration to 0 to avoid animation on the first render

Compared with the js implementation, the CSS implementation code is less, the loading is faster, there is no need to wait for the js to load, the experience is better (for example, it naturally supports hitting the space bar to trigger), and it is also easier to maintain and use, just copy a class name directly. Finally, if you think it's good and helpful to you, please like, bookmark, and forward ❤❤❤


XboxYan
18.1k 声望14.1k 粉丝