CSS Background Position: Complete Guide

Last reviewed on 2026-10-03

Master background-position property with keywords, percentages, and advanced positioning techniques

Understanding CSS Background Position

The background-position property in CSS controls where a background image is positioned within its container. This powerful property offers precise control over image placement using keywords, percentages, lengths, or combinations of these values.

Position Keywords

Five keywords (left, center, right, top, bottom) combine into nine common positions. These keywords offer semantic positioning without needing to calculate exact values.

left top
center top
right top
left center
center
right center
left bottom
center bottom
right bottom
/* Single keyword (centers on other axis) */
background-position: top; /* center top */
background-position: right; /* right center */

/* Two keywords */
background-position: bottom right;
background-position: center center;

Percentage-Based Positioning

Percentages offer responsive positioning that adapts to container size. Understanding how percentages work is crucial for creating flexible layouts.

How Percentages Work

0% 0% aligns the image's top-left with the container's top-left

50% 50% centers both image and container midpoints

100% 100% aligns the image's bottom-right with the container's bottom-right

/* Percentage positioning */
background-position: 25% 75%;     /* image's 25%/75% point on the container's 25%/75% point */
background-position: 50%;         /* 50% horizontal, 50% vertical */
background-position: 100% 0%;     /* Right edge, top edge */

/* Mixing percentages and keywords */
background-position: left 25%;    /* Left edge, image's 25% point on container's 25% point vertically */
background-position: 50% bottom;  /* Centered horizontally, bottom edge */

Pixel and Length Positioning

Length values provide pixel-perfect control over background positioning. You can use any CSS length unit including px, em, rem, vw, and vh.

/* Pixel positioning */
background-position: 20px 30px;
background-position: -10px 50px; /* Negative values allowed */

/* Other units */
background-position: 2rem 3rem;
background-position: 5vw 10vh;
/* Offset from edges (4-value syntax) */
background-position: right 20px bottom 30px;
background-position: left 10px top 50%;
background-position: center top 20px;

Negative Values, Edge Offsets and the Percentage Rule

How Percentages Are Calculated

A percentage does not move the image's top-left corner by that amount. Instead, the point at X% of the image is placed on the point at X% of the container (the background positioning area, set by background-origin). The actual offset is:

offset-x = (container width  - image width)  × X%
offset-y = (container height - image height) × Y%

/* Example: 600px wide box, 100px wide image */
background-position: 25% 0;   /* (600 - 100) × 0.25 = 125px from the left */
background-position: 100% 0;  /* (600 - 100) × 1    = 500px: image touches the right edge */

That is why 50% centers an image and 100% sits it flush against the far edge. When the image is exactly the same size as the container (for example with background-size: 100% 100%), every percentage resolves to 0 and the image does not move. When the image is larger than the container (common with cover), percentages move it in the opposite direction, choosing which part of the image stays visible.

Negative Values

Lengths and percentages can be negative. A negative length moves the image left or up, past the edge of the box, so part of it is clipped. This is how sprites reveal a single icon.

background-position: -20px -10px; /* 20px past the left edge, 10px past the top */
background-position: -50% 0;      /* (container - image) × -0.5: moves left past the edge
                                     when the image is smaller than the box */

Offsets From Any Edge

To place an image a fixed distance from the right or bottom, use an edge keyword followed by an offset (the 3- and 4-value syntax), or calc():

/* 10px from the right, 20px from the bottom */
background-position: right 10px bottom 20px;

/* Same result with calc() */
background-position: calc(100% - 10px) calc(100% - 20px);

/* Longhands per axis */
background-position-x: right 10px;
background-position-y: bottom 20px;

In calc(100% - 10px), the 100% part still follows the percentage rule above, so the image's right edge sits on the container's right edge and then moves 10px left. A 4-value position must pair each offset with an edge keyword (right 10px bottom 20px works; 10px right 20px bottom is invalid).

Complete background-position Value Reference

