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.

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;}

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.

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.

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

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

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.

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.

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)

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

This is centered

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.

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?

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.

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.

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

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.

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.

Sorry to hear that. I did get it looking like css2.gif using only CSShere. 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.

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.

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

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.

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.

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.

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.

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.

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.

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

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.

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.