Free · Fast · Privacy-first

CSS Fixed Background Attachment and Parallax Effects

background-attachment: fixed creates a parallax effect where the background image stays anchored to the viewport while the page scrolls past it, producing the classic depth illusion that designers reach for on long marketing sites.

Generates background-attachment: fixed CSS with full background shorthand

🔒

Includes the transform-based parallax alternative for iOS compatibility

Explains the iOS Safari fixed background rendering limitation

Live preview of the fixed background effect in the browser

Cost
Free forever
Sign-up
Not required
Processing
In your browser
Privacy
Files stay local
FreeNo signupWhite-label

Add this Background Gen to your website

Drop the Background Gen 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.

  • Files stay 100% in the visitor's browser
  • Responsive — adapts to any container width
  • Free forever, no API key needed

Embed code

<iframe
  src="https://www.fixtools.io/css-tool/background-gen?embed=1"
  width="100%"
  height="780"
  frameborder="0"
  style="border:0;border-radius:16px;max-width:900px;"
  title="Background Gen by FixTools"
  loading="lazy"
  allow="clipboard-write"
></iframe>

Attribution-friendly: a small "Powered by FixTools" link appears in the embed footer.

Fixed Background Attachment: How It Works and Where It Fails

background-attachment: fixed changes the background positioning reference from the element to the viewport, and that single semantic shift is what produces the parallax effect. The background image stays anchored to the viewport coordinate system, so as the user scrolls, the element moves over a stationary background while the image appears to lag behind. This is the simplest parallax implementation possible: one property change. Set background: url(image.jpg) center/cover no-repeat fixed and the entire effect is active. The background-position is now relative to the viewport rather than the element, which means adjusting background-position shifts where the image aligns within the viewport. background-position: center positions the image at the viewport centre, not the element centre, and that distinction catches developers off guard the first time they wire up a fixed background.

The iOS Safari problem is significant enough to disqualify fixed attachment for most production sites targeting mobile users. On iOS Safari, background-attachment: fixed causes background images to render as if they are set to background-attachment: scroll instead, so the parallax effect simply does not happen. The reason is that iOS Safari paints the page on a separate compositor thread without access to fixed-position information during scrolling, which makes the fixed background behaviour undefined at scroll time. This bug has existed since iOS 1 and Apple has not fixed it across more than a decade of releases. Approximately 18 to 20 percent of mobile web traffic is iOS Safari depending on region, so shipping a parallax that quietly degrades to a static background on a fifth of your audience is rarely acceptable.

The performant alternative uses a fixed-position pseudo-element instead of the background-attachment property. Set the section to position: relative and overflow: hidden, then add a ::before pseudo-element with position: fixed, inset: 0, z-index: -1, and the background image using background-size: cover. This pins the background image to the viewport via position: fixed rather than background-attachment: fixed, and iOS Safari handles position: fixed pseudo-elements correctly during scroll. On desktop the result is visually identical to the simpler approach. The performance advantage is that the image sits on its own compositing layer and does not trigger main-thread repaints during scroll, unlike background-attachment: fixed, which can cause expensive repaint operations on large viewport-height elements with high-resolution textures.

Beyond raw mechanics, fixed backgrounds touch on accessibility concerns that deserve explicit handling. Parallax motion can trigger motion sickness for users with vestibular disorders, and the WCAG 2.1 success criterion on motion from interactions recommends offering a static alternative. Wrap the fixed background or pseudo-element in a @media (prefers-reduced-motion: no-preference) block so users who have requested reduced motion see a still image without the parallax lag. Combine this with a max-width media query that disables the effect under 768px, and you have a defensible production pattern: parallax for desktop users who have not opted out of motion, static background everywhere else, no broken effect on iOS Safari, and no unexpected paint cost on low-end mobile GPUs.

How to use this tool

💡

Select background-attachment: fixed or the transform-based pseudo-element alternative based on whether you need iOS Safari support. Enter an image URL, configure background-size, position, and the optional gradient overlay for text readability. The tool generates either the simple CSS fixed attachment declaration or the full pseudo-element parallax snippet with the matching container styles and reduced-motion fallback ready to paste into your stylesheet.

How It Works

Step-by-step guide to css fixed background attachment and parallax effects:

  1. 1

    Choose fixed or transform approach

    Select background-attachment: fixed if your site is desktop-only or if you accept a graceful degradation on iOS Safari. Pick the pseudo-element with position: fixed approach when you need genuine cross-device parallax including iOS Safari, smoother paint behaviour, and lower GPU pressure on mid-range mobile devices.

  2. 2

    Enter the image URL

    Paste the background image URL from your CDN or asset host. Use a high-resolution landscape image of at least 1600px wide, since fixed backgrounds render relative to the full viewport and any source smaller than the viewport will look blurry on retina laptops and large external displays.

  3. 3

    Set background-size and position

    Use background-size: cover with background-position: center for the vast majority of fixed backgrounds. Remember that position is viewport-relative with fixed attachment, so the same value frames the image differently than on a scrolling element. Adjust position only after previewing the effect at a representative scroll depth.

  4. 4

    Copy the generated CSS or snippet

    Copy the CSS declaration or the full pseudo-element snippet depending on the approach you picked. Add the @media (max-width: 768px) fallback to disable the effect on small screens and the prefers-reduced-motion media query to deliver a static background for users who have asked for less motion.

