Forum Moderators: not2easy
<div style="width:800px;border:1px solid green">
Content
<table style="width:100%;text-align:center" border="1"><tr>
<td>Link</td><td>Longer link</td><td>Another link goes here</td><td>OK</td></tr>
</tr></table>
Content
</div> Basic aim:
This is a very common requirement from designers... so... I want to put the topic to rest once and for all. How can it be done without the <table> markup?
I have one such project in hand at the moment, so before I put in a table ... I want to ask here if there is a viable CSS solution to that problem.
So far as I am aware, there is no way to replicate this layout using CSS in a reliable fashion which works with the minimum of IE6+ and FF1.5+
<div> Link ¦ Link ¦ Link</div>
and using CSS, assign a % width to the <a> based on the number of links? Four links a = 25%; 10 link a = 10% and so on with text-align: center;
or
A <ul> menu displayed inline with each <li> assigned a % width as I described above?
<div><ul><li>link</li><li>link</li><li>link</li></ul></div>
Or, as I sometimes do, am I missing something here? :)
Marshall
Or, as I sometimes do, am I missing something here?
i.e. if you had this:
¦ here is a long link ¦ shorter link ¦ tiny! ¦
Then removed the 'tiny!' link, you'd get:
¦ --here is a long link-- ¦ --shorter link-- ¦
(-- represents whitespace)
The spacing should be based upon the size of the contents, not upon preassigned widths or equal widths.
If widths are not assigned, then you get containers the same size as the text (plus any padding/margin/border) and they all sit on the left. There's nothing to stretch them outward to span the page.
Drop the HTML from my first post into your browser and notice the resulting effect in which the cells are widest where the text is widest; and also note that there are no widths assigned to the <td> elements. This is the very effect which is required.
Marshall
A <td> is only as wide as the text
If a width is applied to a <TABLE> which is in excess of that produced by the sum of the contents of each <TD> in the row, then all the <TD>s get stretched wider in proportion to their content width until the total table is filled.
Example:
Try the HTML in my first post in a browser
Reference: RFC1942 [ietf.org] section on Autolayout Algorithm (p24)
Though, and I have never tried this or even read up on it, but is there not a display:cell, or something like that, in CSS?
Marshall
What time is it there? It's 02.30 here. Translation - not sure how much longer I will be up :)
[edited by: Marshall at 6:30 am (utc) on Oct. 3, 2007]
Default behaviour for a table is that the TDs within it are sized based upon how much you put in them. More you put in a table cell, the wider the column gets. That is, unless you override that behaviour by fixing the widths. If your TABLE is set to a fixed width, then the same method stretches out all the TDs, based upon the size of their contents, to nicely distribute them throughout the width of the table.
There is display:table-cell, but it does not work reliably with IE6.
Tables are also quite handy for dropping AdSense ads in for text to flow round, etc.
But I would very much like to see the CSS alternative to this. Maybe it doesn't have to be *exactly* the same, but it should make the same automatic and intelligent use of space that the table does in this case.
Rgds
Damon
Could you give me more details on this? I've tried applying various CSS styles to <li> items within <ol> but I can't get them to both fill the entire width of the page and to space themselves according to their content.
Example:
With the <li> inline or floated and block - result is that the list of links don't fill the page entirely:
>¦ here is a long link ¦ short ¦ ______empty_________ ¦< >¦ ---here is a long link--- ¦ ---------short-------- ¦< >¦ -------here is a long link-------- ¦ ----short---- ¦<
=================================
<ul id="navlist">
<li><a href="http://www.example.com/"><img src="http://www.example.com/images/b.jpg" width="100" height="15" alt=" "
border="0"></a></li>
<li><a href="http://www.example.com/directory1/"><img src="http://www.example.com/images/b1.jpg" width="130" height="15" alt=" " border="0"></a></li>
<li><a href="http://www.example.com/directory2/"><img src="http://www.example.com/images/b2.jpg" width="100"
height="15" alt=" " border="0"></a></li>
<li><a href="http://www.example.com/directory3/"><img src="http://www.example.com/images/b3.jpg" width="100" height="15" alt=" " border="0"></a></li>
<li><a href="http://www.example.com/directory4/"><img src="http://www.example.com/images/b4.jpg" width="100" height="15" alt=" " border="0"></a></li>
<li><a href="http://www.example.com/directory5/"><img src="http://www.example.com/images/b5.jpg" width="100" height="15" alt=" " border="0"></a></li>
</ul>
================================
#navlist ul {margin-left: 1px;}
#navlist li
{
display: inline;
list-style-type: none;
margin-left: 1px;
padding-right: 5px;
}
================================
Being inside a table row I didn't have to adjust for the width, and had no text to align. Otherwise, I'd do
#navcontainer in the style sheet and
<div id="navcontainer"> surrounding the list.
Probably cobbled together, but I've gotten it to work with text (somehow), and using buttons were what I needed for a particular site.
==================================
Added:
What I want is that the longer links get larger containers, but the total is still 100% page width, and I want it automatically to adjust in this way:
>¦ -------here is a long link-------- ¦ ----short---- ¦<
>>the navcontainer div 100% wide (maybe the UL, I'm not sure), and then
>>get the spacing around the <li> items uniform using padding on the sides, and *I think* maybe checking into using left and right margins with a value of "auto"
I *think* margin-left: auto and margin-right: auto can get whole pages centered (or divs), which if I'm not mistaken is considered a CSS hack for browser purposes.
[edited by: Marcia at 8:40 am (utc) on Oct. 3, 2007]
One of the immediate problems is that not all browsers implement 'display: table; [w3.org]' [slightly outdated table showing which ones do (or did) here [quirksmode.org]]. In theory a browser that supports CSS 2 should be able to do this, but few can.
However, speaking as someone who's spent a lot of time helping (print) designers understand what they can and can't do on the web, you don't have to do something just because a designer asks for it. By way of example, I'm quite sure you don't let designers specify body text in fonts not widely available on the web, right?
My example is not entirely apt, of course, because you do have a way to implement this particular request, but you need to weigh the costs and benefits of using the table (or not) in these cases. In fact, even the popular cms Drupal (which generally produces quite good markup) uses almost exactly the kind of table you describe to display lists of downloadable files attached to stories, so you're not alone in not having come up with a better way...
-b
[edited by: bedlam at 8:38 am (utc) on Oct. 3, 2007]
Your code gives:
[link][widelink][link] ******space*******
_________________________________________
What I want is:
[***link***][****widelink****][***link***]
__________________________________________
:)
I have previously written javascript to dynamically increase padding until it wraps and then go back one px, but it's messy and means moving things onLoad.
bedlam, I really appreciate your input on that. You say similar layouts can be created - how similar can you get? The key here is that it is to be configurable by a non-techie owner via CMS so I can't be asking him to set px / % sizes for each link.
Regarding designers, I believe in giving them the maximum of flexibility unless it is absolutely necessary to limit something. The approach produces really great and fresh designs, and a stack of challenges when it comes to implementation which are both enjoyable and push the envelope.
I guess that I cannot believe that nobody has been able to come up with some form of hack to achieve this effect through CSS in IE6. It's such a commonly designed layout...!
I often use another approach, which doesn't use list items (although a list of links should be li.) You float elements left:
<div style="float:left;width:100%">
<div style="float:left;width:33%"> col 1 </div>
<div style="float:left;width:34%"> col 1 </div>
<div style="float:left;width:33%"> col 1 </div>
</div>
I've used divs, but they can be anything - this technique is particularly useful in dispensing with table-based forms. Because the "parent" is floated, it has the added advantage of clearing/shrink-wrapping all it's children. Adjust the % accordingly with relevant padding and margins.
But it still doesn't do the coolest thing that tables do, expand and contract with the content. It requires rethinking your requirements.
AIUI the CSS processing model does not spec double-pass processing anywhere. Browsers use this with most tables, and it allows this kind of autofitting - at the cost of progressive display (is this right?).
I would use a table. Rules (or more accurately, guidelines) are made to be broken :)
Basic aim:>Horizontal row of links (top menu)
>Row of links must take up 100% of the page width
>Items are spaced according to their length to evenly fill the 100% page width
>Links are centered in their containers
When I use text zoom, first the items should fill their containers more, then they should wrap within their containers (menu should not become more than 100% width, nor should it wrap to a second line of links)
So I think allowing for user-increased browser text or user stylesheets is a whole different set of problems, if gurus are missing it. ;)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>test template</title>
<style type="text/css">
ul#menu {
margin:0;
padding:0;
width:800px;
[b]display:table;[/b]
border:1px solid red;
}
ul#menu li {
list-style:none;
[b]display:table-cell;[/b]
text-align:center;
border:1px solid green;
}
ul#menu li a {
display:block;
margin:3px auto;
border:1px solid blue;
}
</style>
</head>
<body>
<ul id="menu">
<li><a href="#">Link</a></li>
<li><a href="#">Longer link</a></li>
<li><a href="#">Another link goes here</a></li>
<li><a href="#">OK</a></li>
</ul>
</body>
</html> Basically, you're mimicking the table-cell behavior of your first example. Like I said, it works fine in Opera 9.x, Firefox 2.x, Konqueror 3.5.x but not IE6 or IE7.
So, back to tables for this one, unless there is some fiendishly complicated proprietary IE workaround that I don't know about it. ;) (Or try playing with display:inline-block in an IE conditional comment, you never know.)
I don't use tables for the main layout, but I use them for sub-layouts where it is sensible to do so.
The other point is you would be replacing a few <td> tags, etc., with a bigger CSS overhead.
Tables for layout
Give me the CSS alternative!
Why should we? ;)
It's been the general advice for a few years now that you should NOT try to use CSS to mimick table behaviour, especially not for the sake of it.. if the above described behaviour is what you want from your designers, and they can do it with tables.. then they will do it especially if that's what the boss asked for, if you're the boss and you're happy then go for it!
However the minute you, the boss, needs a similar (it's never gonna be the same, we're at WEB3 or 4 now you know ;)) then the same behaviour without tables for screen, PDA, mobile or text (RSS) format isn't going to happen, CSS might make it pretty for one or two of them, but the MARKUP is important..
Does the document make sense in a text format? - i.e WITHOUT TABLES or CSS?
Know your market and which formats are likely to matter, same old advice really
PS: tables don't "always" work as expected these days either.
[edited by: SuzyUK at 10:30 pm (utc) on Nov. 4, 2007]