Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

CSS question: Displaying 2-level unordered lists in a table layout? 1

Status
Not open for further replies.

Katerine

Programmer
Mar 9, 2001
234
US
Hi,
I have a new website that, because of reasons, I'd really like to use ul tags and have it display however I want with css, if at all possible. :)

In that vein, I have something like the following code:
HTML:
<ul class="level1listing columns 3cols">
<li id="col1head" class="header">Header for column 1</li>
<ul class="level2listing list">
<li id="col1item1" class="none">First item in column 1</li>
<li id="col1item2" class="none">Second item in column 1</li>
</ul>
<li id="col2head" class="header">Header for column 2</li>
<li id="col3head" class="header">Header for column 3</li>
</ul>

Basically, if the top-level ul (in this case, belonging to class level1listing, though that can change) has the class "columns," then I want the list underneath it to display in a table layout:
[pre]
-------------------------------------------------------------------
| Header for column 1 | Header for column 2 | Header for column 3 |
-------------------------------------------------------------------
| First item in | | |
| column 1 | | |
| Second item in | | |
| column 1 | | |
-------------------------------------------------------------------
[/pre]

Basically, the reason for this is that the underlying code needs to be able to iterate through a recordset and handle records returned in the above order in all cases (not just the relatively-rare column layout cases), so I really need something that can handle html that's written in that order. If I can keep using ul tags instead of, say, divs (or heaven forbid, tables, which would be... kind of impossible, actually, with the way the recordset is ordered), that would be great. I could switch to divs if I absolutely have to, though.

The ids in the li tags are dynamically generated, so they can't really be used.

I've tried various permutations of display: table, but I think I just don't quite understand it, because the layout never seems to work. Either the first column appears correctly, but the second two columns appear as table cells, or each of the header items display as block, etc. :-(

Is this even possible? If so, how can it be done? I'm generally open to just about everything, unless it involves changing the order in which the items go in the html generation, because I don't think that can be done, at least not with my current PHP ability. :)

Many thanks!

Katie
 
Why not just use a table?

It's exactly what they are intended for.

Chris.

Indifference will be the downfall of mankind, but who cares?
Time flies like an arrow, however, fruit flies like a banana.
Webmaster Forum
 
Because of the way the underlying query recordset is ordered. The query is, out of necessity, ordered for hierarchical lists, because that's how most of the content is displayed. Lists that need to be displayed in a column layout are the exception, not the rule. Most of the lists need to be displayed as hierarchical lists, and the entire page is based on one query that lists all of the items on the page in that order.

So I need the html to be written in the following order, because that's the only way the PHP code can write it (at least at my current skill level):
heading 1
- column 1 subitem 1
- column 1 subitem 2
heading 2
- column 2 subitem 1
- etc.
heading 3

...etc.

Tables are written in the following order:
heading 1
heading 2
heading 3
row 1 column 1
row 1 column 2
row 1 column 3
... etc.

...which won't work for my purposes (and what I'm going for is actually not what tables are intended for... tables are meant to be read across, which is why they're written across. What I'm trying to write is meant to be read down. :) )

To give a example from an existing website of the kind of thing I'm trying to write... it would be like if just some of this site's forum list needed to be formatted like:
[pre]
....
Software
- MIS/IT
--------------------------------------------------------------------------------------
| DNS / BIND / DHCP Issues | e-Business | Groupware & Mail Products |
--------------------------------------------------------------------------------------
| DNS/BIND/DHCP/WINS | General e-Business | Alt-N Technologies: MDaemon |
| Issues | discussion | Banyan: BeyondMail |
| | General EDI discussion | D. J. Bernstein: qmail |
| | ...etc. | ...etc. |
--------------------------------------------------------------------------------------
[/pre]

Katie
 
...oh, if it helps, note that when I say, "table layout," what I really mean is, "hierarchical lists that need to be displayed as columns, with a header row labeling what each column is for." So it's (probably) not strictly necessary for them to have that border or for them to all have the same bottom point... although the next list item after the column-layout ul ends obviously does need to be displayed on a full row of its own, below the bottom of the "table."

So perhaps something like display:inline-block? The problem is I don't really understand how those work, and would really appreciate some help with that. :)

Katie
 
Hi

You could use the CSS Display Module Level 3 | Box Layout Modes: the display property like this :
HTML:
[b]<ul[/b] [maroon]class[/maroon][teal]=[/teal][i][green]outer[/green][/i][b]>[/b]
[b]<li><ul>[/b]
[b]<li>[/b]DNS / BIND / DHCP Issues[b]</li>[/b]
[b]<li>[/b]e-Business[b]</li>[/b]
[b]<li>[/b]Groupware & Mail Products[b]</li>[/b]
[b]</ul></li>[/b]
[b]<li><ul>[/b]
[b]<li>[/b]DNS/BIND/DHCP/WINS[b]</li>[/b]
[b]<li>[/b]General e-Business[b]</li>[/b]
[b]<li>[/b]Alt-N Technologies: MDaemon[b]</li>[/b]
[b]</ul></li>[/b]
[b]<li><ul>[/b]
[b]<li>[/b]Issues[b]</li>[/b]
[b]<li>[/b]discussion[b]</li>[/b]
[b]<li>[/b]Banyan: BeyondMail[b]</li>[/b]
[b]</ul></li>[/b]
[b]<li><ul>[/b]
[b]<li>[/b][red]&nbsp;[/red][b]</li>[/b]
[b]<li>[/b]General EDI discussion[b]</li>[/b]
[b]<li>[/b]D. J. Bernstein: qmail[b]</li>[/b]
[b]</ul></li>[/b]
[b]<li><ul>[/b]
[b]<li>[/b][red]&nbsp;[/red][b]</li>[/b]
[b]<li>[/b]...etc.[b]</li>[/b]
[b]<li>[/b]...etc.[b]</li>[/b]
[b]</ul></li>[/b]
[b]</ul>[/b]
CSS:
ul.outer {
    display: table;
}
ul.outer>li {
    display: table-row;
}
ul.outer ul li {
    display: table-cell;
    width: 300px;
    border-style: solid;
    border-width: thin;
    padding: 2px;
}
To achieve something like this :

Feherke.
feherke.ga
 
Thanks, feherke. :) Before you got a chance to post this, I'd managed to come up with my own solution, which did require changing it to divs but at least kept the same order. The solution I came up with went something like this (including some context this time):

HTML:
<ul class="level1listing list">
<li id="heading1" class="xxx">Heading 1</li>
<ul class="level2listing list">
<li id="heading1a" class="xxx">Heading 1a</li>
<li id="heading1b" class="xxx">Heading 1b</li>
<li class="level3listing columns threecols">
<div class="col">
<div id="heading1ba" class="header">Heading 1b.a</div>
<div id="item1ba1" class="xxx">Item 1b.a.1</div>
<div id="item1ba2" class="xxx">Item 1b.a.2</div>
<div id="item1ba3" class="xxx">Item 1b.a.3</div>
</div>
<div class="col">
<div id="heading1bb" class="header">Heading 1b.b</div>
<div id="item1bb1" class="xxx">Item 1b.b.1</div>
</div>
<div class="col">
<div id="heading1bc" class="header">Heading 1b.c</div>
<div id="item1bc1" class="xxx">Item 1b.c.1</div>
</div>
</li>
<li id="heading1c" class="xxx">Heading 1c</li>
</ul>
<li id="heading2" class="xxx">Heading 2</li>
</ul>

CSS:
@mixin flexbox() {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
}

@mixin flex($values) {
  -webkit-box-flex: $values;
  -moz-box-flex:  $values;
  -webkit-flex:  $values;
  -ms-flex:  $values;
  flex:  $values;
}

@mixin order($val) {
  -webkit-box-ordinal-group: $val;  
  -moz-box-ordinal-group: $val;     
  -ms-flex-order: $val;     
  -webkit-order: $val;  
  order: $val;
}

li.columns {
	@include flex(1 200px);
	@include order(2);
	-moz-display: inline-flex;
	display: inline-flex;
	flex-flow: row nowrap;
	justify-content:space-around;
	align-items: stretch;
	list-style-type: none;
	width:80%;
	padding: 0;
	margin: 5px;
	border: 1px solid #a1b346;
	font-size:.95em;
}

li.columns div {
	padding: 2px;
}

li.columns div.col {
	flex: 1 auto;
	border: 1px solid #a1b346;
	padding: 2px 5px;
}

li.threecols div {
}

li.columns .header {
	background: #a1b346;
	color:#1a3900;
	font-weight: bold;
}

(I'm not too concerned about legacy browsers. It looks like Flex has been around for some time, so only people running really old browsers won't show it... and even they will still show the listing in a readable format... I tested it with a browser snapshots site).

FYI, your dabblet looks great on regular browsers (I just looked at it in Chrome), but the first time I looked at it, I happened to be on my Kindle using the Silk browser, which returned very odd results indeed. Of course, Silk just seems to have problems with the ul tag in general, though...

Anyway, thanks again for your help! Even if I didn't use it in this case, it's still really informative. :)

Katie
 
You have two choices:

1) Keep the PHP simple - read through your recordsets and spit them straight out in the order you read them - and use some complex HTML/CSS to make the results look like you want it to look.

2) Write some (relatively) complex PHP to read your data and process it into simple HTML/CSS that will be displayed in the way you want

You're pursuing option (1), I'd go for option (2) every time. The complex HTML is going to be interpreted on a wide range of user agents, and is bound to fail on some of them. With luck you'll be able to find most of the problems and have the budget to fix them. How lucky are you feeling?

If it were me, I'd either use a multi-dimensional PHP array to build up the table as I read the recordsets, then loop through the array to build a table with regular table markup, or I'd mark it up something like this:

<table>
<tr>
<th>Heading 1</th><th>Heading 2</th>
</tr>
<tr>
<td><ul><li>Item 1.1</li><li>Item 1.2</li><li>Item 1.3</li></ul></td>
<td><ul><li>Item 2.1</li><li>Item 2.2</li></ul></td>
</tr>
</table>

You can build that up by simply building up two string variables - one for the headers, one for the lists - as you read the recordsets, and then output the table when you've finished.



-- Chris Hunt
Webmaster & Tragedian
Extra Connections Ltd
 
I ran the full page under browsershots.org, and got snapshots of something like 160 browsers. In all the modern browsers, my HTML displays in a column layout, which is good. In the legacy browsers, my HTML displays as headings with the items underneath those headings, one after the other... which is also good. The data is clearly readable, and it's clear what headings they go under, in either case.

I'll use tables when the situation calls for them. The situation does not call for them here. Tables are meant to be read across. Something like a contact list, with columns for name, phone number, and email... there I'd use a table. But one of the primary goals of my programming is that I can then hand my code off to a talented CSS designer, and that designer will be able to make the site look like anything (within reason), just by editing the CSS. So if the client decides they don't want a column layout anymore, the designer can change the CSS and thereby change the look. Using tables in situations that don't call for tables goes against that entire philosophy.

Also... the MySQL recordset is a little more complicated than you're giving it credit for. And I think you're giving me a little too much credit for my ability to go back and forth through arrays. :-D

I do appreciate your time, but my philosophy is different. :)

Thanks,
Katie
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top