Real-world examples

Common situations where this approach makes a real difference:

Marketing site with a parallax hero section

A developer builds a marketing homepage with three full-viewport sections separated by fixed background images that create a layered scrolling story. They use the pseudo-element approach rather than background-attachment: fixed to ensure the parallax works on iOS Safari, which represents 22% of their site traffic according to analytics. The pseudo-elements use position: fixed with inset: 0 and are contained within overflow: hidden sections so each background only paints when its section is on screen. The effect delivers cinematic depth without pulling in a JavaScript parallax library.

Portfolio site with a fixed landscape photograph

A designer adds a fixed background photograph to a portfolio divider section between project case studies, using the simpler background-attachment: fixed declaration for code clarity. They apply background-attachment: fixed on desktop only with a media query disabling it below 768px so the iOS Safari rendering bug never appears to a user. The mobile experience falls back gracefully to a standard scroll background, the section still reads correctly without the parallax, and the overall CSS stays compact and readable for future designers who need to update the layout.

Developer reducing paint cost on an existing parallax section

An engineer notices the site has noticeable jank when scrolling past a fixed background section on mid-range Android phones reported in field data. The browser performance panel shows full-page repaints on every scroll frame, with paint durations exceeding the 16ms frame budget. They convert the background from background-attachment: fixed to the pseudo-element with position: fixed approach in under five minutes. After the change, the performance panel shows the background is composited on its own layer, scroll events no longer trigger repaints, and Core Web Vitals INP improves measurably on the affected page.

Accessibility-conscious developer adding reduced motion fallback

A developer adds the pseudo-element parallax effect but wraps the position: fixed declaration in @media (prefers-reduced-motion: no-preference) so the parallax only activates for users who have not opted out of motion. Users who have set the reduce-motion system preference see a static background image without the parallax movement, which respects the WCAG guidance on motion from interactions. The fallback uses the same image with background-size: cover and background-attachment: scroll, maintaining the visual design and brand impact while keeping the site usable for the audience that needs reduced motion.

Pro tips

Get better results with these expert suggestions:

1

Use the transform parallax approach for production

The pseudo-element with position: fixed works on every modern browser including iOS Safari and triggers GPU compositing rather than main-thread repaints during scroll. Use this pattern for any parallax effect on a site where mobile traffic is non-trivial, which today means almost every site. The code is slightly longer than the one-line background-attachment declaration but the cross-device result is consistent and the performance profile is better in DevTools.

2

Check paint profiler before deploying fixed backgrounds on large elements

Open Chrome DevTools Performance panel, start a recording, and scroll past the fixed background section at a normal speed. Check the Rendering section for paint events and the Layers panel for compositing layers. If the background causes full-page repaints on each scroll frame, it will cause visible jank on mid-range Android devices even when your desktop machine runs it smoothly. The composited pseudo-element approach should show minimal paint events and a dedicated layer for the background.

3

Combine with IntersectionObserver for section-scoped parallax

Trigger the parallax class only when the section is visible using IntersectionObserver with a small rootMargin so the layer attaches just before the section enters the viewport. This limits the fixed background rendering cost to when the element is on screen, which matters for pages with multiple parallax sections. Remove the class when the section leaves the viewport to free compositor resources and keep memory usage flat on long-scrolling marketing pages.

4

Test fixed backgrounds at different scroll speeds

Fixed backgrounds reveal their effect most at slow scroll speeds where the eye has time to register the lag between content and background. Fast scrolling can make the effect imperceptible, which makes designers second guess whether the feature works at all. If the parallax depth feels too subtle at normal scroll speeds, increase background-size slightly above cover so the image appears to move faster relative to the scrolling content and reinforces the depth illusion.

5

Add a media query to disable on mobile

Disable background-attachment: fixed at mobile breakpoints using @media (max-width: 768px) to switch to background-attachment: scroll. This avoids the iOS Safari rendering bug and reduces paint costs on devices with limited GPU memory.

6

Test the effect with reduced motion preference

Parallax effects can cause motion sickness for users with vestibular disorders. Wrap the fixed attachment in a @media (prefers-reduced-motion: no-preference) query so users who prefer reduced motion get a static background instead.

7

Use will-change sparingly with fixed backgrounds

Adding will-change: transform to an element does not improve background-attachment: fixed performance. For the pseudo-element approach, will-change: transform on the pseudo-element promotes it to its own layer, which helps on browsers where it would otherwise be painted on the main thread.

FAQ

Frequently asked questions

