Web Hosting Forum | Lunarpages


*
Welcome, Guest. Please login or register.
Did you miss your activation email?



Login with username, password and session length
February 09, 2012, 05:52:12 PM

Pages: [1]   Go Down
  Print  
Author Topic: Column balancing in CSS  (Read 1664 times)
MrPhil
Berserker Poster
*****
Offline Offline

Posts: 5083



« on: February 10, 2010, 05:46:58 PM »

I am trying to build a two-column list of items, by state:

+----------------------+  +-----------------------+
| AL  Alabama          |  | AL  Alaska            |
|                      |  |                       |
| * item 1             |  | * item 1              |
| * item 2             |  | * item 2              |
| * item 3             |  +-----------------------+
| * item 4             |  +-----------------------+
| * item 5             |  | AZ  Arizona           |
| * item 6             |  |                       |
+----------------------+  | * item 1              |
+----------------------+  | * item 2              |
| AR  Arkansas         |  | * item 3              |
|                      |  | * item 4              |
| * item 1             |  +-----------------------+
| * item 2             |  +-----------------------+
| * item 3             |  | CA  California        |

etc.

Each state has a different number of items (links) in an unordered list (which will vary from time to time), and the length of each line (in characters) varies. I need to keep the states in alphabetical order, such that the next state name (not abbreviation) is either to the right (if at the same Y-position down the page) or below the previous name. That is, you would never go just left, or left and up, to get from one state name (top of <div>) to the next. You go down, or right, or right and down, or left and down. The overall column lengths will be different (no state wraps from one column to the next).

Currently I have it working for a fixed width display, but I'd like to make it work when resized. It's a <div> (width 100%, no margins or padding) containing two side-by-side <div>s (at top 0/left 0 and top 0/right 0) of 50% width and no margins or padding. Each state gets its own <div>, with some margin around it. When building the lists, I count the number of items and add a fixed fractional number of "lines" for title, vertical margins, vertical padding, etc., and call that the overall height of the state's <div>. I keep a running tally of the height (lines) in each column and place the next state in the shorter column.

By tweaking the fixed "lines" amount, it works properly for a display of fixed width. However, when the browser window is resized, some longer item lines start to wrap around, throwing off the line count and running offset, resulting in states that are out of order (e.g., Indiana further up the page than Illinois). So my question, after all these preliminaries, is can I reflow varying height <divs> as the window width changes? Is this a job for Javascript? Each state's <div> will varying in height as the available width changes, due to line wraps. I guess I could either force a fixed width (which is ugly, especially on a mobile device), or use a fixed-pitch font and try to anticipate where lines are going to wrap, and adjust the line count accordingly, or.....? I must keep the states in alphabetical order, which means switching them between left and right columns as their heights change by different amounts. The two columns can have a minimum width, just to prevent an absurd amount of wrapping on longer lines.

Is this something that CSS can handle, or is it a lost cause? Has anyone seen Javascript code that could get the absolute height of a <div> and adjust its "top" value to place it in the right place on the screen, in the correct column (left: 0 or right: 0), so that they stay in the desired order? If so, I suppose I could output the list as one long vertical single column (of final width), and upon load (or resize) go through and build a list of <div> sizes, and then place them left or right as needed to balance while staying in order. Or, am I better off somehow using Javascript to report the actual column widths or <div> lengths back to the PHP code, and rebuilding in the necessary order?

One other possibility that occurs to me is to make each state full page width, and within that <div> make two columns. However, I think I'll run into the same problem as lines wrap and the number of displayed lines change in each column by different amounts. At least, the problem of keeping states in order goes away, but within each state, the items still have to be kept in alphabetical order. Under most circumstances, only a small fraction of the lines wrap around, so I really don't want to go to full width states with only one column each (the list becomes too long, and has too much empty space). The client wants it all on one page, which is why I'm doing two columns.

Thanks much for any thoughts on this, or pointers to code or relevant tutorials.
Logged

wektech
Master Jedi
*****
Offline Offline

Posts: 1031



WWW
« Reply #1 on: February 12, 2010, 06:22:02 AM »

Not sure if this will help but I dealt with a similar situation with 3 columns on http://yumazone.com/todo.htm. While not perfect I found that using inline-block divs seemed to give the best results.
Logged

MrPhil
Berserker Poster
*****
Offline Offline

Posts: 5083



« Reply #2 on: February 12, 2010, 08:07:21 AM »

Thanks, but you're balancing all three across to be the same height, which means empty space on the shorter content. I'm looking to pack as tightly as possible, while maintaining a certain order of blocks. Some state blocks may be literally 10 or 15 times longer than others, so equal lengths would look awful.

For the time being, I think I'll have to go with a fixed width layout, and manually count the number of wrapped lines and add that into the "overhead" count of each block. Since the length of each block will vary due to line wrapping with each change in column width (or font change, or content change), I suspect that I'm going to have to go Javascript with this one -- maybe after load or resize, find the height of each block (<div>) and calculate a new order and adjust the style.top and place in left or right column (style.left=0 or style.right=0). Does anyone have any suggestions on this one? Will browsers wait until all the shuffling is done before re-rendering, or will it look like a Tetris game gone amok?
Logged

Pages: [1]   Go Up
  Print  
 
Jump to: