---
title: "CSS Entrance Animations: Fade & Slide-In Effects"
description: "Ten free CSS entrance animations with live previews: fade, slide, zoom, bounce, flip, blur, and roll. Perfect for scroll reveals. Pure CSS, copy-paste ready."
url: https://frontendhelpers.com/css-entrance-animations
updated: 2026-10-12
---

# CSS entrance animations

Fades, slides, zooms, bounces and flips for content arriving on screen — ideal for scroll reveals and page loads.

## The code for all 10 entrances, explained

Every effect above, with the markup to use and the complete CSS. Each one is self-contained: paste the CSS once, add the class, done.

### Fade In

The workhorse of UI motion. Animates opacity only — the cheapest property a browser can animate.

Markup

```html
<div class="fh-fade-in">Your content</div>
```

CSS

```css
.fh-fade-in {
  animation: fh-fadeIn 0.8s ease-out both;
}
@keyframes fh-fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
```

### Fade In Up

The most common scroll-reveal entrance. Pair it with an IntersectionObserver to trigger when the element scrolls into view.

Markup

```html
<div class="fh-fade-in-up">Your content</div>
```

CSS

```css
.fh-fade-in-up {
  animation: fh-fadeInUp 0.7s cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes fh-fadeInUp {
  from { opacity: 0; transform: translateY(28px); }
  to   { opacity: 1; transform: translateY(0); }
}
```

### Fade In Down

Natural for dropdown menus, toasts and notification banners that enter from the top.

Markup

```html
<div class="fh-fade-in-down">Your content</div>
```

CSS

```css
.fh-fade-in-down {
  animation: fh-fadeInDown 0.7s cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes fh-fadeInDown {
  from { opacity: 0; transform: translateY(-28px); }
  to   { opacity: 1; transform: translateY(0); }
}
```

### Fade In Left

Good for sidebars and staggered list items. Stagger with animation-delay: 0.05s per item.

Markup

```html
<div class="fh-fade-in-left">Your content</div>
```

CSS

```css
.fh-fade-in-left {
  animation: fh-fadeInLeft 0.7s cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes fh-fadeInLeft {
  from { opacity: 0; transform: translateX(-32px); }
  to   { opacity: 1; transform: translateX(0); }
}
```

### Fade In Right

Mirror of Fade In Left — ideal for right-hand drawers and chat panels.

Markup

```html
<div class="fh-fade-in-right">Your content</div>
```

CSS

```css
.fh-fade-in-right {
  animation: fh-fadeInRight 0.7s cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes fh-fadeInRight {
  from { opacity: 0; transform: translateX(32px); }
  to   { opacity: 1; transform: translateX(0); }
}
```

### Zoom In

A classic for modals and image lightboxes. Scale + opacity both run on the GPU compositor.

Markup

```html
<div class="fh-zoom-in">Your content</div>
```

CSS

```css
.fh-zoom-in {
  animation: fh-zoomIn 0.5s cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes fh-zoomIn {
  from { opacity: 0; transform: scale(0.6); }
  to   { opacity: 1; transform: scale(1); }
}
```

### Bounce In

The overshoot gives a playful, springy feel. Great for success states, badges and empty-state illustrations.

Markup

```html
<div class="fh-bounce-in">Your content</div>
```

CSS

```css
.fh-bounce-in {
  animation: fh-bounceIn 0.75s cubic-bezier(0.68, -0.55, 0.265, 1.55) both;
}
@keyframes fh-bounceIn {
  0%   { opacity: 0; transform: scale(0.3); }
  50%  { opacity: 1; transform: scale(1.05); }
  70%  { transform: scale(0.92); }
  100% { opacity: 1; transform: scale(1); }
}
```

### Flip In X

A 3D flip around the horizontal axis. The perspective() value controls how dramatic the depth feels.

Markup

```html
<div class="fh-flip-in-x">Your content</div>
```

CSS