background-attachment: fixed changes the background image positioning reference from the element to the viewport, which is the entire mechanism behind the parallax effect. The image stays fixed relative to the browser window while the page scrolls past it, creating a depth illusion where the content layer floats over a stationary backdrop. The background-position values are interpreted relative to the viewport rather than the element, so center centres the image in the viewport, not the section. This creates a parallax effect where the element appears to scroll over a stationary background, and the effect works on desktop Chrome, Firefox, and Edge without any additional CSS or JavaScript.
iOS Safari renders fixed backgrounds as if they are background-attachment: scroll, so the parallax effect never appears. This is a longstanding WebKit bug related to how iOS Safari composites the page during scrolling: the fixed position context is not available during the scroll paint phase on iOS because the compositor thread does not see updated layout information until the scroll finishes. The bug affects every browser on iOS, since Chrome, Firefox, and Edge on iOS are all WebKit-based due to Apple App Store rules that previously prohibited third-party engines. Use the pseudo-element with position: fixed approach as a cross-device alternative that iOS Safari handles correctly.
Set the section to position: relative and overflow: hidden so the pseudo-element does not bleed into neighbouring sections. Add a ::before pseudo-element with position: fixed, inset: 0, z-index: -1, and the background image using background-size: cover. The pseudo-element is composited by the browser as a separate GPU layer, which avoids the main-thread repaints that background-attachment: fixed triggers during scroll. This approach works on iOS Safari, on every modern desktop browser, and performs better than background-attachment: fixed on every device class because the compositor reuses the cached layer texture rather than repainting on each scroll frame.
On many browsers, background-attachment: fixed prevents the element from being promoted to a compositing layer and forces the background to be repainted on every scroll frame as the viewport changes. This triggers expensive paint operations, particularly on large viewport-height elements with high-resolution textures, and the cost compounds when multiple fixed backgrounds appear on the same page. The paint cost depends on element size, image resolution, the browser version, and the device GPU. The pseudo-element position: fixed alternative sidesteps the issue entirely by compositing the background on a dedicated GPU layer independently of the scrolling content layer.
Use a media query to reset background-attachment to scroll at your mobile breakpoint: @media (max-width: 768px) { .parallax-section { background-attachment: scroll; } }. This disables the effect on smaller screens where it either does not work at all on iOS Safari or performs poorly due to limited GPU memory on entry-level Android devices. The section still displays the background image correctly as a standard scroll background, so the visual design remains intact and only the parallax motion is dropped. Pair the breakpoint query with a prefers-reduced-motion query to cover accessibility preferences in the same media block.
Yes. background-attachment accepts three values: scroll, fixed, and local. Scroll is the default, where the background moves with the element when the element scrolls but stays fixed when the page scrolls past the element. Fixed makes the background stationary relative to the viewport. Local makes the background scroll along with overflowing content inside a scrollable element, which is useful for content panels with internal scroll where you want the texture to move with the text. The local value is rarely seen in production code but is genuinely useful for sticky pattern backdrops inside scrollable containers.
Each layer in a comma-separated background can have its own attachment value, which lets you combine fixed and scrolling layers in a single background declaration. background: url(top.png) center top/cover no-repeat fixed, url(bottom.png) center bottom/cover no-repeat scroll keeps the first layer fixed while the second scrolls normally with the element. Multiple fixed layers all share the same viewport reference, so they move at the same rate relative to the page, which means depth only emerges between fixed and scrolling layers and not between two fixed layers. For true multi-rate parallax, use JavaScript or multiple pseudo-elements with different transforms.
JavaScript parallax libraries such as Lenis or Locomotive Scroll offer more precise control over parallax depth, custom easing curves, and cross-device behaviour than background-attachment: fixed can provide on its own. The trade-off is that they add script weight and require careful performance management to avoid scroll jank, particularly on lower-end devices. For a simple single-image fixed background effect, the CSS pseudo-element approach is simpler, lighter, and more performant than pulling in a JavaScript library. Reach for JavaScript parallax only when the design requires variable depth, element-level parallax, or scroll-bound animations beyond what CSS alone can express.
No. A position: fixed element or a fixed-attachment background inside a parent with a CSS transform, perspective, filter, or will-change other than auto becomes positioned relative to that parent rather than the viewport. This is defined by the CSS specification because transformed elements establish a containing block for fixed descendants. If your fixed background suddenly stops being fixed, check the ancestor chain for transform, filter, or perspective. Move the parallax element outside the transformed parent, or remove the transform if it is not load-bearing.
Aim for at least 1920px wide for fixed backgrounds, and 2560px wide if you support large external displays or 4K monitors. Because background-attachment: fixed sizes the image relative to the viewport rather than the element, a smaller image will stretch and look soft on wide screens even if the section itself is narrow. Compress the image with mozjpeg or convert to AVIF or WebP to keep file size reasonable. A well-compressed 2560px WebP background typically lands between 150KB and 400KB, which is acceptable for a hero asset on most pages.

Ready to get started?

Open the full Background Gen — free, no account needed, works on any device.

Open Background Gen →

Free · No account needed · Works on any device