I can't figure out how to achieve the following layout with CSS (probably because I don't actually know CSS).
I have a bunch of divs like this:
<div class="right"> <p>1</p> </div>
<div class="left"> <p>2</p> </div>
<div class="left"> <p>3</p> </div>
<div class="left"> <p>4</p> </div>
<div class="right"> <p>5</p> </div>
<div class="right"> <p>6</p> </div>
(not the real contents)
Now I want the layout to look like two equal columns of divs, with the "right" ones on the right, and the "left" ones on the left, thus:
2 1
3 5
4 6
[Edit: In a previous version of this question I had textareas inside the divs, and the divs all had different names like "one" and "xyz".] I tried something like
div.right { width:50%; float:right; clear:right; }
div.left { width:50%; float:left; clear:left;}
but it doesn't quite work: It produces something like:
2 1
3
4 5
6
(without the "clear"s, it blithely produces
2 1
3 4
6 5
which is not what is wanted).
It is apparent that it can be made to work if the divs are ordered differently, but I'd like not to do that (because these divs are generated dynamically if the browser has Javascript, and I don't want to change the actual order that is displayed in the absence of Javascript, for semantic reasons). Is it still possible to achieve the layout I want?
[For what it's worth, I'm willing to have it not work on IE or older versions of other browsers, so if there is a solution that works only on standards-compliant browsers, that's okay :-)]
Check out the 960 Grid System. I have used this on projects in the past and I have to say it works pretty well. Not only that, it is easy to use and is consistent across browsers :D
Using this framework:
alt text http://img40.imageshack.us/img40/6889/cd3cc920a04b80e06b8efef.png
The bar on top of the text is from my browser, not part of the CSS or layout.
You have Javascript - why not use it?
You said this:
You're only displaying these
<div>
s if the user has Javascript - why not use Javascript to rearrange them? If you move #4 to be after #5, it looks fine with your current CSS.So (with jQuery):
I felt guilty that the pure css method didn't work, but if you don't mind using JavaScript to get what you're after, then here's some jQuery that'll work (someone else will probably be able to clean this up for you if you don't like the bloat).
I'll leave the rest of this answer in place so that someone else can see what my initial thoughts were, but this approach actually fails and requires that there are always more floating elements than none floating.
I think this is your solution (not tested).
The 51% stops them from floating next to each other and then just let all the .right content wrap up around those floated blocks.
Thinking less often gives you more with HTML/css, and again - NO to using tables for layout.
===[edit]===
I ran a test on this and it does work with a couple of tweaks AND if you know the first item is floating left (or right to reverse the behavior).
Tables are a perfectly acceptable solution for this IMHO.
The backlash against tables was directed towards using them for the entire site layout. But if you need to display your data in rows and columns...... that's what tables were made for :)
If you still are interested in a viable cross browser CSS solution I would look at using a framework. It will save you hours of time in trying to get your page to look right.
http://www.blueprintcss.org/ is an excellent framework IMHO.
Solution 1
If you can afford to duplicate HTML:
Solution 2
Wait a little until browsers support CSS3:
Solution 3
If your divs have the same height, use the indirect adjacent sibling combinator. Even though it belongs to CSS Level 3, it's already well-supported: