Forum Moderators: not2easy

Message Too Old, No Replies

Tables for layout

Give me the CSS alternative!

         

vincevincevince

4:25 am on Oct 3, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Table version:
<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:

  • 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)

    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?

  • Marshall

    4:56 am on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



    Vince,

    Are you asking for a basic template, more or less, that can be posted here for reference?

    Marshall

    vincevincevince

    5:04 am on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    Marshall, not really - the code you see above is something we're asked for by designers quite frequently, reduced to the simplest form.

    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+

    Marshall

    5:20 am on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



    Can't you either do:

    <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

    vincevincevince

    5:28 am on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    Or, as I sometimes do, am I missing something here?

    Unless I'm missing something, your solution gives equal (or preassigned) widths to each link. What is required is that wider links are in wider containers, narrower links are in narrower containers, but the total width is 100% of the page.

    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.

    Marshall

    5:49 am on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



    That being the case, then you simply do not assign widths. Yes? No? I hate to say this, but I think I am missing the point/goal.

    Marshall

    vincevincevince

    5:52 am on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    If I don't assign widths, how do I ensure that the total of all the link widths adds up to the page width?

    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

    6:01 am on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



    If the <div> the links are in is set to 100% width and you have text-align: center, then it should look the same as using <td>'s. A <td> is only as wide as the text and the text width (number of characters) is a constant whether they are in a <td> or not. The only thing I can see as a problem is if you have different backgrounds for the links. If that is the case, I would us the <ul> format and set the <li>'s to display: block and not assign a width, or assign width: auto;. Beyond that, I haven't a clue.

    Marshall

    vincevincevince

    6:07 am on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    A <td> is only as wide as the text

    Ah, that is where you are wrong. Perhaps you have been avoiding tables for too long!

    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)

    Marshall

    6:29 am on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



    I realized my mistake right after I posted it. It's not the size of a link, but the number of <td>'s that you are trying to emulate. I still think, maybe erroneously, that using <ul><li> method would work, though it would require a little creative CSS me thinks.

    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]

    vincevincevince

    6:35 am on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    Marshall, I think 2.30AM is getting the better of you (here it's 2.30PM).

    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.

    Marshall

    6:42 am on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



    You are probably right, about the time that is. Guess I should take my Basset Hound for a final walk and go to sleep. I will give this some thought when I get up.

    Marshall

    vincevincevince

    7:26 am on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    Marshall, thanks for your advice... might be some of the other CSS experts here will weigh in with their best advice before your morning breaks.

    Someone must know the secret to this!

    Marcia

    7:44 am on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    Vince, if that's what you want for a top navigation bar, do a horizontal unordered list inside of a div, with all the formatting controlled in the stylesheet.

    DamonHD

    7:47 am on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    In this instance, VVV, I think that the steam-powered methods still work best.

    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

    vincevincevince

    7:53 am on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    Marcia,

    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_________ ¦<

    With a 50% width applied - long and short links get the same width:
    >¦ ---here is a long link--- ¦ ---------short-------- ¦<

    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---- ¦<

    Marcia

    8:25 am on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    My page is in a 770 wide table, but I had a bug to learn horizontal lists (with images). The top navigation buttons were in a code-heavy nested table with sloppy td's, so I pulled that nav table and spent a night or two up tackling replacing that button table with a horizontal UL. It works, and it should also work outside of a table using the stylesheet.

    =================================
    <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---- ¦<

    I'm just getting into this so don't take it as workable, but I'd imagine it would be styled with

    >>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]

    bedlam

    8:36 am on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    Vincevincevince, there is not yet a way of doing what you're asking as flexibly as what you're used to doing with tables--though it is fairly easy to come up with similar layouts.

    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]

    vincevincevince

    8:37 am on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    Marcia, thanks for that (I noticed that '#navlist ul' needs to be just '#navlist'). Unfortunately the end result doesn't match what I'm looking for.

    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...!

    rocknbil

    6:45 pm on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    Agreed, the columns-flow-to fit copy aspect of a table is the one item that always seems to be left out of the table layout debates. :-)

    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.

    mattur

    8:21 pm on Oct 3, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    I don't know of any CSS way of doing this. Columns in CSS are problematic full stop.

    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 :)

    vincevincevince

    3:00 am on Oct 17, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    Thanks for all the responses, I'm going to assign this as 'impossible to achieve without a table' I think.

    Marcia

    9:49 am on Nov 4, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    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


    Could there be a way using floats and margin-left: auto and margin-left: auto (with appropriate collapsing), and using pre (preformatted) styling? I'm a "beginner" at this sort of thing and struggling to learn how to do the same type of things, being on a dedicated kick to cut down on file size and load time, so I've been on the prowl to find a way to set up workable, re-usable "snippets" to incorporate into a library of page templates. (I've never heard of using pre in styles until this past week.)

    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)

    I don't have a clue (being a n00b at this), but if what you mean by text zoom is when a user increases the size of the text in their browser, I've been doing that on some sites with small fonts, and on a SPECIALIST site for CSS & accessibility (Accessify, to be exact), it causes their left navigation menu to shift right, overlap and sit on top of the text on the right. Try it yourself with IE.

    So I think allowing for user-increased browser text or user stylesheets is a whole different set of problems, if gurus are missing it. ;)

    encyclo

    11:28 am on Nov 4, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    Won't work for IE, but try this:

    <!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.)

    HarryM

    1:51 pm on Nov 4, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    I think the choice is simple. Anything you do to emulate what you can do in tables will involve retesting and possibly recoding whenever a new browser is launched. But tables will always work.

    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.

    SuzyUK

    10:29 pm on Nov 4, 2007 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    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]