Value Meaning
0% 0%Initial value: image's top-left corner on the container's top-left corner
left / rightHorizontal edge (equal to 0% / 100% on the x-axis)
top / bottomVertical edge (equal to 0% / 100% on the y-axis)
center50% on whichever axis it is used for
<length>Any length unit (px, em, rem, vw, ...), negative values allowed
<percentage>Image's X% point placed on the container's X% point
calc()Mix of lengths and percentages, e.g. calc(100% - 10px)
1 valuetop → center top; a length or percentage sets x and the y-axis becomes center
2 valuesx then y for lengths/percentages; two keywords can be in either order (top left = left top)
3 valuesTwo keywords with one offset, e.g. center top 20px
4 valuesTwo keyword + offset pairs, e.g. right 10px bottom 20px
Comma-separated listOne position per background layer, in the same order as background-image
inherit, initial, revert, revert-layer, unsetGlobal CSS keywords

The longhands background-position-x and background-position-y accept the same values for a single axis. In the background shorthand, the position comes immediately before an optional / size: background: url(img.png) right 10px top 10px / 40px no-repeat;.

Advanced Positioning Techniques

Using calc() for Dynamic Positioning

The calc() function enables complex positioning calculations:

/* Position 20px from right and bottom edges */
background-position: calc(100% - 20px) calc(100% - 20px);

/* Center with offset */
background-position: calc(50% + 30px) calc(50% - 20px);

/* Responsive positioning */
background-position: calc(50% - 5vw) calc(50% + 2rem);

Multiple Background Positioning

/* Multiple backgrounds with different positions */
background: 
    url('icon1.svg') left top no-repeat,
    url('icon2.svg') right bottom no-repeat,
    url('icon3.svg') center center no-repeat;

/* Shorthand with position for each layer */
background: 
    url('top.png') 50% 0%,
    url('middle.png') center,
    url('bottom.png') 50% 100%;

CSS Sprites and Background Position

Background positioning is essential for CSS sprites, allowing you to display different parts of a single image.

/* CSS Sprite positioning */
.icon {
    width: 64px;
    height: 64px;
    background-image: url('sprite.png');
    background-size: 256px 64px;
}

.icon-home { background-position: 0 0; }
.icon-user { background-position: -64px 0; }
.icon-settings { background-position: -128px 0; }
.icon-mail { background-position: -192px 0; }

/* Hover states with sprites */
.button {
    background-position: 0 0;
}
.button:hover {
    background-position: 0 -50px;
}

Responsive Background Positioning

Mobile-First Approach

/* Mobile default */
.hero {
    background-image: url('hero.jpg');
    background-position: center center;
    background-size: cover;
}

/* Tablet and up */
@media (min-width: 768px) {
    .hero {
        background-position: center 30%;
    }
}

/* Desktop */
@media (min-width: 1200px) {
    .hero {
        background-position: center 20%;
        background-attachment: fixed;
    }
}

/* Using viewport units */
.responsive-bg {
    background-position: 50vw 25vh;
}

/* Aspect ratio aware positioning */
@media (aspect-ratio > 16/9) {
    .widescreen-bg {
        background-position: center 40%;
    }
}

Common Use Cases

1. Hero Images with Focal Points

/* Keep focal point visible on all devices */
.hero-image {
    background-image: url('hero-portrait.jpg');
    background-size: cover;
    background-position: center 30%; /* Face stays visible */
}

2. Parallax Effects

/* Parallax scrolling effect */
.parallax-section {
    background-image: url('mountains.jpg');
    background-attachment: fixed;
    background-position: center center;
    background-size: cover;
    min-height: 100vh;
}

/* Offset parallax layers */
.parallax-layer-1 {
    background-position: 50% 0;
}
.parallax-layer-2 {
    background-position: 50% -50%;
}

3. Icon Positioning

/* Icon in button */
.button-with-icon {
    padding-left: 40px;
    background-image: url('icon.svg');
    background-repeat: no-repeat;
    background-size: 20px 20px;
    background-position: 10px center;
}

/* Multiple icons in input */
.search-input {
    padding: 10px 40px;
    background-image: 
        url('search.svg'),
        url('clear.svg');
    background-position: 
        10px center,
        right 10px center;
    background-size: 20px;
    background-repeat: no-repeat;
}

Animating Background Position

Background position can be animated for dynamic effects like scrolling backgrounds or sprite animations.

