- Animating buttons with CSS and keyframes
- Initial setup
- Refresh Button
- Back Button
- Next Button
- 20 CSS Button Click Effects
- Related Articles
- Author
- Links
- Made with
- About a code
- Subtle Button
- Author
- Links
- Made with
- About a code
- Button Click Pulsing Effect
- Author
- Links
- Made with
- About a code
- Copy Button Click Effect
- Author
- Links
- Made with
- About the code
- Material UI Stretch Button
- Author
- Links
- Made with
- About the code
- SCSS Beveled Buttons
- Author
- Links
- Made with
- About the code
- Ripple Button with Few JavaScript
- Author
- Links
- Made with
- About the code
- CSS-only Ripple Effect Button
- Author
- Links
- Made with
- About the code
- Sweet Little Button Mixin
- Author
- Links
- Made with
- About the code
- Black Biometirics Login Button
- Author
- Links
- Made with
- About the code
- Delete Button with Micro-Interactions
- Author
- Links
- Made with
- About the code
- Add To Collection Button
- Author
- Links
- Made with
- About the code
- Bubbly Button with Click Animation
- Author
Animating buttons with CSS and keyframes
Let’s say that you have a button in your HTML, and you want it to be animated when someone clicks it. I am going to show you here how you could do it with CSS Animations and a little bit of javascript.
Initial setup
To begin with, I will be setting up some simple HTML and CSS with 3 neon styled buttons, so we can demonstrate some alternatives.
rel="preconnect" href="https://fonts.gstatic.com"> href="https://fonts.googleapis.com/css2?family=Ubuntu&display=swap" rel="stylesheet"> rel="stylesheet" href="index.css"> src="index.js"> class="container"> class="btn btn-back" type="button">Back class="btn btn-refresh" type="button">Refresh class="btn btn-next" type="button">Next
html, body margin: 0; padding: 0; > body background-color: black; > .container display: flex; justify-content: center; align-items: center; height: 100vh; > .btn min-width: 70px; max-width: 200px; margin: 1em; padding: 1em 2em; border-radius: 5px; border-width: 2px; background-color: black; font-family: 'Ubuntu', sans-serif; font-size: 1em; letter-spacing: 1px; > .btn:hover, .btn:focus cursor: pointer; > /* back button */ .btn-back color: hotpink; border-color: hotpink; > /* refresh button */ .btn-refresh color: orange; border-color: orange; > /* next button */ .btn-next color: greenyellow; border-color: greenyellow; >
Refresh Button
The first button I will be working with is the Refresh button. I am going to make the button’s border wider when it is clicked, and then narrow it again by adding a class to the button element.
So in my CSS I’ll add a keyframes at-rule with the animation steps and a class defining the animation style.
@keyframes blinkingBorder 0% border-width: 0.1em;> 50% border-width: 1em;> 100% border-width: 0.1em;> > .blink animation-name: blinkingBorder; animation-duration: 0.1s; animation-iteration-count: 1; >
What I am declaring with the blinkingBorder keyframes at-rule is that the border-width property should start and finish at 0.1em , and to grow to 1em in the middle of the animation.
Elements with the blink class should render the blinkingBorder animation for 0.1 seconds only 1 time. To make this come to life, we have to create a click event handler for the refresh button and add (and the remove) the blink class to it.
// When the HTML has finished loading. document.addEventListener('DOMContentLoaded', () => // Handle click event on the refresh button document.querySelector('.btn-refresh').addEventListener('click', e => handleRefreshClick(e)) >) const handleRefreshClick = (event) => const className = 'blink' // Animate the clicked button (event.target) // by adding the blink class for 100 milliseconds animateButton(event.target, className, 100) > const animateButton = (button, classNameAnimation, milliseconds) => // Remove the class if it exists button.classList.remove(classNameAnimation) // Add the class button.classList.add(classNameAnimation) // When the animation finishes, remove the class setTimeout(() => button.classList.remove(classNameAnimation) >, milliseconds) >
I wrote the class adding logic into the animateButton function so I can reuse it later with the other buttons. I’ll be adding a little more code to it later, though. So let’s see how this animation turned out on Codepen. Click on the Refresh button to test it.
Back Button
The second button I’ll be addressing is the Back button. What I want here is that when the button is clicked, I get like a courtain effect opening to the left. To achieve this behavior, I’ll first add some background CSS properties to the btn-back class, and use the linear-gradient CSS function.
.btn-back color: hotpink; border-color: hotpink; background: linear-gradient(90deg, hotpink 0 50%, transparent 50% 100%); background-size: 200%; background-position: 100%; >
What I’m declaring here is that the half of the button’s background should be hotpink, instead of transparent ( background: linear-gradient(90deg, hotpink 0 50%, transparent 50% 100%); ), that it should be 2 times wider than the button ( background-size: 200%; ), and that it should be positioned at the top-right button’s corner ( background-position: 100%; ) Next, I’ll set the CSS Animation at-rule and class.
@keyframes fillOutFrames 0% color: black; background-position: 0%; > 100% color: hotpink; background-position: 100%; > > .fillOut animation-name: fillOutFrames; animation-duration: 0.5s; animation-iteration-count: 1; >
This CSS is setting the animation to start with a black font color and a background position at the top-left corner, and end with a hotpink font color and a background position at the top-right corner. It last half a second and it runs once.
The trick here is to slide the button’s background to the left, which is half hotpink and half transparent, giving us the visual effect that it is filling out that hotpink color from the button. Lastly, I’ll set up the click button’s handler function in Javascript, which is pretty similar to the Refresh button’s code. You’ll see that the animateButton function is reused.
// When the HTML has finished loading. document.addEventListener('DOMContentLoaded', () => // Handle click event on the refresh button document.querySelector('.btn-refresh').addEventListener('click', e => handleRefreshClick(e)) // Handle click event on the back button document.querySelector('.btn-back').addEventListener('click', e => handleBackClick(e)) >) const handleBackClick = (event) => const className = 'fillOut' // Animate the clicked button (event.target) // by adding the fillOut class for 500 milliseconds animateButton(event.target, className, 500) >
Next Button
This one will be the same as the Back button, except that I’ll change the color, and that the background will slide from left to right, and the button will stay filled at the end of the animation. This will render a visual effect of the button filling in with a greenyellow color, from left to right.
To achieve the «stay filled at the end» part, what I’ll do is to add a new btn-next-final class to the button when the animation finishes.
So the CSS will look like this.
.btn-next color: greenyellow; border-color: greenyellow; background: linear-gradient(90deg, greenyellow 0 50%, transparent 50% 100%); background-size: 200%; background-position: 100%; > .btn-next-final color: black; background-position: 0%; > @keyframes fillInFrames 0% color: greenyellow; background-position: 100%; > 100% color: black; background-position: 0%; > > .fillIn animation-name: fillInFrames; animation-duration: 0.5s; animation-iteration-count: 1; >
The new javscript is very similar, but I will be adding a parameter to the animateButton function so it takes a new classNameFinal parameter, with an undefined defualt value. This will be the class that I will add to the button at the end of the animation.
// When the HTML has finished loading. document.addEventListener('DOMContentLoaded', () => // Handle click event on the refresh button document.querySelector('.btn-refresh').addEventListener('click', e => handleRefreshClick(e)) // Handle click event on the back button document.querySelector('.btn-back').addEventListener('click', e => handleBackClick(e)) // Handle click event on the next button document.querySelector('.btn-next').addEventListener('click', e => handleNextClick(e)) >) const handleNextClick = (event) => const className = 'fillIn' const classNameFinal = 'btn-next-final' // Animate the clicked button (event.target) // by adding the fillIn class for 500 milliseconds // and adding the btn-next-final class at the end of the animation animateButton(event.target, className, 500, classNameFinal) > const animateButton = (button, classNameAnimation, milliseconds, classNameFinal = undefined) => // Remove the class if it exists button.classList.remove(classNameAnimation) // Add the class button.classList.add(classNameAnimation) // When the animation finishes, remove the class // and add the final class, if provided setTimeout(() => button.classList.remove(classNameAnimation) if (classNameFinal !== undefined) button.classList.add(classNameFinal) >, milliseconds) >
Ok, let’s see how is this button behaving on Codepen. Click the Next button to see the animation.
Ok! I’m sure there are many more better ways to animate this buttons, so if you are in the mood to comment, please do so! Thank you for reading!
20 CSS Button Click Effects
Collection of hand-picked free HTML and CSS button click effect code examples from codepen and other resources. Update of February 2019 collection. 6 new items.
Related Articles
Author
Links
Made with
About a code
Subtle Button
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About a code
Button Click Pulsing Effect
Pure CSS button style. Pulsing effect on click with no JavaScript.
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About a code
Copy Button Click Effect
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About the code
Material UI Stretch Button
Delightful Material UI stretch button built by clipping paths.
Compatible browsers: Chrome, Firefox, Opera, Safari
Author
Links
Made with
About the code
SCSS Beveled Buttons
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About the code
Ripple Button with Few JavaScript
Just a simple retro’ish ripple button with few Javascript codes for smoother animation.
Compatible browsers: Chrome, Firefox, Opera, Safari
Author
Links
Made with
About the code
CSS-only Ripple Effect Button
A CSS-only toggle button with dynamic inverse text colour. The animated radial-gradient is achieved by scaling a pseudo element that sits in front of the text. The dynamic text colour uses mix-blend-mode: difference .
Compatible browsers: Chrome, Firefox, Opera, Safari
Author
Links
Made with
About the code
Sweet Little Button Mixin
Compatible browsers: Chrome, Firefox, Opera, Safari
Author
Links
Made with
About the code
Black Biometirics Login Button
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About the code
Delete Button with Micro-Interactions
Playing with micro-interactions, adding some micro-interactions on a delete button/trash icon.
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About the code
Add To Collection Button
Simple animation if you add smth to a collection for example.
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About the code
Bubbly Button with Click Animation
Made the bubbles using radial-gradient for background-image . This property is so cool that you can draw many things without adding extra div s or pseudo elements ( ::before and ::after )
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari