Adding smooth animations to your website is simple with the CSS @keyframes at-rule.
In this tutorial, I’ll show you how to create a clean pop in effect using CSS keyframe animation. This technique is great for buttons, modals, or any element you want to draw attention to.
Understanding the Pop In Effect
The pop in effect makes an element smoothly scale from small to full size while fading in. It gives your UI a subtle animation that feels polished without being distracting.
With CSS keyframes, you define what happens at different stages of the animation, such as 0% (the start) and 100% (the end).
Step-by-Step Implementation
Here’s the base animation code:
@keyframes pop-in {
0% {
opacity: 0;
transform: scale(0.1);
}
100% {
opacity: 1;
transform: scale(1);
}
}
Apply it to any element with a class:
.pop-in-element {
animation: pop-in 0.5s ease-out;
}
How to Use
- Add the class
pop-in-elementto your HTML element. - Adjust the duration (
0.5s) to make the effect faster or slower. - Change the easing function (
ease-out,linear,ease-in-out) to experiment with the feel. - Raise the starting scale for a subtler pop.
scale(0.1)is dramatic; something likescale(0.9)reads as a gentle settle, which tends to suit buttons and modals better than a full zoom.
Customization Ideas
You can make the pop in animation more unique by combining properties like this:
@keyframes pop-in-bounce {
0% { opacity: 0; transform: scale(0.1); }
60% { opacity: 1; transform: scale(1.1); }
100% { transform: scale(1); }
}
You can also get the overshoot without the extra keyframe. A cubic-bezier() with a y value above 1 pushes the scale past 1 and lets it settle back, so the original two-keyframe pop-in gets a bounce for free:
.pop-in-element {
animation: pop-in 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}
To pop in from a direction, add translateY() or translateX() next to the scale in the 0% keyframe, for example transform: translateY(12px) scale(0.9);.
Staggering Multiple Elements
Give each element a slightly longer animation-delay to get a cascade:
.pop-in-element {
animation: pop-in 0.4s ease-out both;
}
.pop-in-element:nth-child(2) { animation-delay: 0.05s; }
.pop-in-element:nth-child(3) { animation-delay: 0.1s; }
.pop-in-element:nth-child(4) { animation-delay: 0.15s; }
The both keyword is the part that matters. It sets animation-fill-mode, and without it each delayed element sits at full size during its delay, then jumps down to the 0% keyframe the moment its animation starts. With both, the element holds the 0% state during the delay and keeps the 100% state after it finishes.
Respect Reduced Motion
Some people turn on reduced motion in their operating system because scaling and zooming animations make them feel sick. The prefers-reduced-motion media query lets you honor that. A good compromise is to keep the fade and drop the scale:
@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
.pop-in-element {
animation-name: fade-in;
}
}
prefers-reduced-motion works in Chrome 74, Firefox 63, and Safari 10.1 and later.
Popping In New Elements With @starting-style
Keyframes run whenever the class is applied. If you want an element to pop in the moment it’s added to the page, like a toast or a new list item, newer CSS has a cleaner option: @starting-style. It defines the values a transition starts from on an element’s first render.
.toast {
transition: opacity 0.3s ease-out, transform 0.3s ease-out;
}
@starting-style {
.toast {
opacity: 0;
transform: scale(0.9);
}
}
@starting-style is supported in Chrome 117, Firefox 129, and Safari 17.5. Browsers without it simply show the element without the transition, so it fails safely.
Live Demo
👉 See this pop in effect on CodePen
FAQ: Pop In Effect with CSS
What is a pop in effect in CSS?
A pop in effect is an animation where an element scales up and fades into view using CSS keyframes.
Can I add the pop in effect to multiple elements?
Yes, just apply the same class to each element, or use delays to stagger them.
Does the pop in animation work on all browsers?
Yes. Every current browser supports CSS keyframe animations without a prefix, going back to Chrome 43, Firefox 16, and Safari 9. The @starting-style version above needs newer browsers, but falls back to no animation rather than breaking.
Final Thoughts
The CSS pop in effect is a quick way to make your UI feel more dynamic. By tweaking duration, easing, and transforms, you can create unique effects that match your site’s style. Just add the both fill mode when you stagger, and a reduced-motion fallback before you ship.
If you want to explore more, check out MDN’s keyframe animation guide and CSS-Tricks for deeper dives.
Have your own take on the pop in animation? Share your example in the comments!
but seems to mee, that the code from coderguy is the right way!
WOW Man, works perfectly! Thanks for that!!!
Hi coderguy,
i try your code but it doesn’t work…
Bad code.. right one:
@keyframes pop-in {
0% { opacity: 0;transform: scale(0.1); }
100% { opacity: 1;transform: scale(1); }
}
@-webkit-keyframes pop-in {
0% { opacity: 0;-webkit-transform: scale(0.1); }
100% { opacity: 1;-webkit-transform: scale(1); }
}
@-moz-keyframes pop-in {
0% { opacity: 0;-moz-transform: scale(0.1); }
100% { opacity: 1;-moz-transform: scale(1); }
}