```css
.fh-flip-in-x {
  animation: fh-flipInX 0.8s ease-out both;
}
@keyframes fh-flipInX {
  0%   { opacity: 0; transform: perspective(600px) rotateX(90deg); }
  40%  { transform: perspective(600px) rotateX(-18deg); }
  70%  { transform: perspective(600px) rotateX(8deg); }
  100% { opacity: 1; transform: perspective(600px) rotateX(0); }
}
```

### Blur In

A cinematic focus-pull. filter: blur() is heavier than transform, so reserve it for hero moments, not lists.

Markup

```html
<div class="fh-blur-in">Your content</div>
```

CSS

```css
.fh-blur-in {
  animation: fh-blurIn 0.9s ease-out both;
}
@keyframes fh-blurIn {
  from { opacity: 0; filter: blur(12px); }
  to   { opacity: 1; filter: blur(0); }
}
```

### Roll In

High-energy entrance for playful brands. Use sparingly — one rolling element per view is plenty.

Markup

```html
<div class="fh-roll-in">Your content</div>
```

CSS

```css
.fh-roll-in {
  animation: fh-rollIn 0.8s cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes fh-rollIn {
  from { opacity: 0; transform: translateX(-60px) rotate(-120deg); }
  to   { opacity: 1; transform: translateX(0) rotate(0); }
}
```

## What entrances are actually for

An entrance animation orients the eye. When new content appears — a modal, a search result, a section scrolling into view — a brief fade or slide tells the viewer where it came from and that it belongs there. Content that simply pops into existence forces the eye to re-scan the page to work out what changed.

Direction carries meaning. Content sliding _up_ reads as arriving from below (natural for scroll reveals); sliding _down_ suits notifications and dropdowns descending from the top; sliding in from a side fits drawers and panels. Matching the direction to where the element actually lives makes the motion feel explanatory rather than arbitrary.

## Triggering entrances on scroll

Most entrances are used as scroll reveals, and the right way to trigger them is `IntersectionObserver` — not a scroll listener. A scroll handler fires hundreds of times a second on the main thread and forces layout reads; IntersectionObserver does the visibility maths off-thread and calls you only when an element crosses the threshold you set.

Reveal each element once and then stop observing it. Content that re-animates every time it scrolls back into view is distracting and makes a page feel unstable — a mistake that's easy to make and easy to fix with `observer.unobserve(entry.target)`.

## Staggering, restraint and reduced motion

For lists and grids, a small `animation-delay` per item — around 50 to 80ms — creates a cascade that guides the eye through the sequence. Beyond about eight items the last ones take too long to arrive, so cap the stagger rather than multiplying indefinitely.

The most common failure is animating everything. If every section on a page fades in, the effect stops meaning anything and the page feels slow because content is perpetually arriving. Reserve entrances for content that genuinely appears in response to something, and honour `prefers-reduced-motion` so people who've asked for stillness get it.

## Frequently asked questions

### How do I trigger a CSS animation on scroll?

Use IntersectionObserver to add a class when the element enters the viewport, then unobserve it so it animates once. Avoid scroll event listeners — they fire constantly on the main thread and cause jank.

### Should entrance animations replay on every scroll?

No. Re-animating content each time it scrolls back into view is distracting and makes a page feel unstable. Reveal once and stop observing that element.

### How long should an entrance animation last?

Between 300 and 600 milliseconds for most entrances. Shorter feels abrupt for content arriving, longer delays the reader. Never gate an action the user must wait for behind an animation.

## Related categories

- [Fade In on Scroll with CSS Scroll-Driven Animations](https://frontendhelpers.com/css-fade-in-on-scroll): Reveal content on scroll with animation-timeline: view(), add an IntersectionObserver fallback, and never hide content that only JavaScript can show.
 
- [Attention](https://frontendhelpers.com/css-attention-animations): Pulses, shakes and celebratory effects
 
- [Loaders](https://frontendhelpers.com/css-loading-animations): Spinners, skeletons and progress bars
 
- [Text Effects](https://frontendhelpers.com/css-text-animations): Typewriter, gradient flow and glitch effects
