How to make a effect when you click a button using CSS and JavaScript

How to make a effect when you click a button using CSS and JavaScript

For advanced website and app design, you often use additional effects when a button is clicked. Let's break down how to implement this using CSS and vanilla Javascript.

Working example of a button:

Click me

Unfortunately, you can't do it with CSS alone, so you'll have to use JavaScript. For those who are not familiar with it yet - this is a great reason to start, I will give exhaustive comments on how the script works. It's small and simple, but I know from myself how intimidating this "magic" is until you figure it out.

The general principle of the effect is as follows:

  • on page load, add a handler for the event of clicking on a button or buttons
  • when clicking, add a certain class to the button, which has a click animation
  • delete the class after N time, so that the effect works on the next click

Let's break it down with a concrete example.

First create a simple wireframe of the page with the button:

<div class="main">
<div class="button">BUTTON</div>

Now let's set basic styles for the page and the button (they are optional, it's for the beauty of the example).

/* Remove default indents */
body, html {
	margin: 0;
	padding: 0;

.main {
    /* Set the height and styles of the common block */
	height: 400px;
	background-color: #f5f5f5;
    /* Center the button */
	display: flex;
	justify-content: center;
	align-items: center;

.button {
	background-color: #000;
	color: #fff;
	padding: .75em 1.5em;
	cursor: pointer;
	transition: box-shadow 200ms linear;

.button:hover {
	box-shadow: 0 .5em 1em 0 rgba(0, 0, 0, 0.15), 0 .4em .5em -.4em rgba(0, 0, 0, 0.4);

And here is the mandatory CSS - the click effect itself.

.button {
	position: relative;

.button:after {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
	margin: -40px 0 0 -40px;
	width: 80px;
	height: 80px;
	border-radius: 50%;
	opacity: 0;
	box-shadow: inset 0 0 0 35px rgba(0,0,0,0.1);
	display: none;
} {
	animation: animate-click 0.6s ease-out forwards;
	display: block;

@keyframes animate-click {
	0% {
		opacity: 1;
		transform: scale3d(0.4, 0.4, 1);

	80% {
		box-shadow: inset 0 0 0 2px rgba(0,0,0,0.1);
		opacity: 0.1;

	100% {
		opacity: 0;
		box-shadow: inset 0 0 0 2px rgba(0,0,0,0.1);
		transform: scale3d(1.2, 1.2, 1);

Let's see how it works. First, add an effect block after the button, set its size and positioning. By default, the block is hidden. It has an internal shadow that fills almost the entire block.

Next, we describe the animation, if the button has the .click class added. Usually animation is added, for example, when hovering over an element, but in our example the class will be added to the block by the script. And the animation will be triggered every time the button has this .click. Without the script, this animation will be triggered simply when the page loads.

Let's write the animation itself. First, the block is reduced in size to 40% by the property transform: scale3d(0.4, 0.4, 1);. Then follows a gradual decrease in transparency and reduction of the internal shadow, that is, it shrinks from the center to the edges, which visually looks like an increase in the block. At the same time the block itself increases, becoming transparent, it adds the effect of wavy disappearance of the shadow, as if it is catching up with the expanding block.

You can change the color, animation time, initial block size, size at compression and enlargement to achieve the desired effect. Now all that's left is to add the JS code.

// After document structure load
document.addEventListener("DOMContentLoaded", () => {
    // Define the button block
    const button = document.querySelector('.button');
    // Set up the event listener by clicking on the button
    button.addEventListener("click", (event) => {
        // Define the clicked element
        const elem =;
        elem.classList.add('click'); // Add a .click class to the block
        setTimeout(function() {
            elem.classList.remove('click'); // Delete the .click class after 400ms
        }, 400);

That's it, now we have buttons with click effect. If you liked the article, you can share it on social networks and bookmark it to look up when necessary. Thanks for reading :)

Please rate this article
(5 stars / 2 votes)