A fade-in animation is one of the most used effects in web UI, appearing in modals, toasts, hero sections, dashboard cards, and almost every entrance animation in modern interface design.
Loading Animation Builder…
Control opacity start value, duration, and easing
Preview the exact fade-in timing before copying
Generates both @keyframes and animation property
Supports delayed fade-in for staggered sequences
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 fade-in animation works by transitioning the opacity CSS property from 0 (fully transparent) to 1 (fully opaque) over a defined duration. At the CSS level, this requires a @keyframes rule that declares opacity: 0 at 0% and opacity: 1 at 100%, and an animation property on the target element that references the keyframe name and sets the duration, easing, delay, and fill-mode. Because opacity is one of only two properties (the other being transform) that the browser handles entirely on the GPU compositor thread, the browser runs the fade-in animation without triggering layout recalculation or paint operations on each frame. This makes opacity-based fade-ins one of the most performant animation types available, reliable at 60 frames per second even on lower-end mobile hardware where heavier animations would visibly stutter. The same property choice also means a fade-in animation does not block interaction on the page: a user can click a button while a sibling element is fading in, and the click is registered immediately without waiting for the animation to finish.
Choosing the right easing function for a fade-in changes how the animation feels at a perceptual level even when the duration is identical. An ease-out easing, which starts fast and slows toward the end, feels natural for appearing elements because it mimics how objects come into focus: quick initial appearance followed by a gentle settling at the final state. A linear easing fades in at a constant rate, which can feel mechanical and is rarely the right choice for UI elements except in rare cases like a precise progress bar fill. An ease-in easing, which starts slow and accelerates toward the end, makes elements feel like they are reluctantly appearing and can create a subtle sense of anxiety in the user that becomes obvious only when the animation is compared side by side with an ease-out version. For most fade-in use cases, ease-out with a duration between 200 and 400 milliseconds produces a result that feels immediate without being jarring.
Pairing a fade-in with a small transform creates the subtle entrance effect that UI frameworks use for modals, toasts, and notifications. Adding translateY(-10px) at the 0% keyframe and translateY(0) at the 100% keyframe alongside the opacity change produces an upward float that signals the element has come from above the viewport edge or a parent container. A translateY(10px) to translateY(0) produces a rise from below, common for bottom sheets, action menus, and toast notifications on mobile interfaces. A translateX(-12px) to translateX(0) produces a slide from the left, suitable for inline alerts and form validation messages. The transform adds no additional performance cost because transform, like opacity, runs on the compositor thread, and the combined effect requires only a few extra characters in the 0% stop of the @keyframes rule, making it a high-leverage upgrade to the basic fade pattern.
Fill-mode is the most commonly forgotten setting in fade-in animations, and forgetting it produces the classic pre-animation flash bug that ships to production more often than any other CSS animation defect. Without animation-fill-mode: both, an element with a positive animation-delay shows in its base opacity (typically 1) during the delay period, then jumps to opacity 0 the moment the animation starts, then fades back to 1 over the duration. The result is a visible flash of the element followed by a fade-in, which looks like an unintended double exposure rather than a polished entrance. Setting animation-fill-mode: both makes the element hold the 0 percent keyframe state throughout any delay and the 100 percent state after the animation completes, eliminating the flash without requiring any JavaScript or additional CSS classes.
Set the starting opacity (usually 0), end opacity (usually 1), duration in milliseconds, and easing. Add a delay for staggered sequences. Copy the complete fade-in CSS when the preview looks right.
Step-by-step guide to css fade in animation:
Set opacity and duration
Set the starting opacity to 0 and the end opacity to 1 for a standard fade-in, or to 0.4 and 1 for a softer reveal that never fully hides the element. Choose a duration based on the role of the element: 200ms for quick UI feedback on tooltips and inline alerts, 400ms for a standard entrance on cards and modals, and 600ms for a slower hero-level reveal that should feel deliberate and premium rather than instant.
Choose an easing function
Select ease-out as the default choice for an entrance fade, which feels natural because it mimics how objects come into focus in the physical world. Adjust the cubic-bezier curve for a custom timing if no keyword option produces the right feel, dragging the two control points to shape the acceleration profile. Avoid linear for fade-ins unless you have a specific reason, because linear timing makes the fade feel mechanical and uniform rather than organic.
Add a transform for depth (optional)
Enable the optional translateY setting to add a vertical float to the fade, creating the polished entrance effect used by most modern UI frameworks. A value of -10px to 0 creates an upward entrance that suggests the element has arrived from above the viewport edge, while 10px to 0 creates a rise from below suitable for toasts and bottom sheets. The transform adds no measurable performance cost because both opacity and transform run on the compositor thread.
Copy the generated CSS
Click Copy Code to copy the @keyframes fade-in block plus the matching animation property declaration to your clipboard, then paste both into your stylesheet at the appropriate selector. Apply the animation class to the target element and verify in the browser that the fade behaves identically to the preview. Add the prefers-reduced-motion override block if it was not already included in the generated output, since fade animations should respect user motion preferences.
Common situations where this approach makes a real difference:
Modal dialog entrance
A product developer applies a 300ms ease-out fade-in combined with a translateY(-12px) to translateY(0) float to a modal dialog component used throughout the application. The upward entrance signals that the modal is overlaying the current page content rather than replacing it, matching the spatial hierarchy expected for layered UI. The animation plays the moment the modal's open class is added by the trigger handler, and animation-fill-mode: both prevents any flash of the unstyled modal before the transition begins. The same animation class is reused across alert modals, confirm modals, and full-screen dialogs to maintain consistent motion across the product surface.
Dashboard card stagger
A SaaS dashboard UI has six metric cards that should appear sequentially on page load to create the perception of fast rendering even when all six cards finish loading at roughly the same time. A developer generates a single fade-in-up @keyframes block and applies it to each card with animation-delay values from 0ms to 250ms in 50ms increments using nth-child selectors on the card container. The staggered sequence guides the user's eye from top-left to bottom-right across the grid, finishing within roughly 700 milliseconds of the initial render. The technique is purely CSS, requires no JavaScript orchestration, and works regardless of whether the data is server-rendered or fetched on the client.
Toast notification appearance
A notification component uses a 200ms ease-out fade-in with a translateY(8px) to translateY(0) rise-from-below effect that matches the mobile native pattern of toasts appearing at the bottom of the screen. The short duration makes the toast feel responsive to the user action that triggered it, signaling immediate acknowledgment of a save, submit, or upload. The animation runs once, the toast stays visible for three seconds while the user reads it, then a separate fade-out animation plays before the element is removed from the DOM by the dismissal handler. The exit animation uses the reverse translate and a slightly shorter 150ms duration to keep the dismissal feeling responsive rather than dragging.
Hero section content reveal
A marketing page developer creates a sequence of three fade-ins for the hero section: the headline at 0ms delay, the subheadline at 200ms, and the CTA button at 400ms. Each uses a 500ms ease-out duration for a premium, deliberate feel appropriate for the above-the-fold brand moment that sets the tone for the entire visit. The staggered timing guides the visitor's eye from the headline down to the call to action in a natural reading order, increasing CTA click-through on the page measurably compared to a version where all three elements appeared at once. The fill-mode: both setting ensures none of the elements flash visible before their scheduled animation starts.
Use this when you need a fade-in effect for a modal, toast, card, hero section, or any element that should appear gradually rather than snapping into view.
Get better results with these expert suggestions:
Use will-change: opacity sparingly for complex layouts
Adding will-change: opacity to an element before a fade-in animation tells the browser to promote the element to its own GPU compositor layer in advance, which can prevent a layer promotion hitch at the start of the animation on complex pages with many DOM nodes. Remove will-change after the animation completes to free the GPU memory, as leaving it on static elements wastes resources and can actually degrade performance on pages where many elements have it set unnecessarily. Use will-change as a targeted optimization for animations you have measured to be janky, not as a default.
Set initial opacity in your CSS, not just in @keyframes
For elements that fade in on page load, set opacity: 0 as a base style on the element selector in addition to declaring it at the @keyframes 0 percent stop. This prevents a brief flash of the fully visible element before the browser applies the animation, which can happen on slow connections or when the stylesheet loads after the initial HTML render. The base style is overridden by animation-fill-mode: forwards or both once the animation starts and completes, so the redundant opacity declaration does not interfere with the final state.
Match fade-in duration to content weight
Heavier, denser content like tables, long text blocks, and image grids warrants slightly longer fade-in durations than lightweight elements like tooltips, badges, and chips. A 400ms fade-in on a table feels appropriately measured and gives the eye time to register the new content. A 400ms fade-in on a tooltip feels sluggish because the small element does not require the same perception time. Match the perceived weight of the content to the duration, treating element size and visual density as the primary inputs to the timing decision rather than picking a single duration for everything.
Test fade-in animations with the page in a slow-CPU throttle
Open Chrome DevTools Performance panel, set CPU throttle to 4x or 6x slowdown, and reload the page to simulate the experience on lower-end devices. On throttled hardware, delayed fade-ins sometimes appear to start late because the initial render takes longer than on the development machine, pushing the animation start relative to when the user expects to see content. Reduce delays if this occurs, or use the IntersectionObserver pattern to trigger animations on scroll rather than on a fixed delay, which makes the timing relative to when the element is actually visible rather than to page load.
More use-case guides for the same tool:
Open the full Animation Builder — free, no account needed, works on any device.
Open Animation Builder →Free · No account needed · Works on any device