CSS again

Dear Lazyweb,

I think my last example was too stripped down and was hiding problems. Let's try that again with a complete document: test.html.

What I'm seeing is: css1.gif. What I want to be seeing is this: css2.gif.

<LJ-CUT text=" --More--(41%) ">

In the first one, the top margin of the heading box escapes out of its enclosing rectangle. This is visible in two places (look at them side by side.)

  • "Heading One" is too close to the top edge of the window (it is overlapping the document's outer bounding box.)
  • "Heading Three" overlaps the enclosing table, meaning that the top edge of the box around the heading does not line up with the top edge of the image to its left.

So, CSS gurus, tell me how to edit that file to make it look like css2.gif.

If you think you know how to fix this, please try it out by editing the file instead of just saying "you need to use a DIV inside a SPAN and change the ziggurat mode to inverted", because I think what's going on here is more complicated than it at first appears.

Update:
Admitting Defeat

startled's comment has convinced me that, while it might be possible to acomplish this with CSS in a way that will work in the current crop of browsers, any solution will be flaky and fragile, and it's just far, far more trouble than it's worth. So I'm going back to a table-based layout.

All I wanted to do was put a dumb box around my headings. This, apparently, is rocket science with CSS. But with tables, it will work just fine in every browser shipped in the last ten years.

Sad, really.

Tags: , , , ,

55 Responses:

  1. jferg says:

    Just changing:

    <H1><SPAN CLASS="heading">Heading Three in a Box</SPAN></H1>

    to:

    <H1><DIV CLASS="heading">Heading Three in a Box</DIV></H1>

    seems to do the trick for me. What am I missing?

    • jwz says:

      Changing it in one place but not all three is cheating.

      When you change it from SPAN to DIV then the box becomes 100% wide.

      • jesus_x says:

        Why not just assign style to the tag? My blog's H2 tags are styles so I just use H2 around my dates to give them a box style. And actually, I have two different H2 styles depending on which DIV the'yre inside of and are automatically styled correctly. in the content's div, this is what's applied:
        .contents h2 {
        background-color: #f3fcfb;
        border: 1px solid #b7cec2;
        border-right-width:3px;
        border-bottom-width:3px;
        padding: 5px;
        font-size: large;
        margin-bottom: 5px;
        -moz-border-radius: 1em 0 1em 0;
        }

        and you can see the results at http://burntelectrons.org/ with the style sheet http://burntelectrons.org/skins/base/default.css

        If I wanted all H2's to look like that, I'd just remove the .contents part from the first line.

  2. happysteve says:

    okay, try adding this:

    /* to move the first header down a little */
    body { padding-top: 5px; }

    /* SPANs ignore the margins and padding for top and bottom,
    * only switch to block mode if it's inside a TD */
    td .heading { display: block; }

    /* This one you may or may not need, it looked like there was too much
    * space inside the table once the .heading turned into a block */
    td h1 { margin-bottom: 0em; }

    • jwz says:

      That's insane!

      If I have to basically hand-tweak every single instance of a heading to take into account where in the document it is and what might be around it, I'll just go back to using nested tables.

  3. carus_erus says:

    I think it's display:inline that's messing with your box height.

    Also I think spans are intrinsicly evil, but I think the reason for this is that they're inline by defuault.

    This is also wrong, but closer to what you're looking for in terms of layout:

    div.heading {
    border: 1px solid #0F0;
    color: #0F0;
    background: #040;
    font-size: large;
    font-weight: bold;
    padding: 0.3em 1.4em;
    display:block;
    text-align:center;
    }

    (and replace all the <h1><span> with <div class=heading>

    I know, not much closer, but I'm pretty sure display:inline is what's bumping you up a few pixels. At the very least your Heading Three box is displaying correctly.

    • carus_erus says:

      Hmm, pretty much what <lj user=jferg> says.

      I'd probably stick with the div tags, and modify the css and classes as required. You should be able to mimic h1, h2 etc with the css exclusively without inheriting any strange properties different browsers might give to h1 and h2.

  4. the problem is the document is being rendered in 'quirks mode' because you don't have a !DOCTYPE header. quirks mode is for bug-compatibility with old pages that relied on broken css implementations, so it's hard to do anything nontrivial with css in quirks mode. adding an appropriate !DOCTYPE header makes the overlapping problem go away for me. (firefox 1.0.3)

    • What grayscalewolf says is important... Here's your page switched up to using XHTML 1.1, specified in the doctype:

      http://battletothedeath.net/~fwph/test.html. It doesn't look right, but it doesn't have the overlap problem in Firefox anymore. I just used XHTML because that's the tag I have hanging around, I'm sure finding the HTML 4.01 tag should be pretty easy (and it won't mess up the display the way that my page does). I didn't change your CSS at all, except to move it into a stylesheet (along with the body attributes), but that was just a vague attempt to get it to validate, which I'm not going to bother finishing.

      FWIW, though, Opera displays your original page as intended.

    • ralesk says:

      Seconded (or thirded as it may be).  Very good point.

      In standards mode, even IE/Win32 behaves well enough that div-only1 designs can actually be made.

      1: as far as the layout goes - abolishing h1 and the other semantic stuff is a BAD IDEA.

      PS: so is using p for "line breaking" such as between a dl and dt.  But I'm really being nitpicky here now.

  5. artlung says:

    <style type="text/css">
    <!--
    /*
    my experience is that with any CSS, once you actually get some content into your CSS greek text, you have to tweak the CSS again. Good luck!
    */

    div#jwzlayout
    {
    background-color: #000;
    padding: 10px;
    color: #00FC00;
    font-family: sans-serif;
    text-align: center;
    }

    div#jwzlayout h2
    {
    color: #00FC00;
    background-color: #004100;
    border: 1px solid #00FC00;
    text-align: center;
    padding: 0 20px 0 20px;
    min-width: 150px;
    display: inline;
    }

    div#jwzlayout p
    {
    color: #00FC00;
    text-align: left;
    }

    div#jwzlayout p.subtitle
    {
    color: #00FC00;
    font-weight: bold;
    text-align: center;
    }

    //-->
    </style>

    <div id="jwzlayout">

    <h2>Heading One</h2>

    <p>All work and no play makes jack a dull boy.
    All work and no play makes jack a dull boy.
    All work and no play makes jack a dull boy.
    All work and no play makes jack a dull boy.
    All work and no play makes jack a dull boy.
    </p>

    <h2>Heading Two</h2>

    <p>All work and no play makes jack a dull boy.
    All work and no play makes jack a dull boy.
    All work and no play makes jack a dull boy.
    All work and no play makes jack a dull boy.
    All work and no play makes jack a dull boy.
    </p>

    <table>
    <tr valign="top">
    <td><img src="dnalounge.gif"></td>
    <td width="24">&nbsp;</td>
    <td align="center">
    <h2>Heading Three in a Box</h2>
    <p class="subtitle">with a subtitle</p>
    </td>
    </tr>
    </table>

    <p>All work and no play makes jack a dull boy.
    All work and no play makes jack a dull boy.
    All work and no play makes jack a dull boy.
    All work and no play makes jack a dull boy.
    All work and no play makes jack a dull boy.
    </p>

    </div>

  6. sinf says:

    Try adding 'display: table;' to the .heading class.

  7. saintnobody says:

    .heading {
    border: 1px solid #0F0;
    color: #0F0;
    background: #040;
    font-size: large;
    font-weight: bold;
    padding: 0.3em 1.4em;
    line-height: 1.92;
    }

    I added line-height to make the line box tall enough to enclose the line, plus the padding, times the standard multiplier of 1.2, without which it still doesn't look right for some reason. It renders just about right in konquerer (my browser of choice) and in Mozilla 1.7.3.

    The real problem is that what you want seems to be an inline box, and support for that is generally somewhere between completely lacking and shitty depending on browser.

  8. jwz says:

    This seems to work:

      <STYLE TYPE="text/css">
        heading {
          border: 1px solid #0F0;
          olor: #0F0;
          background: #040;
          ont-size: large;
          font-weight: bold;
          padding: 0.3em 1.4em;
          display: table;
        }
      </STYLE>

      <H1 ALIGN=CENTER><SPAN CLASS="heading">Heading One</SPAN></H1>

    Then I tried this:

      <STYLE TYPE="text/css">
        H1 {
          border: 1px solid #0F0;
          color: #0F0;
          background: #040;
          font-size: large;
          font-weight: bold;

          padding: 0.3em 1.4em;
          display: table;
        }
      </STYLE>

      <H1>This works</H1>

      <H1 ALIGN=CENTER>But this is not centered?</H1>

      <DIV ALIGN=CENTER><H1>This is centered</H1></DIV>

    Is there some CSS thing I can put in there to make <H1> be centered, or to make <H1 ALIGN=CENTER> work? Maybe what I'm asking is "what is the CSS to express <TABLE ALIGN=CENTER>", since that's what I'm basically turning H1 into.

    • zonereyrie says:

      I believe 'text-align: center;' is what you're looking for.

    • jiritsu says:

      h1{
      ...
      text-align:center;
      }
      will center the text in the h1.

      if i may make a suggestion, don't use "display:whatever" on elements if you can avoid it. some elements are blocks and some are inline so that if your page is viewed on an old browser that doesn't understand your css the page degrades as gracefully as possible. instead use "width:150px;"

      and since i was bored, here's how i would have written that page...
      (disclaimer: the text wraps in the h1's in IE. you can either increase the width of the h1's or change the text size to fix it)

      <?xml version="1.0" encoding="utf-8"?>
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
      <head>
      <style type="text/css">
      body{
      background-color:#000000;
      color:#00FF00;
      font-size:13pt;
      text-align:center;
      font-family:verdana;
      }

      a{color:#00ddff;}

      a:visited{color:#aadd00;}

      a:active{color:#ff6633;}

      .heading{
      margin:5px auto 20px auto;
      width:150px;
      text-align:center;
      border: 1px solid #00ff00;
      color: #0f0;
      background: #040;
      font-size:14pt;
      font-weight: bold;
      padding:0.3em 1.4em;
      }

      p{
      text-align:left;
      margin:1px;
      }

      table{margin:0;}

      td{vertical-align:top;}

      div{
      text-align:center;
      margin:20px 0 0 0;
      font-weight:bold;
      }

      .specialheading{
      width:280px;
      margin:0;
      }
      </style>
      </head>
      <body>
      <H1 class="heading">Heading One</H1>
      <p>
      All work and no play makes Jack a dull boy.
      All work and no play makes Jack a dull boy.
      All work and no play makes Jack a dull boy.
      All work and no play makes Jack a dull boy.
      All work and no play makes Jack a dull boy.
      </p>
      <H1 class="heading">Heading Two</H1>
      <p>
      All work and no play makes Jack a dull boy.
      All work and no play makes Jack a dull boy.
      All work and no play makes Jack a dull boy.
      All work and no play makes Jack a dull boy.
      All work and no play makes Jack a dull boy.
      </p>
      <TABLE BORDER="1" CELLPADDING="0" CELLSPACING="0">
      <TR>
      <TD><IMG SRC="http://www.dnalounge.com/logo-green-small.gif" WIDTH="180" HEIGHT="58" BORDER="1" /></TD>
      <TD style="width:20px;"> </TD>
      <TD id="headingcell">
      <!-- %%HEADING%% -->
      <H1 class="heading specialheading">Heading Three in a Box</H1>
      <DIV>with a subtitle.</DIV>
      </TD>
      </TR>
      </TABLE>
      <p>
      All work and no play makes Jack a dull boy.
      All work and no play makes Jack a dull boy.
      All work and no play makes Jack a dull boy.
      All work and no play makes Jack a dull boy.
      All work and no play makes Jack a dull boy.
      </p>
      </body>
      </html>

      • jwz says:

        text-align:center will center the text in the h1.

        No. It doesn't.

        • spc476 says:

          Well, yes and no. text-align: center; will center the text within the box defined by the tag. So while:


          <H1 STYLE="text-align: center;">This is one line</H1>

          may not look like it's centering the text:

          This is one line

          Technically, it is. Change the text to read:


          <H1 STYLE="text-align: center;">This<BR>
          is<BR>
          multiple<BR>
          lines</H1>

          And you get it centered within the <H1> tag:

          This

          is

          multiple

          lines

          You want it centered based upon the parent box, and for that, you set margin-left: auto; and margin-right: auto;, so the following should be centered:


          <H1 STYLE="margin-left: auto; margin-right: auto; text-align: center">This is centered</H1>

          This is centered

      • jwz says:

        if i may make a suggestion, don't use "display:whatever" on elements if you can avoid it. some elements are blocks and some are inline so that if your page is viewed on an old browser that doesn't understand your css the page degrades as gracefully as possible. instead use "width:150px;"

        You've got to be fucking kidding me -- you're actually pretending to care about things looking ok on computers other than the one on your desk, and at the same time, advocating hardcoded pixel sizes? If you care about "old browsers", you don't use CSS at all, you use HTML circa 1995.

        I'm sorry, but obfuscated, verbose, and yet still fundamentally wrong examples like that one are why I've put off using CSS for so long in the first place.

        • jiritsu says:

          I'm sorry, but obfuscated, verbose, and yet still fundamentally wrong examples like that one are why I've put off using CSS for so long in the first place.

          amazing... i have been doing this 40 hours a week for the past 5 years and you're the first person to notice that i have been completely wrong this whole time.

          i guess i should have become a carpenter.

          • jwz says:

            I'm sorry to be the one to break it to you that describing text with hardcoded pixel widths is absolutely, 100% wrong. But it is.

            • jiritsu says:

              see, the funny thing is, i don't see any text described in pixel sizes anywhere in my css. in fact, all i see is "font-size:xx pt", as per w3c's css1 spec.

              so at this point in the thread you have disagreed with three people on how text-align works, despite the fact that they were all giving you correct information, and you have casually dismissed a completely workable solution as "wrong". are there any other ways you want to encourage people not to help you?

              • jwz says:

                I asked, "how do I center the box?" They said, "use text-align:center". They were wrong. That centers the text inside the box, which has no visible effect at all.

                What do you call "width:150px" if not describing text in terms of pixel sizes?

                No wait, don't answer that. Just go away.

                • jiritsu says:

                  "text-align:center" will center the box if it is applied to the element that contains the box. such as the <body>. such as in my "wrong" example.

                  "width:150px" describes the size in pixels of the box containing the text. it has nothing to do with the size of the text because width is not inherited. rtfm

            • What makes it hard to avoid px sizing for text is that images are sized in px, so if you care about the balance and alignment of a layout that includes images, then you have to size everything in px. Fortunately, Opera will scale both text and images when you tell it to magnify. Unfortunately mozilla doesn't do that. I forget what IE does. Widespread adoption of SVG will solve some of these problems but introduce others.

              Personally, I've given up on anything but simple layout with minimal markup. Book-quality layout on the web is basically impossible right now, it's not going to become possible for a long time. Web design today is a huge collection of tips and tricks that will become obsolete quickly, it's not really worth learning unless someone's paying for it.

              • jwz says:

                Using pixels for text is bad because it's better to have images be too small relative to the text than to have the text wrap stupidly or overlap or otherwise become unreadable, which is what happens with every fixed-pixel web site design I've ever come across. (I have a very high resolution screen, meaning small pixels, meaning bigger fonts than the dumbass designers had in mind.

                But come on, I wasn't trying to do "book quality" markup, I just wanted to put a stupid box around my headings!

                Which is utterly trivial to do (and obvious!) using three nested tables. And it's been completely portable since 1995.

                That this is not merely nontrivial, but apparently impossible to do portably using CSS is just madness.

    • saintnobody says:

      just make sure the table has margin-left: auto and margin-right: auto and it should be centered.

  9. startled says:

    (My apologies for posting this twice, the first post had its formatting destroyed in a way that the Preview didn’t show.)

    CSS makes the trivial into the impossible, and there’s no one-line fix to your problem. I’ll show you what I got to work, at least as much as “work” means anything on the modern web.

    First I changed the HTML a bit. I changed the heading markup to read:
    <DIV CLASS="heading">Heading N</DIV>

    And wrapped the text in paragraph tags, so that they would have suitable margins. I also added a doctype at the top of the file:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd">

    Doctypes are annoying, but CSS is (even more) unpredictable without one. My solution will not work in IE without one, though Mozilla seems to cope.

    To prevent the DIVs from naturally take up the width of the window, I modified .heading like this:


    .heading {
    border: 1px solid #0F0;
    color: #0F0;
    background: #040;
    font-size: large;
    font-weight: bold;
    padding: 0.3em 1.4em;

    display: table; /* shrink the div to fit its content */
    margin: 0 auto; /* center the div horizontally */
    }

    This makes your layout work in Mozilla, but display: table is ignored by IE (it will still expand the DIVs 100%). I hear some people still use that browser, so here's a workaround. Add to .heading:


    white-space: nowrap; /* prevents line breaks */
    width: 1px; /* annoyingly hackish, but the element will expand to fit */

    Any reasonable browser would set the width of the div to 1 pixel, but modern browsers aren’t reasonable and have never really been about doing what is asked of them. IE (and everyone else) will try to make the element 1px wide, but then expand it to fit the contents. The cost is the nowrap, so if you want to have multi-line headings instead of horizontal scrollbars, this is a deal-breaker. I haven’t thought of a suitable way around this.

    The last problem is with Opera and its interpretation of display: table. Since Heading Three is itself in a table, it picks up the properties of that table, namely BORDER=1. This draws an ugly table border immediately around the text, inside the green padding. If you care about the untold hordes which make up the Opera user-base, you can fix it by taking the BORDER declaration out of the table element, and in the stylesheet adding:


    table, td { border:1px solid gray; }

    And there you have it, enough to make you run screaming back to good-ol’ table layouts. I really hope somebody comes up with a simpler solution for this that makes me hit my head and say “of course!”, but I’ve had that fantasy daily for as long as I’ve been working with CSS. I’ve tested this to work on IE6, Firefox 1.0, and Opera 7.5/8 (I can’t find a Mac around to test Safari). It does not work on older versions of IE (headings are not centered.) With my luck, it won’t work on your system, either. Thanks for your blog, by the way.

    • jwz says:

      You are making my brain bleed.

      I thought that I had a solution:

        H1 {
            border: 1px solid #0F0;
            background: #040;
            font-size: large;
            padding: 0.3em 1.4em;
            display: table;
            margin: auto;
        }

        <H1 ALIGN=CENTER> Heading! </H1>

      But that looks a lot like what you did, and you say this does something horrible in IE, and something differently horrible in Opera?

      Would you confirm that with test2.html?

      If that doesn't work, then it seems clear that I should go back to plain old tables for this.

      • startled says:

        Yep, in test2.html Opera shows an ugly additional table border in Heading Three, and IE6 makes the headings 100% wide. Additionally, IE6 adds a top margin to heading elements, so Heading Three is about .5 ems below the top of the table. My version corrects for those problems, but could easily become broken in the next round of browser updates. Good thing we’ve got these standards.

        • jwz says:

          Yeah, screw it, I'm going back to tables then.

          Can I assume that a hybrid table/CSS trick like this is portable? It saves a lot of characters, because otherwise I have to nest three tables with different backgrounds:

          <TABLE ALIGN=CENTER CELLPADDING=8 STYLE="border: solid 1px; color: #0F0; background: #040; font-size: large"> <TR><TD><B> Admitting Defeat </B></TD></TR></TABLE>

          Admitting Defeat
          • spc476 says:

            Sorry to hear that. I did get it looking like css2.gif using only CSS here. Basically, outside of a <TD> I had to wrap the text in <H1><SPAN> … </SPAN></H1> tags (to keep the box from expanding across the entire page), but within a <TD> you can just use a bare <H1> (since the <TD> will bound the <H1>).

            The CSS is a bit more than you had initially, but the HTML is simpler now.

            Oh, and I did add a <DOCTYPE> declaration to the page just to make sure.

            • jwz says:

              But you had to do that by special-casing "H1 inside of TD". If I have to add special-cases for every possible permutation like that, I'll just use tables instead, because I know it'll work and won't come back to bite me in the ass at some random point in the future.

              • spc476 says:

                Well, I got rid of that special case, but I did have to special case it in the CSS—six of one thing, half dozen the other.

                But I do have two questions if you don't mind: 1. Why use CSS in the first place? And 2. Is the table there just to layout an image? (if so, and you don't need the table borders, then there's no special casing at all required as far as I can see).

                • jwz says:

                  I was having layout problems that (it turned out) resulted from mixing and matching some CSS stuff with <FONT> tags, so I went through and converted the <FONT> stuff to CSS. While I was at it, I was hoping that converting some more stuff from <TABLE> to CSS would make the code more concise; it doesn't. Well, it does get smaller, but it also turns out to make it no longer work.

                  • ciphergoth says:

                    The CSS kool-aid doesn't taste good to me.

                    If CSS wanted to do away with table-based layout, they should have created exactly the same concept in CSS. When I look at what you're trying to do, I see a grid, with certain objects taking up certain cells in the grid. Trying to express that without using concepts like "table" or "grid" is like trying to explain number theory without using the concept of "divisible".

                    I'll happily manage my fonts and suchlike with CSS, but for layout tables are the only option that works.

                  • jwz says:

                    For the menu wrapping around the page, and positioning-related stuff like that, yes, I think tables are and will remain the best way to do it. But I kind of expected that "draw this text with a box around it" would be something CSS could handle! But no.

                  • wntd says:

                    If CSS wanted to do away with table-based layout, they should have created exactly the same concept in CSS.

                    http://www.w3.org/TR/CSS2/tables.html#q2

              • spc476 says:

                Oh, never mind—you answered that in your other post. Sorry to have taken up your time.

    • saintnobody says:

      if i remember correctly, ie supports display: inline-block, which you should be able to use in place of the single-cell table hack. the specs specifically say that all unsupported settings are ignored, so you should be able to do display: table; display: inline-block to use inline blocks (which is what he probably really wants) where they're supported, falling back to single cell tables where they're not, which should be a pretty good solution.

      • startled says:

        I tried it out, hoping you were right, but display: inline-block fails differently in each browser. IE doesn’t support it yet. Mozilla prefers the “block” part to the “inline” part and seems to render the same way it would display: block. Opera makes the box the correct size, but doesn’t center it with horizontal margins set to auto. Pure CSS is embarrassingly bad at laying things out horizontally instead of vertically, and requires falling back to tables or very specific single-use hacks.

  10. charkes says:

    I'm not a CSS expert but here's my suggestion. Add this to the style:

    h1 {
    padding-top: 0.2em;
    }

    It seems to work in Firefox and Safari. Hope it helps.

  11. This appears to do what you want in Firefox 1.4 and IE6 (though I'm prepared to discover that it looks bad in anything else)

    http://www.redgrittybrick.org/test/jwz.html

    • jwz says:

      Look, any approach where you have to do something different for the "normal" H1s and the one in the box is not acceptable -- I'm not going to waste my time devising new special cases every time I happen to place an H1 in a context I hadn't thought of before.

      • Are you saying:

        A) It is ok for the third H1 to be wrapped in a TABLE

        b) It is NOT ok for the third H1 to be wrapped in a DIV

        I must be missing something here (my classname wouldn't have thrown you off would it?) my third H1 is otherwise identical to every other H1 isn't it?

        • jwz says:

          Oh, I didn't notice that you had converted the "in a box" table to CSS too. I thought that was something else.

    • jwz says:

      Also, please ask yourself: "why would I use CSS for this instead of tables?" Is it clearer? More portable? More concise?

      If it takes 10 lines to express it with TABLE and 50 lines to express it with CSS, you're failing on at least two of those.

      • 1) CSS instead of tables.

        If you prefer tables, use em.

        * clearer? - surely it depends what you are used to. I find a plain CSS approach can be clearer than a mongrel mix of TABLES and DIVS and SPANs but I'll concede this to you.

        * more portable? - nope. Though it may be better for people using speech browsers.

        * more concise - For me the answer is not as simple as your reply suggests:

        2) Lines of code.
        An interesting and valid point. OK you had 59 lines I have 78 (i.e. + 19)

        * I added doctype (2 lines) html (2 lines) head (2 lines) title (1 line). I added P tags around the text bocks (6 lines)
        You shouldn't count this against CSS, its just me being a little finicky.

        * I put the vlink stuff in CSS instead of body attributes and inserted newlines for clarity (same info, 5 lines instead of 2)
        I removed your B tags and put that in CSS

        All the above bulk out the CSS, If you separate content and style, the stuff you remove from the HTML ends up bulking out the CSS.

        On the positive side for CSS...

        I changed a 15-line table (plus blank lines for clarity) to a 6 line img+div. The HTML *is* simpler in my example. OK the CSS looks more complicated but its defined once and if I add another few H1 tags in the same article I'm potentially saving 9 lines of table markup each time.

        I removed the SPAN class = heading stuff from the H1s. To add a fourth, fifth etc H1 I add less code with a plain CSS approach than with your original example.

        Of course, you're way smarter than me so I'm probably misunderstanding the thrust of your response - in which case I'm sure you'll have the sense to ignore me! I kinda enjoyed playing with a bit of CSS anyway.

  12. fgmr says:

    I knew the asswipe who invented CSS; we were on TimBL's team at CERN together, briefly. (He's one of the main reasons I quit.) I think he's CTO of Opera now, or something.

    He loved the whole "cascading" bit, where one file could inherit from another. He didn't intend so much that the CSS would be embedded, as loaded separately at another URL. This would let people "steal" other sites' styles merely by referring to their CSS files.

    Better yet, he originally designed in multiple weighted inheritance. If you inherited 40% from the New York Times and 60% from the Washington Post, then all the colors, font sizes, etc. would be averaged at that ratio from those sources.

    He was a bit stumped by fonts .. what's the 40/60 average of Helvetica and Times New Roman? I was strongly tempted to tell him about metafont, just to see him go down a rathole, but in the end I figured the world would be a better place without him knowing about that.

  13. edge_walker says:

    Even though you admitted defeat, just to explain why this is happening: when you write <ul><li><p>Whatever</p></li></ul>, you expect the line saying “Whatever” to line up with the bullet. This is only possible if the P’s margin can overlap up out of the LI’s box.

    But you need to undo that. And change nothing else. You failed badly because you tried to throw out the SPAN – but making block boxes shrink-wrap is for your intents and purposes not possible. You need the SPAN to hook the style onto, you just need to make the H1 take enough space for the SPAN’s border to end up where you wanted it. So keep your markup exactly as is in the test case, and add this rule to your CSS:

    h1 { margin-top: 0.2em }

    I originally used padding instead of a margin, which Opera did not like. With the margin it works in Firefox 1.0x and in Opera 7.54/8.0 (all on Linux). Of course IE or Safari may still decide to do things differently (IE has issues with top margins, which is why I generally reflexively reach for padding first), so might require tweaking.

    The problem with CSS is that it tries to tackle an impossibly difficult problem (that tables will never be capable of): fully rewrappable layouts. I mostly like CSS (if that wasn’t clear yet), but it was a first large-scale attempt at addressing this particular kind of problem and it’s obvious that it didn’t come out right. There are millions of edge cases like lining up the bullet with the first line in the paragraph, and in CSS they resulted in a horribly complex machinery of rules that you have to understand completely to make even simple things work. It’s no easier to implement in browsers than it is to use when designing, either, so on top of the complexity of CSS, you also have to cope with multiple buggy implementations that disagree with each other. In the end, for all the noble goals it sets out to achieve and the potential it has, mere mortals resign to making less flexible CSS layouts than their table constructions would have been, and it’s hard to blame them.