split backgrounds

Sometimes css tricks just work. You hit a certain problem, take a few good minutes to think it over, devise a css solution ... and it works. These cases are quite rare indeed, but they do exist. And as these examples are particularly fun to share with others, here goes. This article will demonstrate a little trick splitting a background into two parts while keeping it flexible in width.

split issue

A few days ago I received a design for a splash page. The page functioned as an entrance to two different (but closely related) sites. To accentuate the split the design of the splash page was cut in the middle, each side using its site-specific color scheme. The design was screen-filling, meaning that the left half of the screen featured one color, the right half the other color. Sadly there is no easy way to accomplish this in css.

.container {background:url("...") 50% top repeat-x;}

The problem lies with the background-repeat property, which is unable to repeat a background from a specified point. It can only repeat across a whole axis. If you look at the code above you could assume that the background would be repeated across the x-axis starting 50% from the left base point. Sadly this doesn't fly. No matter what value you state for the left parameter, the background will be repeated across the entire x-axis.

split solution

After some pondering the solution proved to be quite simple, though it does require an excessive amount of structural elements. The method is not much different from creating a two column grid, only now we're not going to create separate columns.

<div class="container"> <div class="wrap1"> <div class="wrap2"> ... </div> </div> </div>

The code above will be used to create the wanted effect. It's a simple setup of three nested divs.

.container {background:#0f0; /* right */} .container .wrap1 {width:50%; background:#f00; /* left */} .container .wrap2 {margin-right:-100%;} /* ie6 negative margin fix*/ .container .wrap2 {position:relative; zoom:1;}

We start by applying a base color to the container div. To create the split, we nest an extra div, make it 50% wide and apply a different background color to it (which will visually create the left column). To finish it off, we nest another div to pull the content back to the entire width. Some very simple math tells us we need a negative right margin of -100% to accomplish just that.

We are now back to square 1, only with the background in place, forming a perfect, screen-wide 50% split that goes on forever. Of course a small fix is needed for ie6 as we're working with negative margins, but all that is needed is a pos:rel and zoom:1; which always does the trick when fixing negative margins in ie6.

check out the test page


As you can see, you need quite a few structural elements to pull this trick off, so use it only when necessary. If you have to create this effect within a 100px wide element it might be better to simply cut a background that's wide enough. But if you don't mind the extra divs, this is a simple css method that works like a charm and lets you keep all control in css.

You can play with the effect by adding background images (fades) or playing with the split widths. A 25-75% split will need a right margin of -300% so make sure you'll keep the math correct when doing this.

The next couple of weeks I'll be quite busy with enjoying my vacation, so this will be the last work update for three weeks. Until then!