In short
CSS multiple backgrounds let you stack images and gradients on one element. Learn layering, background-attachment fixed, scroll and local, a parallax effect, background-clip and background-origin. How do multiple backgrounds work?
CSS multiple backgrounds let you stack images and gradients on one element. Learn layering, background-attachment fixed, scroll and local, a parallax effect, background-clip and background-origin.
How do multiple backgrounds work?
In the CSS Backgrounds lesson you added one image or gradient to an element. But one element can have many background layers, stacked like sheets of transparent plastic on a projector. You list them in background-image, separated by commas.
The most important rule: the first layer in the list is on top, and the last one is at the bottom. A background-color, if you set one, always sits below all the images.
Every other background property can also take a comma-separated list. The first value goes with the first image, the second with the second, and so on.
<header class="hero">
<h1>Summer Sale</h1>
<p>Up to 50% off everything</p>
</header>
.hero {
min-height: 60vh;
display: grid;
place-content: center;
text-align: center;
color: white;
background-color: #1e293b;
background-image:
linear-gradient(rgb(0 0 0 / 0.55), rgb(0 0 0 / 0.2)),
url("https://picsum.photos/id/1011/1600/900");
background-size: cover, cover;
background-position: center, center;
}
You'll see a photo with a dark see-through layer on top, and white text that is easy to read. The gradient is listed first, so it covers the photo. This "dark overlay" is the most useful multiple-background trick: it makes any photo work behind white text.
Layering images and gradients with the shorthand
You can also write each layer in the background shorthand, separated by commas. Each layer can have its own image, position, size (after a /) and repeat. The color goes only in the last layer.
.card {
padding: 32px;
border-radius: 16px;
background:
radial-gradient(circle at 100% 0%, #fde68a 0 60px, transparent 61px) no-repeat,
radial-gradient(circle at 0% 100%, #c7d2fe 0 80px, transparent 81px) no-repeat,
linear-gradient(135deg, #fff7ed, #eef2ff);
}
This card has a soft two-color gradient, with a yellow quarter-circle in the top-right corner and a lilac quarter-circle in the bottom-left. No extra HTML elements or image files are needed: three gradient layers draw the whole decoration.
Common mistake: Putting the color in the first layer, like
background: red, url(photo.jpg);. That is invalid, and the browser ignores the whole declaration. A color is only allowed in the final layer.
background-attachment: scroll, fixed and local
background-attachment controls what happens to a background when the page or the box scrolls.
| Value | What the background does |
|---|---|
scroll | The default. Moves with the element as the page scrolls, but stays still if the element's own content scrolls. |
fixed | Stays fixed to the browser window. The element moves over it, like looking through a window at a still landscape. |
local | Moves with the element's own content when that content scrolls (for example in a box with overflow: auto). |
A simple parallax effect with background-attachment: fixed
Parallax means things at different distances move at different speeds, like trees and mountains seen from a train window. With fixed, the background stays still while the section scrolls past it, which creates a cheap parallax look.
<section class="text">Scroll down to see the effect.</section>
<section class="parallax">
<h2>Explore the mountains</h2>
</section>
<section class="text">More content below.</section>
.text {
min-height: 80vh;
padding: 40px;
}
.parallax {
min-height: 60vh;
display: grid;
place-items: center;
color: white;
background-image: url("https://picsum.photos/id/1018/1600/1000");
background-size: cover;
background-position: center;
background-attachment: fixed;
}
As you scroll, the text sections move normally, but the mountain photo seems to stay still behind the window made by the middle section.
Note: Many mobile browsers, including Safari on iPhone, ignore
background-attachment: fixedfor performance reasons and treat it likescroll. The page still works; the effect is just missing. Treat parallax as a bonus, and respect users who don't like motion with@media (prefers-reduced-motion: reduce) { .parallax { background-attachment: scroll; } }.
Scroll shadows with background-attachment: local
local enables a clever trick: shadows that appear only when a scrolling box has more content to show.
.scroll-box {
max-height: 200px;
overflow: auto;
padding: 12px;
background:
linear-gradient(white 30%, transparent) center top,
linear-gradient(transparent, white 70%) center bottom,
radial-gradient(farthest-side at 50% 0, rgb(0 0 0 / 0.25), transparent) center top,
radial-gradient(farthest-side at 50% 100%, rgb(0 0 0 / 0.25), transparent) center bottom;
background-color: white;
background-repeat: no-repeat;
background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px;
background-attachment: local, local, scroll, scroll;
}
Put a long list inside a <div class="scroll-box">. At the top, there's no top shadow; when you scroll down, a soft shadow appears at the top edge. When you reach the end, the bottom shadow disappears. The white "covers" (local) move with the content and hide the shadows (scroll) only when you're at an edge.
background-clip and background-origin
These two properties decide which part of the box the background uses.
background-originsets where a background image starts (its position 0 0). Values:padding-box(the default),border-box,content-box.background-clipsets where the background is visible; it cuts off everything outside. Values:border-box(the default),padding-box,content-box, andtext.
<h1 class="gradient-text">Hello, CodeCraft!</h1>
<div class="framed">Padding stays white here.</div>
.gradient-text {
font-size: 3rem;
background: linear-gradient(90deg, #ec4899, #8b5cf6, #3b82f6);
background-clip: text;
color: transparent;
}
.framed {
padding: 24px;
border: 8px dashed #94a3b8;
background: linear-gradient(#bae6fd, #bae6fd) content-box, white;
}
The heading's letters are filled with a pink-to-blue gradient, because the background is clipped to the shape of the text and the text color is transparent. In the second box, the blue layer (a "gradient" of one color, because a plain color isn't allowed in an upper layer) fills only the content area: the padding stays white, and the white also shows through the gaps in the dashed border. A single box value in a layer (here content-box) sets both the origin and the clip.
Tip: With
background-clip: text, always keep a readable fallback: if the background fails, transparent text is invisible. Test your gradient colors for contrast against the page background.
Practice exercise
Build a landing page header with three background layers: a dark gradient overlay, a small repeating dot pattern made with radial-gradient, and a photo at the bottom. Below it, add a parallax section with background-attachment: fixed, and a "Terms and conditions" box with scroll shadows.
Hint: for the dot pattern use radial-gradient(rgb(255 255 255 / 0.2) 1px, transparent 1px) with background-size: 16px 16px for that layer only.
Key takeaways
- Separate background layers with commas; the first layer is on top, and a color goes only in the last.
- A dark gradient over a photo makes white text readable.
background-attachment: fixedpins the background to the window for a simple parallax effect (often ignored on mobile).background-attachment: localscrolls with the box's content and enables scroll shadows.background-originsets where the image starts;background-clipsets where it's visible, andtextcreates gradient text.