CSS positioning - unnesting a nest

We do just enough CSS to be dangerous. And we’ve got a weird problem between css & JS that got bubbled up to me. And I’m more of a CSS noob than a pro, particularly when it comes to the black art (to me) of positioning.

We have html like this:


<div id='outer'>
content1
  <div id='innerA'>content A</div>
  <div id='innerB'>content B</div>
content2
</div>

Which renders lke
content1
contentA
contentB
content2

So far so good. That’s what we want.

But … one customer wants it to render like
content1
content2
contentA
contentB

We’d like to drive this change solely through CSS just for that one customer. If absolutely necssary we could break the nesting of the divs, provided we could retain the original appearance via changed CSS for everybody else.
Just a couple small complicators …

Run time JavaScript on the page generates all these divs and resizes them on the fly. E.g. the JS creates <div id=‘outer’ style=‘width:###px; height:###px’> where the ### is dynamically calculated based on external factors. The script then pokes the div (and its children) into the DOM.

And the four content pieces are dynamic too. So there are no fixed sizes of anything which can be embedded in the css as offsets.

I’m trying to avoid smartening the JS if possible since there are an infinity of positioning options customers might want. If CSS can handle it, that leaves all the heavy lifting to that infrastructure rather than our code.

Anybody wanna take a crack at it?

Could you do something where the contents of #innerA and #innerB are duplicated as #innerC and #innerD…and for some customers, #innerA and #innerB are display: block while #innerC and #innerD are display: none, and vice versa?

Add a container:



  <div id='outer'>
  content1
  <div id='inner_container'>
    <div id='innerA'>content A</div>
    <div id='innerB'>content B</div>
  </div>
  content2
  </div>


You have to define the position style of the outer container
#outer {position:relative}
And the inner gets an abosulte position and since its parent has a position property, the inner container’s position is relative to its parent. (I know, it’s counterintuitive)
#inner_container {position:absolute;left:0px}

Then you need a little Javascript to assign the ‘top’ property of the inner container to a value that places it at the bottom of the ‘outer’ container

document.getElementById(‘inner_container’).style.top = document.getElementById(‘outer’).style.height + “px”;

or if you know what the height is supposed to be for ‘content1’ and ‘content2’, just add those values together and that’s your position for the inner_container.

You may also want to try

Dynamic Drive Forums

These people are great at helping you with CSS, XHTML, JavaScript you name it

Thanks folks.

What I really want is CSS to be able to say “position *this *relative to that, not to its container”. But that doesn’t seem to be on offer.

Both of the ideas above solve the specific problem, but not the general problem of moving all the divs around relative to each other in any arbitrary manner for any customer.

(The actual problem has about 15 of them, so you can see coding JS for all possible permutations of arrangements of the divs is a non-starter. And we try very hard to never solve a one-off problem with a one-off patch; we alway want to to end up with a general solution to the general problem.)

I have until Monday to come up with an attack plan, so please keep the ideas coming. Hell, we may find it easier to generate the css dynamically too. Or tell me to abandon hope of a generalized CSS-centric solution.

Thanks again …

Thanks. Done.

I don’t think CSS is the right tool for this.

To quote your post from DD:

If there’s “an infinity of positioning options”, it sounds like you actually need a very lightweight templating system. If you’re already going to have to customize output for each customer individually, you might as well give each one their own HTML or JavaScript template instead of a different CSS stylesheet. The idea is the same and the former will give you much more flexibility.

The templates themselves can be as simple as:



Customer 1:
1
2
3
4

Customer 2:
1
4
2
3


And your script will look at those and output accordingly. If you want to add left-right arrangements as well, just build that into your templating system too. Then you’ll be modifying the simple plain text templates in the future instead of fiddling with your main script every time.

Yeah, that’s the approach I was afraid we’d end up with. Which is a larger swamp of uncertain depth. We were hoping for an a cheap fix where the only thing really needed was more knowledge on our part.

Knowing which wall *not *to bang one’s head against is darn valuable advice.

Oh well. Thanks again.