ScreenshotNeo

BlogGuides

CSS Image Effects: Examples and a Quick Animation Guide

Explore practical CSS image effects, filter combinations, hover transitions, and keyframe animation, with reduced-motion support and runnable examples.

By the ScreenshotNeo team4 October 20268 min read

Use filter to change an image’s rendered appearance, such as its color, contrast, blur, or shadow. Use backdrop-filter to affect what shows through a translucent element behind it. For a hover or keyboard-focus change, use a transition; for a staged or repeating effect, use keyframes. The examples below are ready to adapt and include reduced-motion handling.

1. Choose the effect that matches the result

CSS image effects can change an image’s tone, move it, combine its colors with other layers, or shape its visible silhouette. Those are different jobs, so start with the property that matches the effect you want.

Goal Use Example
Change an image’s color or tone filter Grayscale, sepia, blur, brightness
Blur or otherwise affect what is behind a translucent element backdrop-filter Frosted-glass panel over an image
Move, rotate, or scale an image transform Small zoom on hover
Combine colors across layers mix-blend-mode or background-blend-mode Blend an image with its backdrop
Change the visible silhouette clip-path or a mask Circle, polygon, or masked reveal

filter operates on the element itself. backdrop-filter operates on the area behind an element, so the element needs a translucent background for that treatment to show through. These properties are not interchangeable.

2. CSS filter effects examples

CSS filter functions include blur(), brightness(), contrast(), drop-shadow(), grayscale(), hue-rotate(), invert(), opacity(), saturate(), and sepia(). Combine functions in one filter declaration. The order matters: each function is applied after the ones before it.

<img class="photo photo--warm" src="portrait.jpg" alt="A person standing in a garden">
<img class="photo photo--soft" src="garden.jpg" alt="A garden softened with blur">
<img class="photo photo--shadow" src="cutout.png" alt="A transparent image with a shadow">
.photo {
  display: block;
  max-width: 100%;
  height: auto;
}

/* Adjust tone with a sequence of filters. */
.photo--warm {
  filter: sepia(25%) saturate(125%) contrast(105%);
}

/* Blur the image itself. */
.photo--soft {
  filter: blur(3px);
}

/* The shadow follows transparent edges in the source image. */
.photo--shadow {
  filter: drop-shadow(0 4px 10px rgb(0 0 0 / 25%));
}

For a shadow around a rectangular box, box-shadow is often the simpler choice. drop-shadow() is useful when the source image has transparent areas and the shadow should follow its visible shape.

More combinations to try:

.photo--mono {
  filter: grayscale(100%) contrast(115%);
}

.photo--bright {
  filter: brightness(1.08) saturate(1.15);
}

.photo--inverted {
  filter: invert(100%);
}

.photo--hue-shift {
  filter: hue-rotate(35deg) saturate(120%);
}

Values are design choices, not universal presets. Check the image at its displayed size and against the page background. Heavy blur can obscure useful detail, while aggressive contrast, inversion, or color shifts can make an image hard to interpret.

3. Animate an image on hover and keyboard focus

A transition eases a property between two states. This is a good fit for an image that changes when someone hovers or focuses its control. The image below is inside a link, so the interaction is keyboard accessible and has a visible focus indicator.

<a class="photo-link" href="/gallery" aria-label="Open the photo gallery">
  <img class="photo photo--reveal" src="portrait.jpg" alt="A person in a sunlit garden">
</a>
.photo-link {
  display: inline-block;
  overflow: hidden;
}

.photo--reveal {
  display: block;
  filter: grayscale(100%);
  transform: scale(1);
  transition: filter 250ms ease, transform 250ms ease;
}

.photo-link:hover .photo--reveal,
.photo-link:focus-visible .photo--reveal {
  filter: grayscale(0%);
  transform: scale(1.03) rotate(-1deg);
}

.photo-link:focus-visible {
  outline: 3px solid currentColor;
  outline-offset: 4px;
}

Keep the movement modest so the crop does not jump unexpectedly. If the image is purely decorative and not interactive, avoid making it look like an interactive control. If the image itself is intentionally focusable, provide an appropriate keyboard interaction and focus treatment rather than relying on hover alone.

4. How to animate an image with CSS keyframes

Use a transition for a state change, such as hover to focus. Use @keyframes when you need a sequence, intermediate stages, or a repeating animation.

<img class="photo photo--animated" src="landscape.jpg" alt="A landscape with rolling hills">
@keyframes gentle-zoom {
  from { transform: scale(1); }
  to   { transform: scale(1.04); }
}

.photo--animated {
  display: block;
  max-width: 100%;
  height: auto;
  animation: gentle-zoom 3s ease-in-out infinite alternate;
}

@media (prefers-reduced-motion: reduce) {
  .photo--animated {
    animation: none;
  }
}

The animation alternates between its start and end scale. The reduced-motion rule keeps the image in a static, useful state for visitors who request less motion. Motion should be decorative and nonessential; don’t make animation the only way to reveal important information.

5. Use backdrop blur, blending, and clipping for different treatments

Blur the area behind a translucent panel

This example blurs the image visible behind the caption panel, not the image itself. The translucent background lets the backdrop treatment show through.

<figure class="photo-card">
  <img src="coast.jpg" alt="Waves breaking on a rocky coast">
  <figcaption>Coast at dusk</figcaption>
</figure>
.photo-card {
  position: relative;
  width: min(100%, 36rem);
  margin: 0;
  overflow: hidden;
}

.photo-card img {
  display: block;
  width: 100%;
  height: auto;
}

.photo-card figcaption {
  position: absolute;
  inset: auto 1rem 1rem;
  padding: 0.75rem 1rem;
  color: white;
  background: rgb(0 0 0 / 35%);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

The prefixed declaration is included as a compatibility fallback for environments that need it. Check the current support requirements for your audience before relying on a newer effect. If the backdrop blur is unavailable, the translucent background still provides contrast for the caption.

Blend colors across layers

Blend modes control how colors combine with layers beneath an element. They are useful for color treatments that ordinary filters do not express as directly. The visual result depends on the image and background, so inspect the actual combination.

.photo--multiply {
  mix-blend-mode: multiply;
}

Shape the visible image

Clipping changes which part of the image is visible; it does not recolor the image. For example, a circular crop can use clip-path:

.photo--circle {
  width: 12rem;
  aspect-ratio: 1;
  object-fit: cover;
  clip-path: circle(50% at 50% 50%);
}

Use a mask when the reveal needs graded transparency or a more elaborate alpha or luminance shape. Keep meaningful image content and alternative text useful even when the visual crop changes.

6. Apply an effect to an image you capture

If you need a screenshot of a page that contains these effects, the screenshot captures the rendered result. For repeatable output, give the page enough time to load its image and styles, choose the required viewport, and account for animations. A moving image can be captured at different points in its animation; prefer a static state or a deliberate wait when the frame matters.

For local development, open the page in a browser and capture it after the assets have loaded. If you are automating captures, check whether your tool waits for fonts, images, and network activity, and set a fixed viewport so the responsive layout is predictable. A screenshot API can capture the rendered page without requiring you to build and maintain browser automation infrastructure.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. One GET request returns an image or PDF. For a WebP screenshot of the demo page, replace the example URL with your own:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for request options. The same capture can be requested with Python or Node.js:

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));

Cookie banners are accepted and removed before the shot, along with known newsletter popups and chat widgets; each cleanup step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Sign up for 1,000 free screenshots a month, no card required.

7. Troubleshooting CSS image effects

Symptom Likely cause Fix
The image does not change on hover The selector does not match the hovered element, or another rule overrides filter. Inspect the computed styles and ensure the hover selector targets the image or its parent. Check selector specificity and later declarations.
The effect jumps instead of easing The changed property is missing from transition, or the transition rule is only declared in the hover state. Put transition on the base state and list the property that changes.
Keyboard users cannot trigger the reveal The example responds only to :hover. Use a keyboard-operable control and add a :focus-visible state with a visible focus indicator.
The shadow is a rectangle box-shadow is applied to a box that includes transparent pixels. Use filter: drop-shadow() when the shadow should follow the nontransparent image shape.
The backdrop looks unchanged The element is opaque, has no content behind it, or the browser does not support the effect. Use a translucent background, position content behind the panel, and retain a readable fallback background.
The image looks washed out or too dark Filter values compound, and function order affects the result. Reduce intensity, try one function at a time, then combine in the intended order.
The animation still moves for a reduced-motion visitor The media query misses the animated selector or is overridden later. Verify the selector and cascade, and ensure the static state remains informative.
Different screenshots show different frames The capture occurs at varying points in a running animation. Disable decorative animation for capture, use a fixed state, or coordinate the capture timing.

8. Performance, reliability, and cost considerations

These examples describe CSS behavior; no browser benchmark is implied. The practical cost depends on the page, image dimensions, effect, and device. Keep large images sized appropriately, avoid stacking effects without a visual reason, and check animation smoothness on the devices and browsers your audience uses. Prefer a static state when motion does not add meaning.

For reliable screenshot automation, use stable source assets, fixed viewports, and an explicit capture wait that matches the page’s loading behavior. If exact animated timing is not part of the deliverable, remove the time-varying state. When using an API, factor request volume and plan limits into cost; ScreenshotNeo lists 1,000 free monthly shots with no card, then plans from $5 for 3,000. Its billing headers identify whether a response was billed.

9. FAQ

Can CSS filters permanently edit the original image file?

No. A CSS filter changes how the browser renders the element; it does not rewrite the source image.

Should I use a transition or keyframes?

Use a transition when a state changes, such as hover or focus. Use keyframes for a sequence, intermediate states, or a repeated cycle.

Does blur affect the image or the background?

filter: blur() blurs the element. backdrop-filter: blur() blurs the visible area behind the element.

How do I capture a consistent screenshot of an animated image?

Capture a static state or control when the capture happens. Otherwise, the animation may be at a different point on each request.

References