CSS Background Effects: Parallax & Patterns
Master modern CSS background techniques: parallax effects, scrolling patterns in containers, gradient overlays, and responsive backgrounds. With browser compatibility and performance tips.
CSS backgrounds are far more than just colors or images. With modern techniques, you can create subtle patterns, parallax effects, and dynamically scrolling backgrounds – all without JavaScript. In this tutorial, I’ll show you the most important techniques with complete code examples.
Gradient Backgrounds: The Basics
Gradients are the foundation of many modern background designs. They can be combined and layered in any way you like.
Linear Gradients for Hero Sections
/* Diagonal gradient for hero areas */
.hero {
background: linear-gradient(
135deg,
hsl(231 77% 60%) 0%,
hsl(271 47% 50%) 100%
);
min-height: 100vh;
}
/* Multi-color gradient with defined transitions */
.gradient-complex {
background: linear-gradient(
to right,
hsl(200 80% 50%) 0%,
hsl(200 80% 50%) 30%,
hsl(260 70% 55%) 70%,
hsl(260 70% 55%) 100%
);
}
Radial Gradients for Spotlight Effects
/* Spotlight effect from a specific position */
.spotlight {
background: radial-gradient(
circle at 30% 40%,
hsl(200 80% 50% / 0.3),
transparent 60%
);
}
/* Multiple overlapping spotlights */
.multi-spotlight {
background:
radial-gradient(circle at 20% 30%, hsl(200 80% 50% / 0.2), transparent 40%),
radial-gradient(circle at 80% 70%, hsl(280 70% 50% / 0.2), transparent 40%),
hsl(220 15% 10%);
}
Parallax Effects with background-attachment: fixed
The classic parallax effect is created using background-attachment: fixed. The background image stays fixed to the viewport while the content scrolls over it.
/* Classic parallax hero */
.parallax-section {
background-image: url('/images/hero.webp');
background-attachment: fixed;
background-position: center;
background-size: cover;
min-height: 70vh;
}
/* With overlay for better readability */
.parallax-with-overlay {
background:
linear-gradient(hsl(220 15% 10% / 0.7), hsl(220 15% 10% / 0.7)),
url('/images/hero.webp') center / cover fixed;
min-height: 70vh;
}
Mobile Fallback – iOS Issues
background-attachment: fixed doesn’t work reliably on iOS Safari. A fallback is therefore essential:
.parallax-section {
background-image: url('/images/hero.webp');
background-attachment: fixed;
background-position: center;
background-size: cover;
}
/* Mobile fallback */
@media (max-width: 1024px) {
.parallax-section {
background-attachment: scroll;
}
}
/* Alternative: Feature query */
@supports not (background-attachment: fixed) {
.parallax-section {
background-attachment: scroll;
}
}
Scrolling Backgrounds in Containers
A common problem: A scrollable container has a patterned background that stays in place when scrolling. The content scrolls, but the pattern doesn’t – which looks unnatural.
Understanding the Problem
/* Default behavior: Background does NOT scroll with content */
.scrollable-box {
max-height: 300px;
overflow-y: auto;
background-image: url('/pattern.svg');
background-size: 20px 20px;
/* background-attachment: scroll; is the default */
}
With the default value scroll, the background is fixed to the element’s frame. When scrolling within the element, the frame doesn’t move – so neither does the background.
The Solution: background-attachment: local
/* Background scrolls WITH the content */
.scrollable-box {
max-height: 300px;
overflow-y: auto;
background-image: url('/pattern.svg');
background-attachment: local;
background-size: 20px 20px;
}
Comparing the Three Values
| Value | Behavior | Use Case |
|---|---|---|
scroll | Fixed to element edge | Normal pages (default) |
fixed | Fixed to viewport | Parallax effects |
local | Scrolls with content | Scrollable containers |
Browser Compatibility
background-attachment: local has 96.25% browser support. Safari had a bug until version 15.3, but since Safari 15.4 (March 2022) it works reliably in all modern browsers.
CSS Stripe Patterns for Code Blocks
Alternating colored rows in <pre> elements significantly improve the readability of code blocks.
Classic Solution with em
/* Zebra stripes for code blocks */
.code-block {
background: repeating-linear-gradient(
to bottom,
hsl(220 15% 13%) 0,
hsl(220 15% 13%) 1.5em,
hsl(220 15% 16%) 1.5em,
hsl(220 15% 16%) 3em
);
background-attachment: local;
line-height: 1.5;
padding: 1em;
overflow: auto;
font-family: monospace;
}
Modern Solution with the lh Unit
The lh unit (line-height) automatically adapts to the line height – perfect for zebra stripes:
/* With lh unit (93% browser support) */
@supports (height: 1lh) {
.code-block-modern {
background: repeating-linear-gradient(
to bottom,
hsl(220 15% 13%) 0,
hsl(220 15% 13%) 1lh,
hsl(220 15% 16%) 1lh,
hsl(220 15% 16%) 2lh
);
background-attachment: local;
}
}
The lh unit has been supported since Chrome 109, Firefox 120, and Safari 16.4.
Combined: With Fallback
.code-block {
/* Fallback for older browsers */
background: repeating-linear-gradient(
to bottom,
hsl(220 15% 13%) 0,
hsl(220 15% 13%) 1.5em,
hsl(220 15% 16%) 1.5em,
hsl(220 15% 16%) 3em
);
background-attachment: local;
line-height: 1.5;
padding: 1em;
overflow: auto;
}
/* Progressive enhancement with lh */
@supports (height: 1lh) {
.code-block {
background: repeating-linear-gradient(
to bottom,
hsl(220 15% 13%) 0,
hsl(220 15% 13%) 1lh,
hsl(220 15% 16%) 1lh,
hsl(220 15% 16%) 2lh
);
}
}
Subtle Grid Patterns
Subtle grids in the background add depth to designs without being intrusive.
Simple Dot Grid
.dot-pattern {
background-image: radial-gradient(
circle,
hsl(0 0% 100% / 0.1) 1px,
transparent 1px
);
background-size: 24px 24px;
}
Line Grid
.line-grid {
background-image:
linear-gradient(
hsl(0 0% 100% / 0.03) 1px,
transparent 1px
),
linear-gradient(
90deg,
hsl(0 0% 100% / 0.03) 1px,
transparent 1px
);
background-size: 24px 24px;
}
Combined Grid with Accents
.complex-grid {
background-image:
/* Large accent lines every 96px */
linear-gradient(hsl(200 80% 50% / 0.1) 1px, transparent 1px),
linear-gradient(90deg, hsl(200 80% 50% / 0.1) 1px, transparent 1px),
/* Fine lines every 24px */
linear-gradient(hsl(0 0% 100% / 0.03) 1px, transparent 1px),
linear-gradient(90deg, hsl(0 0% 100% / 0.03) 1px, transparent 1px);
background-size: 96px 96px, 96px 96px, 24px 24px, 24px 24px;
}
Browser Compatibility Overview
| Feature | Chrome | Firefox | Safari | Edge | iOS Safari |
|---|---|---|---|---|---|
local | 4+ | 25+ | 15.4+ | 12+ | 15.4+ |
fixed | 4+ | 25+ | 5+ | 12+ | ⚠️ Buggy |
lh unit | 109+ | 120+ | 16.4+ | 109+ | 16.4+ |
repeating-linear-gradient | 10+ | 16+ | 5.1+ | 12+ | 5.1+ |
Known Limitations
- iOS Safari:
background-attachment: fixeddoesn’t work as expected – use fallback toscroll - Safari 14-15.3: Bug with
local/fixedwhen scrolling outer containers – fixed since 15.4 - Samsung Internet:
localonly works reliably withborder-radius
Performance Tips
1. Use fixed Sparingly
background-attachment: fixed causes a repaint on every scroll frame. With large images or multiple fixed backgrounds, this can lead to noticeable lag.
/* Better: Pseudo-element with transform */
.parallax-performant {
position: relative;
overflow: hidden;
}
.parallax-performant::before {
content: '';
position: absolute;
inset: -10%; /* Slightly larger for scroll headroom */
background: url('/hero.webp') center / cover;
will-change: transform;
z-index: -1;
}
2. Optimize Images
The same optimization rules apply to background images as to <img>:
- WebP or AVIF instead of JPEG/PNG
- Appropriate resolution (not larger than necessary)
- Lazy loading for backgrounds below the viewport
3. Gradient Performance
Gradients are generally performant. However, very complex gradients with many color stops can cause rendering issues:
/* Performant: Few color stops */
.simple-gradient {
background: linear-gradient(135deg, hsl(200 80% 50%), hsl(260 70% 55%));
}
/* Potentially problematic: Many color stops */
.complex-gradient {
background: linear-gradient(
135deg,
hsl(200 80% 50%) 0%,
hsl(210 75% 52%) 10%,
hsl(220 70% 54%) 20%,
/* ... many more stops ... */
hsl(260 70% 55%) 100%
);
}
Practical Example: Complete Code Block
Here’s a complete example of a code block with zebra stripes that combines all the techniques discussed:
/* Modern code block with scrolling zebra stripes */
.code-block {
/* Layout */
max-height: 400px;
overflow: auto;
padding: 1em;
border-radius: 8px;
/* Typography */
font-family: 'Fira Code', 'Consolas', monospace;
font-size: 0.9rem;
line-height: 1.6;
tab-size: 2;
/* Fallback background */
background-color: hsl(220 15% 13%);
background-image: repeating-linear-gradient(
to bottom,
transparent 0,
transparent 1.6em,
hsl(220 15% 16%) 1.6em,
hsl(220 15% 16%) 3.2em
);
background-attachment: local;
}
/* Progressive enhancement with lh unit */
@supports (height: 1lh) {
.code-block {
background-image: repeating-linear-gradient(
to bottom,
transparent 0,
transparent 1lh,
hsl(220 15% 16%) 1lh,
hsl(220 15% 16%) 2lh
);
}
}
Conclusion
CSS offers powerful capabilities for background effects without JavaScript. The key takeaways:
background-attachment: localis the solution for scrolling backgrounds in containersbackground-attachment: fixedcreates parallax effects but needs mobile fallbacksrepeating-linear-gradientis perfect for stripe patterns- The
lhunit makes line-based patterns robust and maintainable - Keep performance in mind: Especially
fixedcan be problematic with large images
The combination of these techniques enables creative, performant designs – entirely without external libraries or JavaScript.
Related Content
- Interactive Design - Creative web design with CSS
- Responsive Design - Mobile-friendly design techniques
- Performance Optimization - Performant animations and effects
Tags:
René Lauenroth
Web developer with over 30 years of experience. Specialized in TYPO3, WordPress and AI integration.
Learn moreRelated Articles
AI Chatbot Website Integration
Complete guide to integrating AI chatbots on your website. OpenAI API, Claude, open-source alternatives and no-code platforms compared. With code examples and GDPR notes.
Web DevelopmentAstro Framework: Static Sites
Discover why the Astro Framework is the best choice for high-performance websites. Islands Architecture, Zero-JS-Default and practical examples.
PerformanceCore Web Vitals Optimization
Step-by-step guide to optimizing Core Web Vitals. Improve your website's LCP, FID, and CLS for better rankings and user experience.
Have questions about this topic?
I'm happy to advise you on your web project.
Get in touch