background-attachment
background-attachment controls whether a background image scrolls with the element (default scroll) or stays fixed relative to the viewport (fixed). A third value, local, makes the background scroll with the element's content box. This property is most visible on hero sections and enables parallax scrolling effects.
Attachment values
Value | Reference frame | Use case |
|---|---|---|
| Fixed to element (default) | Normal images, moves with element |
| Fixed to viewport | Hero backgrounds, parallax effects |
| Scrolls with content | Pattern inside scrolling container |
/* Scroll with the element (default) */
.card {
background-image: url('texture.png');
background-attachment: scroll;
/* Background moves when you scroll past the element */
}
/* Stay fixed to the viewport */
.hero {
background-image: url('hero.jpg');
background-attachment: fixed;
height: 100vh;
/* Background stays in place as you scroll */
}
/* Scroll with content inside element */
.scrollable-box {
overflow-y: scroll;
height: 300px;
background-image: url('pattern.png');
background-attachment: local;
/* Background scrolls with the box's content */
}scroll — moving with the element
This is the default. The background image stays in its position relative to the element, so it moves when the element scrolls.
/* Default behaviour — background moves with element */
.box {
width: 300px;
height: 300px;
background-image: url('pattern.png');
background-attachment: scroll;
background-repeat: no-repeat;
background-position: center;
/* As you scroll the page, this element and its background move together */
}fixed — parallax scrolling
With fixed, the background stays pinned to the viewport. As you scroll, the element moves but the background appears to stay in place, creating a depth effect called parallax scrolling.
/* Hero section with parallax */
.hero {
width: 100%;
height: 100vh;
background-image: url('hero-bg.jpg');
background-attachment: fixed;
background-size: cover;
background-position: center;
display: flex;
align-items: center;
justify-content: center;
color: white;
/* As user scrolls, the background appears to move slower */
}
/* Parallax with multiple layers */
.parallax-container {
height: 100vh;
background-image: url('background.jpg');
background-attachment: fixed;
background-size: cover;
background-position: center;
}
.content {
position: relative;
background-color: white;
padding: 60px 20px;
/* Sits on top, scrolls normally while background stays fixed */
}Creating parallax depth
Parallax works best when you layer multiple elements with different background images and attachment values.
<!-- HTML structure -->
<!-- <div class="parallax-layer layer-1"></div> -->
<!-- <div class="content">Content here</div> -->
<!-- <div class="parallax-layer layer-2"></div> -->
<!-- <div class="content">More content</div> -->
/* CSS for layered parallax */
.parallax-layer {
height: 50vh;
background-size: cover;
background-position: center;
background-attachment: fixed;
}
.layer-1 {
background-image: url('distant-mountains.jpg');
}
.layer-2 {
background-image: url('closer-trees.jpg');
}
.content {
background-color: white;
padding: 60px 40px;
/* Scrolls normally while backgrounds stay fixed */
}local — scrolling within a container
The local value makes the background scroll with the element's content box, useful for scrollable containers like modals or scrollable divs.
/* Scrollable container with background pattern */
.scrollable-list {
height: 300px;
overflow-y: scroll;
background-image: url('stripes.png');
background-attachment: local; /* scrolls with the list */
background-repeat: repeat;
}
.scrollable-list::-webkit-scrollbar {
width: 8px;
}
.scrollable-list::-webkit-scrollbar-thumb {
background: #cccccc;
}
/* Modal with fixed background pattern */
.modal {
max-height: 80vh;
overflow-y: scroll;
background-image: url('modal-pattern.png');
background-attachment: local;
background-position: top left;
}Combining background properties
/* Hero section with all background properties */
.hero-section {
width: 100%;
height: 100vh;
/* Colour fallback */
background-color: #2c3e50;
/* Image with darken overlay */
background-image:
linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4)),
url('hero-image.jpg');
/* Size, position, repeat */
background-size: cover;
background-position: center;
background-repeat: no-repeat;
/* Parallax effect */
background-attachment: fixed;
/* Content positioning */
display: flex;
align-items: center;
justify-content: center;
color: white;
text-align: center;
}