views:

161

answers:

4

I have a 700x300 background repeating seamlessly inside of the main content-div. Now I'd like to attach a div at the bottom of the content-div, containing a different background image that isn't repeatable, connecting seamlessly with the repeatable background above it. Essentially, the non-repeatable image will look like the end piece of the repeatable image.

Due to the nature of the pattern, unless the full 300px height of the background image is visible in the last repeat of the content-div's backround, the background in the div below won't seamlessly connect. Basically, I need the content div's height to be a multiple of 300px under all circumstances. What's a good approach to this sort of problem?

I've tried resizing the content-div on loading the page, but this only works as long as the content div doesn't contain any resizing, dynamic content, which is not my case:

function adjustContentHeight()
{
    // Setting content div's height to nearest upper multiple of column backgrounds height, 
    // forcing it not to be cut-off when repeated.

    var contentBgHeight = 300;
    var contentHeight   = $("#content").height();
    var adjustedHeight  = Math.ceil(contentHeight / contentBgHeight);

    $("#content").height(adjustedHeight * contentBgHeight);
}

$(document).ready(adjustContentHeight);

What I'm looking for there is a way to respond to a div resizing event, but there doesn't seem to be such a thing. Also, please assume I have no access to the JS controlling the resizing of content in the content-div, though this is potentially a way of solving the problem.

Another potential solution I was thinking off was to offset the background image in the bottom div by a certain amount depending on the height of the content-div. Again, the missing piece seems to be the ability to respond to a resize event.

+1  A: 

Another approach is to calculate the background-position style for the bottom and top DIVs based on the size of the content DIV. You can use negative positions to align the bottom of one to the top of another.

Yet another approach is to use a layered DIV approach in which the top, content and bottom are all children of a parent DIV that contains the background.

The benefit of these approaches is that it doesn't change the natural rendering of the content DIV simply for managing the background.

Example: http://bin.googlecode.com/svn/trunk/css/repeating-bg-content.html

nicerobot
Thanks, but it doesn't address the seamless issue.
Stiggler
It most certainly does if you position the x and y appropriately. That is, based on the size of the content div, you can calculate exactly where the background ends and position the other divs to position the origin so that they match exactly.
nicerobot
But what if the content div is resized dynamically? Please refer to the part of my question below the code; I think you may have overlooked it as it already proposes your first suggestion, including what's problematic with it.
Stiggler
If you are resizing a div, there are two reasons. The window resizes or you are manipulating the content. Both have events points. One provided by the browser, the other provided by the developer (that is, you are changing the content so you know to manage the div). With JavaScript, you ALWAYS have control. You can replace any function with your own wrapper or completely replace the function. Might be a PitA with lame libraries but it's always possible.But why not use the second alternative? Just move the divs to be children of a parent and give the parent the background.
nicerobot
The JS that dynamically resizes the content is from the CMS I'm using. I'm curious whether this can be done without resorting to hacking 3rd party code.Sorry, but I don't understand how the second alternative solves the issue: I'm working with multiple backgrounds that cannot be merged into one. In other words, there's one repeatable and one non-repeatable background, both of which must merge without a seam.
Stiggler
You're right. The second alternative doesn't solve it because i didn't understand that "continuation-to-end" means a different image than the content div's repeating image. I think multiple divs and layering divs will be the solution. For example, layering opaque over the portions of the top/bottom. And look at how borders with rounded corners used to be implemented with multiple slices of images. And i believe, if you insist on solving this javascript, i think it'll require dynamically creating images.
nicerobot
Dynamically creating images sounds rough; I think I'd rather hack 3rd party code. :)
Stiggler
Btw, I've updated the question to make what I need clearer. Thanks for the feedback!
Stiggler
Here's an example of what i imaging you're looking for: http://bin.googlecode.com/svn/trunk/css/repeating-bg-content.html it isn't perfect but it gets the point across that javascript isn't the solution. It's simply a matter of structuring the content and styling them appropriately. If you can't accomplish that with your CMS, you might want to consider a different CMS solution.
nicerobot
Thanks, but I don't think that's what I'm looking for. As far as styling and structuring goes, the CMS doesn't reign me in.
Stiggler
Well, good luck to you.
nicerobot
A: 

Could setting background-position: fixed in your css help? Then your bottom div could move, but its background image would remain fixed in relation to the top of the page. As more of your repeating image was revealed, so more of your bottom image would be hidden.

This would comes under the heading of "offset the background image in the bottom div by a certain amount depending on the height of the content-div", rather than "the content div's height to be a multiple of 300px under all circumstances".

action_ben
Sorry, but I'm not sure I understand how this is supposed to work... Do you mean 'background-attachment: fixed'? How is bottom-div's background image gradually hidden?
Stiggler
You're right, I did mean background-attachment. I was thinking of the effect demonstrated on the apparently-transparent menu items on this page:http://meyerweb.com/eric/css/edge/complexspiral/demo.htmlThinking about it now, though, I don't think it would work in your situation. I was confusing "scrolling" with "changing position relative to other content".
action_ben
A: 

You could try adding an event listener to the div:


        var div = document.getElementById("content");
        div.addEventListener("resize", adjustContentHeight, false);
Angie
Supposedly, the resize event doesn't apply to divs:http://stackoverflow.com/questions/229010/jquery-resize-not-working-at-firefox-chrome-and-safari
Stiggler
Hmm. Well I guess that's what I get for trusting w3schools instead of testing it myself. They've got resize as applying to all HTML elements: http://www.w3schools.com/jsref/dom_obj_all.asp
Angie
A: 

If nothing needs to match up at the top, position the repeating image at the bottom of the div (so the overflow will spill over the top). Like this:

div#repeating { background: transparent url('/path/to/image') repeat left bottom; }

kingjeffrey
Yeah, I just saw Pekka's comment above. Sorry for the duplication.
kingjeffrey