A pulse animation cycles an element between two visual states to draw the user's eye to something that needs attention.
Loading Animation Builder…
Scale pulse for a breathing or heartbeat feel
Opacity pulse for notification badge flashing
Control rhythm speed from slow ambient to fast urgent
Generates infinite-loop CSS with alternate direction option
Drop the Animation Builder into any page — blog post, product docs, intranet, school portal — with a single line of HTML. Your visitors get the full tool, processed entirely in their browser. No backend, no uploads, no signup.
Embed code
<iframe
src="https://www.fixtools.io/css-tool/animation-builder?embed=1"
width="100%"
height="780"
frameborder="0"
style="border:0;border-radius:16px;max-width:900px;"
title="Animation Builder by FixTools"
loading="lazy"
allow="clipboard-write"
></iframe>Attribution-friendly: a small "Powered by FixTools" link appears in the embed footer.
A pulse animation achieves one goal: drawing the user's eye to a specific element without requiring them to interact with it. Unlike an entrance animation that plays once, a pulse animation repeats continuously, creating an ambient signal that persists until the user takes action or the condition changes. The visual mechanism is cycling between two states: the element appears to breathe or beat because the transition between states is smooth in both directions. The design choice is which property to cycle. Scale cycling from 1.0 to 1.05 creates a gentle breathing effect visible on medium and large elements. Opacity cycling from 1.0 to 0.6 creates a flashing effect suitable for small badges and counts where scale changes would be too subtle.
Two CSS implementations produce pulse animations. The first uses animation-direction: alternate with two keyframe stops: 0% at the base state and 100% at the pulsed state. The alternate direction plays the keyframes forward on odd iterations and backward on even iterations, creating a smooth cycle without requiring a return keyframe. This produces a gentle, even pulse. The second approach uses four explicit keyframe stops: 0% at base, 50% at the pulsed state, and 100% back at base, without using alternate. This gives more control over the hold time at each state, which is useful when you want the element to briefly hold its pulsed state before returning. The four-stop approach can also include a hold at 50% by adding a stop at 60% with identical values.
Choosing between scale and opacity pulses depends on the element and the urgency of the signal. Scale pulses work for notification dots, online status indicators, and CTA buttons in empty states, where a subtle breathing motion signals that the element is active without alarming the user. Opacity pulses work for unread count badges, live data feed indicators, and error banners that need to remain visible to users even as the page content updates. For genuinely urgent signals, a combined scale and opacity pulse at a short duration (under 0.8s) creates a more insistent effect, but this should be reserved for actual errors or time-sensitive states, not ambient activity indicators.
Pulse animation density across an interface determines whether the technique feels purposeful or chaotic. A single pulsing element on a page reliably attracts attention because it is the only thing in motion. Two or three pulsing elements at the same time split the user's focus and reduce the effectiveness of each. Four or more simultaneous pulses produce a noisy interface where nothing reads as urgent and the user begins to ignore the motion entirely. Treat pulse animations as a finite attention budget: each one costs a unit of focus that other interface elements cannot reclaim. When introducing a new pulsing indicator, audit the page to confirm no other elements are already pulsing in the same view, and consider replacing or pausing existing pulses if the new signal is higher priority.
Choose between scale pulse and opacity pulse. Set the minimum and maximum values for each cycle. Adjust duration to match the urgency: 1.5s for calm, 0.6s for urgent. Enable alternate direction for smooth reversal. Copy the code when the rhythm is right.
Step-by-step guide to css pulse animation:
Choose scale or opacity pulse
Select scale pulse for a breathing effect on icons and buttons, or opacity pulse for a flashing effect on badges and status indicators.
Set the pulse range
For scale: set the base scale (1.0) and the peak scale (1.04 to 1.08 for subtle, 1.15 to 1.2 for obvious). For opacity: set base (1.0) and minimum (0.5 to 0.7 for subtle, 0.2 to 0.4 for sharp).
Set duration and direction
Set duration to 0.6s for urgent, 1s for standard, 1.5s to 2s for calm ambient. Enable alternate direction for smooth cycling without a jump at the end of each iteration.
Copy and add a reduced-motion override
Click Copy Code. After pasting, add a @media (prefers-reduced-motion: reduce) block that sets animation: none for the pulse class.
Common situations where this approach makes a real difference:
Live data feed indicator
A financial dashboard shows a green dot next to each ticker that is receiving live price updates. The dot uses a slow 1.5-second opacity pulse from 1.0 to 0.5 to signal that data is streaming. The pulse pauses when the WebSocket disconnects and a reconnecting class replaces it with a faster 0.7-second pulse to signal the different state.
Unread notification badge
A messaging app sidebar icon shows an unread count badge that uses a 1-second scale pulse from 1.0 to 1.15 when new messages arrive. The pulse starts when the count increments via a class added in the message handler, and stops automatically after three iterations using animation-iteration-count: 3. This draws attention at the moment of arrival without running the animation indefinitely.
CTA button in an empty state
A project management app's empty project list shows a Create Project button with a slow 2-second breathing scale pulse from scale(1) to scale(1.04). The subtle pulse draws the eye to the primary action without feeling urgent. The animation runs only when no projects exist; once a project is created, the pulse class is removed permanently for that user session.
Error state requiring immediate attention
A form shows an error banner when a payment fails. The banner uses a fast 0.6-second opacity pulse between 1.0 and 0.7 combined with a red background. The combined urgency of the colour and fast pulse signals that user action is required. The pulse runs for five iterations (animation-iteration-count: 5) then stops, leaving the static red banner visible without the ongoing distraction of continued flashing.
Use this for notification badges, live data indicators, error states that need ongoing attention, and any element that should signal activity or urgency without interrupting the user's current task.
Get better results with these expert suggestions:
Use animation-iteration-count to limit pulses to a specific count
For event-triggered pulses, set animation-iteration-count: 3 to 5 rather than infinite. The element pulses a defined number of times to signal the new event, then stops cleanly. This is less distracting than infinite looping for events that should attract initial attention but not demand ongoing focus.
Pair pulse with a box-shadow glow only on small elements
Adding an animated box-shadow alongside a scale pulse creates a glow effect that reinforces the pulse visually. Keep this to elements under 40px in diameter. On larger elements, an animated box-shadow triggers paint on every frame and causes performance issues. For large elements, stick to transform and opacity only.
Prefer opacity pulse over scale pulse for elements inside flex or grid containers
A scale pulse on an element inside a flex row or grid cell can cause visual collision with adjacent elements when the element grows. Opacity pulses have no layout effect and are always safe inside any container type. Use opacity for badges, counts, and indicators; reserve scale for standalone elements with clear surrounding space.
Stop the pulse immediately when the underlying condition clears
A notification badge should stop pulsing the moment the user views the notification, not on the next page reload. Listen for the state change in your component and remove the pulsing class at the same time as clearing the unread count. Leaving a pulse running after the condition has cleared confuses users about whether new activity has occurred.
More use-case guides for the same tool:
Other tools you might find useful:
CSS Transform Generator
Build transform values to use inside your keyframes.
CSS Filter Builder
Generate filter effects to animate alongside transforms.
HTML Element Builder
Build the HTML element you want to apply your animation to. Pause animations when the tab is backgrounded using requestAnimationFrame visibility checks. Use animation-play-state to pause pulses programmatically when needed. Always pair pulses with prefers-reduced-motion so users sensitive to motion can opt out. The pulse pattern is also useful for loading indicators where the rhythm communicates ongoing activity without specific progress. Reduce pulse intensity for status indicators where subtlety is more important than visibility.
Open the full Animation Builder — free, no account needed, works on any device.
Open Animation Builder →Free · No account needed · Works on any device