CSS Backgrounds
CSS backgrounds control the visual area behind an element's content. The background system is remarkably powerful — supporting colors, images, gradients, repeating patterns, positioning, sizing, and clipping. Multiple backgrounds can be layered on a single element, opening up creative compositing possibilities.
Every element has a background area that starts at the padding edge by default. Backgrounds are painted below borders and above the element's own background color. Understanding background properties is essential for creating rich visual interfaces, from simple solid fills to complex layered textures.
| 1 | .element { |
| 2 | background-color: #0D0D0D; |
| 3 | background-image: url("pattern.png"); |
| 4 | background-repeat: no-repeat; |
| 5 | background-position: center; |
| 6 | background-size: cover; |
| 7 | } |
The background-color property fills the background area with a solid color. It is painted behind any background images. If no background image is specified, the background color fills the entire background area.
| 1 | .solid-bg { |
| 2 | background-color: #0D0D0D; |
| 3 | } |
| 4 | |
| 5 | /* Transparent backgrounds */ |
| 6 | .transparent { |
| 7 | background-color: transparent; /* default */ |
| 8 | } |
| 9 | |
| 10 | .semi-transparent { |
| 11 | background-color: rgba(0, 255, 65, 0.1); |
| 12 | } |
| 13 | |
| 14 | /* Using currentColor */ |
| 15 | .theme-bg { |
| 16 | color: #00FF41; |
| 17 | background-color: color-mix(in srgb, currentColor 10%, transparent); |
| 18 | } |
| 19 | |
| 20 | /* HSL for terminal palette */ |
| 21 | .terminal-panel { |
| 22 | background-color: hsl(0, 0%, 5%); /* #0D0D0D */ |
| 23 | } |
| 24 | .terminal-highlight { |
| 25 | background-color: hsl(130, 100%, 10%); /* dark green */ |
| 26 | } |
The background-image property sets one or more background images on an element. Images are layered on top of the background color, with the first image in the list rendered closest to the viewer (on top).
| 1 | /* Single background image */ |
| 2 | .single { |
| 3 | background-image: url("texture.png"); |
| 4 | } |
| 5 | |
| 6 | /* Gradient as background image */ |
| 7 | .gradient-bg { |
| 8 | background-image: linear-gradient(135deg, #0D0D0D, #1A1A2E); |
| 9 | } |
| 10 | |
| 11 | /* Multiple images — layered */ |
| 12 | .layered { |
| 13 | background-image: |
| 14 | url("overlay.png"), |
| 15 | url("base-texture.png"); |
| 16 | /* overlay appears on top of base-texture */ |
| 17 | } |
| 18 | |
| 19 | /* No background image (default) */ |
| 20 | .none { |
| 21 | background-image: none; |
| 22 | } |
| 23 | |
| 24 | /* URL with fallback — use background-color as fallback */ |
| 25 | .safe-bg { |
| 26 | background-color: #0D0D0D; |
| 27 | background-image: url("pattern.webp"); |
| 28 | } |
Controls how background images tile (repeat) across the background area. The default is repeat, which tiles the image both horizontally and vertically. Modern CSS supports two-value syntax for independent axis control.
| 1 | /* One-value syntax */ |
| 2 | .repeat { background-repeat: repeat; } /* both axes (default) */ |
| 3 | .repeat-x { background-repeat: repeat-x; } /* horizontal only */ |
| 4 | .repeat-y { background-repeat: repeat-y; } /* vertical only */ |
| 5 | .no-repeat { background-repeat: no-repeat; } /* no tiling */ |
| 6 | |
| 7 | /* Two-value syntax (modern) */ |
| 8 | .repeat-axes { |
| 9 | background-repeat: repeat space; /* horizontal: repeat, vertical: space */ |
| 10 | } |
| 11 | .no-repeat-h { |
| 12 | background-repeat: repeat no-repeat; /* vertical only */ |
| 13 | } |
| 14 | |
| 15 | /* Space — distribute evenly with gaps */ |
| 16 | .space-distributed { |
| 17 | background-repeat: space; |
| 18 | } |
| 19 | |
| 20 | /* Round — scale to fit without clipping */ |
| 21 | .rounded-repeat { |
| 22 | background-repeat: round; |
| 23 | } |
| 24 | |
| 25 | /* Practical: patterns */ |
| 26 | .terminal-grid { |
| 27 | background-image: url("grid.svg"); |
| 28 | background-repeat: repeat; |
| 29 | } |
| 30 | |
| 31 | .terminal-header-accent { |
| 32 | background-image: linear-gradient(90deg, #00FF41, transparent); |
| 33 | background-repeat: no-repeat; |
| 34 | background-position: bottom; |
| 35 | background-size: 100% 2px; |
| 36 | } |
background-position defines the starting position of the background image within the background area. It accepts keywords, lengths, percentages, and combinations. The default is 0% 0% (top-left corner).
| 1 | /* Keyword positions */ |
| 2 | .top-left { background-position: left top; } /* default: 0% 0% */ |
| 3 | .top-center { background-position: center top; } |
| 4 | .top-right { background-position: right top; } |
| 5 | .center-left { background-position: left center; } |
| 6 | .center { background-position: center center; } /* often used */ |
| 7 | .center-right { background-position: right center; } |
| 8 | .bottom-left { background-position: left bottom; } |
| 9 | .bottom-center { background-position: center bottom; } |
| 10 | .bottom-right { background-position: right bottom; } |
| 11 | |
| 12 | /* Percentage values */ |
| 13 | .percent-pos { |
| 14 | background-position: 50% 50%; /* center */ |
| 15 | background-position: 25% 75%; /* 25% from left, 75% from top */ |
| 16 | } |
| 17 | |
| 18 | /* Length values */ |
| 19 | .pixel-pos { |
| 20 | background-position: 20px 40px; /* 20px from left, 40px from top */ |
| 21 | } |
| 22 | |
| 23 | /* Offset from edges — modern syntax */ |
| 24 | .offset-edges { |
| 25 | background-position: right 20px bottom 30px; |
| 26 | } |
| 27 | |
| 28 | /* Multiple values for multiple backgrounds */ |
| 29 | .multi-pos { |
| 30 | background-image: url("top.png"), url("bottom.png"); |
| 31 | background-position: top left, bottom right; |
| 32 | background-repeat: no-repeat; |
| 33 | } |
background-size controls the size of the background image. The cover keyword scales the image to cover the entire area (clipping if necessary), while contain scales the image to fit entirely within the area (letterboxing if necessary).
| 1 | /* Keywords */ |
| 2 | .cover { background-size: cover; } /* fills area, may clip */ |
| 3 | .contain { background-size: contain; } /* fits entirely, may letterbox */ |
| 4 | .auto { background-size: auto; } /* natural image size (default) */ |
| 5 | |
| 6 | /* Single value — sets width, height auto */ |
| 7 | .single-val { background-size: 50%; } |
| 8 | |
| 9 | /* Two values — width height */ |
| 10 | .two-val { background-size: 200px 100px; } |
| 11 | |
| 12 | /* Cover vs Contain — choose wisely */ |
| 13 | /* cover: great for hero images, banners */ |
| 14 | /* contain: great for icons, patterns, logos */ |
| 15 | |
| 16 | /* Practical terminal examples */ |
| 17 | .terminal-hero { |
| 18 | background-image: url("hero.png"); |
| 19 | background-size: cover; |
| 20 | background-position: center; |
| 21 | } |
| 22 | |
| 23 | .terminal-logo { |
| 24 | background-image: url("logo.svg"); |
| 25 | background-size: contain; |
| 26 | background-repeat: no-repeat; |
| 27 | background-position: center; |
| 28 | } |
| 29 | |
| 30 | /* Multiple sizes for multiple backgrounds */ |
| 31 | .multi-size { |
| 32 | background-image: url("large.png"), url("icon.png"); |
| 33 | background-size: cover, 32px 32px; |
| 34 | background-position: center, bottom right; |
| 35 | background-repeat: no-repeat; |
| 36 | } |
info
Controls whether the background image scrolls with the content or remains fixed in the viewport. This property creates interesting visual effects like parallax scrolling and fixed watermarks.
| 1 | /* Values */ |
| 2 | .scroll { background-attachment: scroll; } /* scrolls with element (default) */ |
| 3 | .fixed { background-attachment: fixed; } /* fixed to viewport */ |
| 4 | .local { background-attachment: local; } /* scrolls with element's content */ |
| 5 | |
| 6 | /* Parallax effect — fixed background */ |
| 7 | .parallax-section { |
| 8 | background-image: url("bg.jpg"); |
| 9 | background-attachment: fixed; |
| 10 | background-size: cover; |
| 11 | background-position: center; |
| 12 | } |
| 13 | |
| 14 | /* Fixed background for terminal watermark */ |
| 15 | .terminal-watermark { |
| 16 | background-image: url("watermark.svg"); |
| 17 | background-attachment: fixed; |
| 18 | background-repeat: no-repeat; |
| 19 | background-position: center; |
| 20 | background-size: 200px; |
| 21 | opacity: 0.05; |
| 22 | } |
| 23 | |
| 24 | /* Local attachment — background scrolls with scrollable content */ |
| 25 | .scrollable-panel { |
| 26 | height: 200px; |
| 27 | overflow-y: auto; |
| 28 | background-image: url("grid-pattern.png"); |
| 29 | background-attachment: local; /* pattern scrolls with content */ |
| 30 | } |
warning
The background shorthand property sets all background properties in one declaration. The order is flexible but must follow the convention: color image repeat attachment position / size origin clip.
| 1 | /* Full shorthand — order matters */ |
| 2 | .element { |
| 3 | background: #0D0D0D url("bg.png") no-repeat fixed center / cover; |
| 4 | } |
| 5 | |
| 6 | /* Breakdown of the shorthand above: */ |
| 7 | /* #0D0D0D — background-color */ |
| 8 | /* url("bg.png") — background-image */ |
| 9 | /* no-repeat — background-repeat */ |
| 10 | /* fixed — background-attachment */ |
| 11 | /* center — background-position */ |
| 12 | /* / cover — background-size (note the slash) */ |
| 13 | |
| 14 | /* Common shorthand patterns */ |
| 15 | .solid { background: #0D0D0D; } |
| 16 | .gradient { background: linear-gradient(135deg, #0D0D0D, #1A1A2E); } |
| 17 | .image { background: url("bg.png") no-repeat center/cover; } |
| 18 | .combo { background: #0D0D0D url("overlay.png") repeat-x bottom/auto 40px; } |
| 19 | |
| 20 | /* Multiple backgrounds in shorthand */ |
| 21 | .layered { |
| 22 | background: |
| 23 | url("front.png") no-repeat center / 100px, |
| 24 | url("back.png") repeat, |
| 25 | #0D0D0D; |
| 26 | } |
| 27 | |
| 28 | /* Terminal panel shorthand */ |
| 29 | .terminal-panel { |
| 30 | background: #0D0D0D; |
| 31 | /* Equivalent to: */ |
| 32 | background-color: #0D0D0D; |
| 33 | background-image: none; |
| 34 | background-repeat: repeat; |
| 35 | background-attachment: scroll; |
| 36 | background-position: 0% 0%; |
| 37 | background-size: auto auto; |
| 38 | } |
best practice
CSS allows multiple background images on a single element by comma-separating values. The first image in the list renders on top of subsequent images. Each layer can have its own position, size, and repeat settings.
| 1 | .multi-bg { |
| 2 | background: |
| 3 | linear-gradient(135deg, rgba(0,255,65,0.1), transparent 50%), |
| 4 | repeating-linear-gradient( |
| 5 | 0deg, |
| 6 | transparent, |
| 7 | transparent 20px, |
| 8 | rgba(0,255,65,0.03) 20px, |
| 9 | rgba(0,255,65,0.03) 21px |
| 10 | ), |
| 11 | #0D0D0D; |
| 12 | } |
| 13 | |
| 14 | /* Practical: terminal-style card */ |
| 15 | .terminal-card { |
| 16 | background: |
| 17 | linear-gradient(180deg, rgba(0,255,65,0.05) 0%, transparent 100%), |
| 18 | #0D0D0D; |
| 19 | } |
| 20 | |
| 21 | /* Layered with different positioning */ |
| 22 | .complex-layer { |
| 23 | background-image: url("corner.svg"), url("pattern.png"), url("texture.jpg"); |
| 24 | background-position: top right, center, center; |
| 25 | background-size: 64px, auto, cover; |
| 26 | background-repeat: no-repeat, repeat, no-repeat; |
| 27 | } |
| 28 | |
| 29 | /* Scanline overlay */ |
| 30 | .crt-effect { |
| 31 | background: |
| 32 | repeating-linear-gradient( |
| 33 | 0deg, |
| 34 | transparent, |
| 35 | transparent 2px, |
| 36 | rgba(0,0,0,0.1) 2px, |
| 37 | rgba(0,0,0,0.1) 3px |
| 38 | ), |
| 39 | linear-gradient(135deg, #0D0D0D, #1A1A2E); |
| 40 | } |
background-clip controls how far the background extends within the element. It determines whether the background paints under the border, under the padding, or only behind the content.
| 1 | .border-box { |
| 2 | background-clip: border-box; /* extends under the border (default) */ |
| 3 | } |
| 4 | |
| 5 | .padding-box { |
| 6 | background-clip: padding-box; /* extends to padding edge, not under border */ |
| 7 | } |
| 8 | |
| 9 | .content-box { |
| 10 | background-clip: content-box; /* only behind the content area */ |
| 11 | } |
| 12 | |
| 13 | .text { |
| 14 | background-clip: text; /* clips to the text shape */ |
| 15 | -webkit-background-clip: text; |
| 16 | color: transparent; /* must be transparent to show background */ |
| 17 | } |
| 18 | |
| 19 | /* Practical: text with gradient fill */ |
| 20 | .gradient-text { |
| 21 | background: linear-gradient(135deg, #00FF41, #3B82F6); |
| 22 | background-clip: text; |
| 23 | -webkit-background-clip: text; |
| 24 | color: transparent; |
| 25 | font-weight: 800; |
| 26 | font-size: 3rem; |
| 27 | } |
| 28 | |
| 29 | /* Practical: border with background visible */ |
| 30 | .border-clip { |
| 31 | border: 4px dashed #00FF41; |
| 32 | background: #0D0D0D; |
| 33 | background-clip: padding-box; /* bg stops at padding, border is transparent */ |
| 34 | } |
background-origin determines the positioning area of the background image (where background-position is relative to). It works alongside background-clip but controls positioning, not painting extent.
| 1 | /* Values */ |
| 2 | .padding-box { |
| 3 | background-origin: padding-box; /* position relative to padding edge (default) */ |
| 4 | } |
| 5 | |
| 6 | .border-box { |
| 7 | background-origin: border-box; /* position relative to border edge */ |
| 8 | } |
| 9 | |
| 10 | .content-box { |
| 11 | background-origin: content-box; /* position relative to content edge */ |
| 12 | } |
| 13 | |
| 14 | /* Practical: image positioned from border edge */ |
| 15 | .border-origin { |
| 16 | background-image: url("corner-deco.svg"); |
| 17 | background-origin: border-box; |
| 18 | background-position: top right; |
| 19 | background-repeat: no-repeat; |
| 20 | padding: 20px; |
| 21 | border: 10px solid transparent; |
| 22 | } |
| 23 | |
| 24 | /* origin vs clip — they differ */ |
| 25 | .example { |
| 26 | background-origin: border-box; /* image starts from border edge */ |
| 27 | background-clip: content-box; /* image clipped to content area */ |
| 28 | } |
background-blend-mode defines how background layers (images and color) blend with each other. It uses the same blend modes as Photoshop and CSS mix-blend-mode — multiply, screen, overlay, and more.
| 1 | .multiply { |
| 2 | background-blend-mode: multiply; /* darkens, good for textures */ |
| 3 | } |
| 4 | |
| 5 | .screen { |
| 6 | background-blend-mode: screen; /* lightens */ |
| 7 | } |
| 8 | |
| 9 | .overlay { |
| 10 | background-blend-mode: overlay; /* multiplies or screens depending on base */ |
| 11 | } |
| 12 | |
| 13 | .darken { |
| 14 | background-blend-mode: darken; /* keeps darker pixels */ |
| 15 | } |
| 16 | |
| 17 | .lighten { |
| 18 | background-blend-mode: lighten; /* keeps lighter pixels */ |
| 19 | } |
| 20 | |
| 21 | .color-dodge { |
| 22 | background-blend-mode: color-dodge; /* brightens base */ |
| 23 | } |
| 24 | |
| 25 | /* Practical: terminal texture overlay */ |
| 26 | .textured-panel { |
| 27 | background: |
| 28 | url("noise.png"), |
| 29 | linear-gradient(135deg, #0D0D0D, #1A1A2E); |
| 30 | background-blend-mode: overlay; |
| 31 | } |
| 32 | |
| 33 | /* Photo tinting effect */ |
| 34 | .photo-tint { |
| 35 | background: |
| 36 | linear-gradient(0deg, rgba(0, 255, 65, 0.3), rgba(0, 255, 65, 0.3)), |
| 37 | url("photo.jpg") center/cover; |
| 38 | background-blend-mode: multiply; |
| 39 | } |
| 40 | |
| 41 | /* Multiple blend modes */ |
| 42 | .artistic { |
| 43 | background-image: |
| 44 | url("texture.png"), |
| 45 | url("photo.jpg"), |
| 46 | linear-gradient(135deg, #00FF41, #3B82F6); |
| 47 | background-blend-mode: overlay, normal; |
| 48 | } |
pro tip