72

I'd like to put an image as the background of a webpage but have it offset by some number of pixels with respect to the center.

How can I do this?

I want:

background-image: url("bg.png");
background-position: 25% center;
background-attachment: fixed;
background-repeat: no-repeat;

but instead of 25%, I want something along the lines of "center - 50px". Is there any solution to this?

sdleihssirhc
  • 42,000
  • 6
  • 53
  • 67
rhombidodecahedron
  • 7,693
  • 11
  • 58
  • 91
  • do you want to move the image to the left or right and keep white space around it? – JD Audi May 12 '11 at 17:22
  • 1
    Can you modify the image and add 50px of space to the right of it before setting it as the background image? Or is it a more complicated image? – novacara May 12 '11 at 17:23
  • If you want to move from left or right - CSS3 (imo better solution) here: http://stackoverflow.com/questions/3197250/position-a-css-background-image-x-pixels-from-the-right – jave.web Dec 26 '16 at 18:37

8 Answers8

100

I believe I have a solution that achieves what you're wanting:

A background image (specifically a page background) offset by a number of pixels with respect to the center.

This works using only HTML & CSS - no javascript required.


Update

This can now be easily achieved using background-position and calc as a CSS unit.

The following CSS will achieve the same outcome as the previous solution (see "Original Solution" below):

#background-container {
    width: 100%;

    background-image: url("background-image.png");
    background-position: calc(50% - 50px) 50%;
    background-repeat: no-repeat;
}

Note: Don't use this method if you require support for legacy versions of IE.


Original Solution

#background-container {
    width: 100%;
    left: -100px; /* this must be TWICE the required offset distance*/
    padding-right: 100px; /* must be the same amount as above */

    background-image: url("background-image.png");
    background-position: center;
    background-repeat: no-repeat;
}

What this does is moves the entire container horizontally by the amount specified (in this case to the left 100px). Because the background image is centered relative to the container it moves to the left with the container.

The padding fixes the 100px of blank space that would appear to the right of the container as a result of the move. Background images show through padding). Because browsers use the border-box value instead of the default content-box value to calculate background sizing and positioning, the background image is effectively moved back to the right 50px - half the distance of the padding. (Thanks to ErikE for clarification).

So your offset/padding must be twice the required offset distance.

I have prepared a sample page for you here: http://www.indieweb.co.nz/testing/background-offset-center.html

Have a play with resizing the window. You will see that the purple and blue background image (laid over a deeper background image marking the center of the page) remains exactly 50px (half the offset/padding distance) to the left of the page center.


HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
Luke
  • 4,825
  • 2
  • 30
  • 37
  • 1
    This should be the correct answer. Of course the other answer, adding negative space to the image to achieve offset is viable, but this is more correct from a "How do I achieve this effect with only code?" standpoint. – Brian Apr 07 '13 at 08:12
  • 1
    Technically, padding does not "add to the overall container width" in the way you stated. Your fix still works because background images show through padding, and therefore all browsers (apparently and specially) use the border-box instead of the content-box for calculating background sizing and positioning. In general CSS positioning, padding only "adds to the overall container width" in Internet Explorer, because it uses `box-sizing: border-box` instead of what the other browsers use, `box-sizing: content-box`. – ErikE Jul 15 '13 at 19:33
  • 1
    It's worth noting that this will only allow you to nudge the image towards the left. This works perfectly for me to go to the left, but stretches the page if you're going to the right. – Mike B Nov 21 '13 at 16:52
  • Will this solution work with a FIXED background-attachment? The padding and position will be ignored if the background sticks to the relatively positioned parent. Maybe the trick should be done on that parent? – sergio Jun 09 '15 at 16:11
  • I had trouble using this to center with a _horizontal_ offset (a la `background-position: top calc(50% - 50px)` but I found that `background-position-x: calc(50% - 50px)` works perfectly (in Chrome 60 at least) – Rebecca Scott Aug 29 '17 at 02:13
  • @BenScott did you try `background-position: calc(50% - 50px) 0%;` ? The first value in the background-position property is the x axis and the second is the y, so I wouldn't expect your example of `background-position: top calc(50% - 50px);` to work. – Luke Aug 29 '17 at 12:09
51

Using background-position: center; is the same as background-position: 50% 50%;.

So you can use calc to do some simple math in CSS as a replacement for any length value, for example:

background-position: calc(50% - 50px) 50%;

Will center the background image, but shift it 50 pixels to the left.

hynick
  • 775
  • 8
  • 14
  • 1
    This worked perfectly for my situation, thank you! However, it's worth noting that [`calc()`](https://developer.mozilla.org/en-US/docs/Web/CSS/calc) is currently considered experimental and isn't [universally supported](http://caniuse.com/#feat=calc). – Nick Spreitzer Nov 01 '14 at 20:45
  • 3
    Great answer. There is pretty good support for `calc()` now in 2016: http://d.pr/i/GrAk – Clifton Labrum Mar 09 '16 at 06:50
  • NB: Partial support in IE9 refers to the browser crashing when used as a background-position value. (source: caniuse.com). Calc is supported by browsers as primitiv as IE9, but IE9 does not support calc when used on background-position. – clearfix Apr 12 '16 at 09:35
  • FYI: testing in Browserstack, it doesn't crash my IE9 (I am using `background-position-x` and `background-position-y` explicitly). So maybe it got fixed or only applies to certain circumstances? – sthzg Jun 29 '16 at 09:41
4

So you want it centered by shifted 50 pixels to left. I would add the 50 pixels to the image in the form of a transparent space, unless you are dealing with absolute dimensions.

Dustin Laine
  • 37,935
  • 10
  • 86
  • 125
-1

if you know the width of the image you can use this:

background-position: (BgWidth - 50)px 0px;

Note that you can't have it like that, i.e. you need to calculate (BgWidth - 50) and then write the number there.

If you don't know the width you can use Javascript(with-or-without jQuery) and then use this:

$(#ID).css('background-position', (BgWidth - 50)+'px 0px');
Jonathan J
  • 105
  • 1
  • 7
-1

Nice answer Luke,

one more thing, if your block width is larger than screen resolution, your must put your block in another container and do this:

#container{
  position:relative;
  overflow:hidden;
}

#shadowBox{
  width: 100%;
  left: -100px; /* this must be TWICE the required offset distance*/
  padding-right: 100px; /* must be the same amount as above */
  background-image: url("background-image.png");
  background-position: center;
  background-repeat: no-repeat;
  position:absolute: /*this is needed*/
}
Mohd Sakib
  • 471
  • 5
  • 11
-1

My answer gotta be too late but somehow I've found another solution.

padding-left: 100px; /* offset you need */
padding-right: 100%;

or

padding-right: 100px;
padding-left: 100%;

The examples have the same effect.

Yan Ivanov
  • 196
  • 15
-1

There's no obvious CSS answer. You would either need to use JavaScript to calculate values or do something tricky. You can try keeping the background-position:25% center and adding position:relative;left:-50px or margin-left:-50px but those might not work depending on how you are using the DOM element.

Jeff
  • 13,943
  • 11
  • 55
  • 103
-1

The only method I've found for this is to have the background inside another div, then use javascript to reposition ...

<style>
    body {
        width: 100%;
        overflow: hidden;
        }
    #bg {
        position: absolute;
        background: url(images/background.jpg) center top;
        }
</style>

<script>
    function recenter(){
        var $pos = $('#content').offset().left;
        $('#bg').css('left',$pos-580);
    }
    recenter();
    $(window).resize(function(){ recenter(); });
</script>

<body>
    <div id="bg"></div>
    <div id="content">
        blah
    </div>
</body>
designosis
  • 5,182
  • 1
  • 38
  • 57