/* Continuous scrolling background (tile is 200px × 200px) */
@keyframes scrollBackground {
    from { background-position: 0 0; }
    to { background-position: 200px 200px; } /* move exactly one tile for a seamless loop */
}

.scrolling-bg {
    animation: scrollBackground 20s linear infinite;
}

/* Sprite animation */
@keyframes spriteWalk {
    0% { background-position: 0 0; }
    100% { background-position: -512px 0; }
}

.character {
    width: 64px;
    height: 64px;
    background-image: url('character-sprite.png');
    animation: spriteWalk 1s steps(8) infinite;
}

/* Hover transition */
.hover-shift {
    background-position: center center;
    transition: background-position 0.3s ease;
}
.hover-shift:hover {
    background-position: center 40%;
}

Performance Optimization

Best Practices for Performance

  • Use transform instead of position for animations - Transforms are GPU-accelerated
  • Minimize repaints - Changing background-position triggers repaints
  • Preload critical images - Ensure images are ready before positioning
  • Consider will-change - Hint browser about upcoming animations
/* Performance-optimized animation */
.optimized-animation {
    background-image: url('background.jpg');
    background-position: center center;
    will-change: transform;
}

/* Use transform instead of background-position for animation */
.parallax-optimized {
    position: relative;
    overflow: hidden;
}

.parallax-optimized::before {
    content: '';
    position: absolute;
    top: -20%;
    left: -20%;
    width: 140%;
    height: 140%;
    background-image: url('large-bg.jpg');
    background-size: cover;
    transform: translateY(0);
    will-change: transform;
}

/* Reduce paint areas */
.icon-optimized {
    position: relative;
    padding-left: 30px;
}

.icon-optimized::before {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 20px;
    height: 20px;
    background: url('icon.svg') center/contain no-repeat;
}

Browser Compatibility

Background Position Support

Feature Chrome Firefox Safari Edge
Basic keywords & values ✓ 1.0 ✓ 1.0 ✓ 1.0 ✓ All
Four-value syntax ✓ 25 ✓ 13 ✓ 7 ✓ All
calc() in position ✓ Current ✓ Current ✓ Current ✓ All
Animation / transition ✓ Current ✓ Current ✓ Current ✓ All
/* Fallback strategies */
.background-position-safe {
    /* Old syntax fallback */
    background-position: right bottom;
    
    /* Modern four-value syntax */
    background-position: right 20px bottom 20px;
}

/* Feature detection */
@supports (background-position: right 20px bottom 20px) {
    .modern-position {
        background-position: right 2rem bottom 2rem;
    }
}

Common Pitfalls and Solutions

1. Percentage Confusion

/* Problem: Expecting a percentage to be a fixed gap from the edge */
.wrong {
    background-position: 95% 50%; /* Aligns the image's 95% point with the container's 95% point,
                                     so the gap changes with container and image size */
}

/* Solution: Use keywords or calc() for edge spacing */
.correct {
    background-position: right 20px center;
    /* or */
    background-position: calc(100% - 20px) center;
}

2. Mobile Background Positioning

/* Problem: Fixed positioning breaks on mobile */
.mobile-issue {
    background-attachment: fixed;
    background-position: center 30%;
}

/* Solution: Detect mobile and adjust */
@media (max-width: 768px) {
    .mobile-fix {
        background-attachment: scroll;
        background-position: center top;
    }
}

/* Or use feature detection */
@supports (-webkit-touch-callout: none) {
    .ios-fix {
        background-attachment: scroll;
    }
}

3. Sprite Calculation Errors

/* Problem: Wrong sprite calculations */
.sprite-wrong {
    background-position: 64px 0; /* Positive value moves the sprite right: shows the wrong icon (or empty space with no-repeat) */
}

/* Solution: Use negative values to show right portions */
.sprite-correct {
    background-position: -64px 0; /* Shows second sprite */
}

/* Helper mixin for sprites (SCSS) */
@mixin sprite($x, $y, $width: 64px, $height: 64px) {
    background-position: -($x * $width) -($y * $height);
}

Try It Yourself

Experiment with different positioning techniques in these interactive examples:

Custom Position Playground

Related Resources