neeh
neeh

Reputation: 3025

How to center a background div?

What I want

two div : A page body (1) and a background block (2)

Desired layout

Constraints

What I tried

Page body CSS:

#pageBody {
    width: 820px;
    margin: 0 auto;
}

Background block CSS:

1. A full-page div which displays a CSS centered background

<div id="backgroundBlock"></div>
<div id="pageBody">
</div>
#backgroundBlock {
    background: no-repeat center 0 url(bg.png);
    width: 100%;
    height: 100%;
    position: absolute;
}

But when the window's size is odd:

2. A repositioned child div

<div id="pageBody">
    <div id="backgroundBlock"></div>
</div>
#backgroundBlock {
    background: no-repeat url(bg.png);
    width: 2560px;
    height: 780px;
    position: absolute;
    margin: 0 0 0 -870px;
    overflow: hidden;
}

But problem: the scroll bar appears for the background block...

Upvotes: 4

Views: 2513

Answers (1)

Bali Balo
Bali Balo

Reputation: 3408

Here are a few ideas I could think of, with their issues. However, I could not reproduce the "blurry in IE" issue, so I don't know which solution have it or not.
I did put "Extra markup" as an issue for solutions including a div (#backgroundBlock) only used to display the background image, as it is not semantic.


Solution 1 (jsfiddle)

  • Description : Your first solution
  • Issues :
    • Extra markup
    • On Chrome, depending on the page size, pixels can be aligned differently. You can see it on jsfiddle near the right border : pixel problem

Solution 2 (jsfiddle)

  • Description : Multiple-backgrounds on body. #backgroundBlock div not needed.

    body {
        background: no-repeat center top url(bg.png), url(bodybg.png);
    }
    
  • Issues :

    • Not compatible with old browsers (IE8, FF3.5, ... ; source)
    • On Chrome, same alignment problem as in solution 1

Solution 3 (jsfiddle)

  • Description : Use of translate. No more pixel alignment errors.

    #backgroundBlock
    {
        background: url(bg.png);
        width: 2560px;
        height: 780px;
        position: absolute;
        top: 0;
        left: 50%;
        transform: translate(-50%, 0);
    }
    
  • Issues :

    • Extra markup
    • You have to use overflow-x: hidden on body to avoid horizontal scrollbar
    • Not compatible with old browsers (IE8, FF3, ... ; source). You should also use prefixes for compatibility (-webkit-, -moz-, ...). I did not add them to keep the example simple

Solution 4 (jsfiddle)

  • Description : Use of translate and ::before. Alternative version of solution 3. Pseudo-elements compatibility are not an issue here since every browser supporting 2D-tranforms supports ::before (source).

    #backgroundBlock
    {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        overflow: hidden;
    }
    #backgroundBlock:before
    {
        content: '';
        background: url(bg.png);
        width: 2560px;
        height: 780px;
        position: absolute;
        top: 0;
        left: 50%;
        transform: translate(-50%, 0);
    }
    
  • Issues :

    • Extra markup
    • Not compatible with old browsers (IE8, FF3, ... ; source). You should also use prefixes for compatibility (-webkit-, -moz-, ...). I did not add them to keep the example simple

There are other possibilities but I think most of them would have one of the above issues.
For example, you could set the #pageBody width to 2560px, set the background on it, add padding to have a content size of 820px and translate it in order to have it centered on the page (and prevent horizontal scrollbars using overflow-x on body). This would be possible because the background image and page body both have fixed width.

Upvotes: 2

Related Questions