3

I am creating a web page which currently looks like the following image:

enter image description here

What I am trying to do now, is replace the grass image with two or more alternating background images. These images must be repeating in the x direction. Example:

bg repeating

The gray background and the gradient between the grass and the gray background can be ignored. All background images are 260x650 pixels in size and the number of images is static.

What I have tried, is creating a background like this:

background: url('bg1.png') 0 0 no-repeat, url('bg1.png') 260px 0 no-repeat

The problem is I cannot set repeat-x, because there has to be a margin of 260px between the images. This answer to other question states there is no such margin. I would prefer not to combine the images in a single image.

My resources are plain JavaScript, CSS and HTML. My target browsers are relatively new(IE 9, but preferrably 8), so don't worry about old quirks.

Community
  • 1
  • 1
Aart Stuurman
  • 3,188
  • 4
  • 26
  • 44
  • It's way simpler to edit the image and add some transparent margins... – MaxArt Jun 11 '13 at 22:43
  • I understand this, but I want my user to be able to change the images. – Aart Stuurman Jun 11 '13 at 22:45
  • i do not understand http://www1.picturepush.com/photo/a/13298504/img/Anonymous/background.png, do you want a real gap in betwwen, or should they overlap some how. (different background-size only for width could be okay with grass design) ? :) If you want gaps like a grid , extra image over it will do it – G-Cyrillus Jun 11 '13 at 22:50
  • So the user can upload his own image or something like that? You could rely on some server-side image manipulation plugin, or resolve on Javascript composing the `background-image` and `background-position` style properties (`background-repeat` can be set to `no-repeat` separately). – MaxArt Jun 11 '13 at 22:52
  • @GCyrillus I'm not sure if I unserstand what you mean. I want the images to alternate directly after eachother until the whole screen is filled. – Aart Stuurman Jun 11 '13 at 22:54
  • @MaxArt I'll have a look into some server side code to combine the background images into one later if I can't figure out how to do it without. Thanks for the suggestion. – Aart Stuurman Jun 11 '13 at 22:57
  • @MaxArt How would you see javascript composing those properties? Create an event listener and append more background images is the best thing I can think of. This doesn't seem very nice to me though. – Aart Stuurman Jun 11 '13 at 23:06
  • @AartStuurman Yes, it's ugly. But effective. Sometimes you have to accept some compromises... – MaxArt Jun 11 '13 at 23:09
  • Alright, I'll check it out. – Aart Stuurman Jun 11 '13 at 23:13
  • @Aart Stuurman, okay, i get it , images would need to be same size with alternate half width transparent , to show half side of each others. If thats not possible, you need javascript :(. Thx to have made it clear to me :) – G-Cyrillus Jun 11 '13 at 23:19

2 Answers2

3

See demo here.

Here's a function you can use:

function changeBodyBackground() {
    var images = ['http://goo.gl/tQl3t', 'http://goo.gl/6t3lG',
                                                          'http://goo.gl/HDzqs']
    var imagesWidth = 260;
    var screenWidthToCover = 3000; // the max resolution expected
    var i = 1, backgroundStyle = 'url("'+images[0]+'") 0 0 no-repeat';
    while (i*imagesWidth < screenWidthToCover) {
        backgroundStyle += ', url("'+images[i%images.length]+'") '
                                               +(imagesWidth*i)+'px 0 no-repeat';
        i++;
    }
    document.body.style.background = backgroundStyle;
}

Edit the images array with the URL of the images you need. They will be placed side-by-side with the order given in the array. Also, the spacing between the images is defined by the imagesWidth variable.

In the demo the background is being set when the button is clicked. You can, of course, call the function at the <head>, if you want the background images to be loaded right away.

acdcjunior
  • 132,397
  • 37
  • 331
  • 304
  • This is great! Pretty much what I was thinking about after what MaxArt said. I'll see if I can chance this a bit, so it'll wait for a window resize, after which it will append more images if needed. – Aart Stuurman Jun 11 '13 at 23:35
  • Also, thanks for the image edit. I'm too young for showing them directly. – Aart Stuurman Jun 11 '13 at 23:36
  • Yeah, np. Maybe I can help with the tweak as well, so don hesitate to come by! Cheers! – acdcjunior Jun 12 '13 at 00:17
0

After playing arround with the ideas acdcjunior and MaxArt gave me, I ended up creating a header element at the top of the page, and filling this with divs with a background image. I used divs instead of a long background style, because I find this way more convenient. This way I don't have to worry about the background image size, even though I specified in my question they all had the same size.

My HTML structure looks like this:

<header><div class=bg data-bgNumber=1 style="background-image:url('header1.png')"></div></header>

CSS:

header {
    white-space: nowrap;
    height: 260px;
    display: inline-block;
    max-width: 100%;
    overflow:hidden;
}

header .bg {
    width: 650px;
    height: 260px;
    display: inline-block;
    background: no-repeat center;
    background-size: cover;
}

JS for the header class:

function Header() {
    this.header = document.body.getElementsByTagName('header')[0];
    this.makeHeader(4);
    window.onresize = function() {
        this.makeHeader(4);
    }.bind(this);
}
Wrapper.prototype = {
    makeHeader: function(difBgCount) {
        while(this.header.offsetWidth < document.body.clientWidth) {
            var bg = 1+this.header.lastElementChild.getAttribute('data-bgNumber')%difBgCount;
            this.header.innerHTML += '<div class=bg data-bgNumber='+bg+' style="background-image:url(\'header'+bg+'.png\')"></div>';
        }
    }
}

Then, when your document is ready, you create a new instance of the header class, and everything will go fine:

var header;
function onBodyLoad() {
    wrapper = new Header();
}

The argument for the makeHeader function is the amount of different background images. These images must be named 'header1.png', 'header2.png', etc, but it should not be hard to change the name and extension, if you want to have it named differently.

Finally, it looks like this, when the images are of different sizes: No zoom

And zoomed out: enter image description here

Aart Stuurman
  • 3,188
  • 4
  • 26
  • 44
  • There was a bug in this, that if the last image was too big to fit on the page, a horizontal scrollbar would appear. I fixed this by applying max-width:100% and overflow:hidden to the header tag. I also fixed a small bug where the calculation would use the screen width plus the scrollbar, which would create an infinite loop. – Aart Stuurman Jun 12 '13 at 16:38