Ghost Town Markup

An experiment in developing a fluid/elastic XHTML layout with minimal markup, CSS2 and a sprinkling of DOM scripting magic.

I'm very lucky. I get to work with some great clients and I'm currently working with a very cool consultancy company. Part of the brief was to do something which no one in his industry had done before and I wanted this to involve code as well as design. I'm off travelling at the weekend and And All That Malarkey will be in the careful hands of three guest authors while I'm away (Peter Roxburgh, Patrick Lauke and Bruce Lawson).


But to say au revoir I thought I share some of the interesting stuff that might be going into the site.

First a sneak preview of the design

A sneak preview of the design

Ghost town

I intended the site to use a liquid layout with an elastic side column. A little negative margin trickery always does the job nicely.

XHTML

<div id="container">
<div id="branding"> ... </div>

<div id="content">
<div id="content-main"> ... </div>
</div>

<div id="content-sub"> ... </div>
<div id="siteinfo-legal"> ... </div>
</div>

CSS

div#container { width : 100%; }
div#content { float : right; width : 100%; margin-left : -22em; }
div#content-main { margin-left : 22em; }
div#content-sub { float : left; width : 21em; }
div#siteinfo-legal { clear : both; width : 100%; }

Here's a look at the first example.

Tombstone

I've been striving recently to drastically reduce or remove <div> id or class names from my code with a view to including them only where necessary for Microformats. I even joke that my guys should now pay for id or class names out of their wages. So I thought it might be interesting to remove all names from my markup.

With no ids in the document the first task was to hook in my CSS rules to generate the layout structure. Here a combination of,

performed their magic.

body>:first-child { }
body>:first-child>div { }
body>:first-child>div+div { }
body>:first-child>div+div>div { }
body>:first-child>div+div+div { }
body>:first-child>div+div+div+div { }

In all CSS2 capable browsers, the second example works a treat.

Deadwood

Of course Internet Explorer currently does not support any of these selectors, but I am now reaching a point where I believe that we need to move forward with modern browsers by using modern methods and then provide a safety net for less capable browsers. The safety net comes courtesy of the DOM and a tiny script by Philip Roche which installs id styling hooks only for less capable browsers.

function startDivIds() {
if (document.all  &&  document.getElementById && document.getElementsByTagName ) {

var divs;
divs = document.getElementsByTagName("div");
 
for (var i = 0; i < divs.length; i++) {
divs[i].id = 'div'+i;
}

}
}

window.onload = startDivIds;

And an equally tiny CSS file gives Internet Explorer what it needs.

* html #div0 { }
* html #div1 { }
* html #div2 { }
* html #div3 { }
* html #div4 { }
* html #div5 { }

Try the final example in Internet Explorer.

Go for your gun

So that's it. A liquid/elastic column layout experiment with the leanest markup I can muster. I'm unsure of the real practical advantages of this technique or whether it over complicates matters. But as an experiment in progressive enhancement I'm impressed at what a little CSS2 and DOM scripting can do.

Bullet time?


Replies

  1. #1 On July 19, 2005 02:00 AM B. Adam said:

    I tried this earlier this year with my earlier blog design -- but on a much smaller scale. I, too, was trying to avoid div ids and class names.

    But, I found, that semantically it was almost worse than using #left, #right or #bottom, #top as div ids.

    Mainly because what happens if you want to move those divs around a little? Or add a new div in the middle? Not only do you have to go into the CSS and find out exactly where that new div lies in the heirarchy -- or where the old div was in the heirarchy -- but you have to go into the IE specific CSS and make the change there, too. In the end, it just wasn't worth the extra effort -- I decided ids aren't really that bad.

    But, that was just me ;)

  2. #2 On July 19, 2005 02:03 AM Ramin said:

    I personally prefer to have ID's and Classes on my html elements. It makes it easier to read the code and understand what is happening. I don't really see any advantages of getting rid of the ID's and/or Classes.

    In regards to IE and its lack of support for those selectors, you should take a look at Dean Edward's IE7: http://dean.edwards.name/IE7/intro/

  3. #3 On July 19, 2005 04:19 AM Richard M. said:

    I agree... it's a neat trick and all, but leaving out ids and classes makes the style of the site dependent on the structure. And one of the best parts about standards-based coding is that it enables a (almost) complete separation of the two.

    Having said that, though, it's pretty nice bragging rights to have such clean code. :)

  4. #4 On July 19, 2005 06:45 AM Paul V said:

    I agree with the fellows before me...kind of a neat conceptual parlor trick but it can confuse you later on unless it's commented completely, and the hassle of using the script to fall back on for non-CSS2 browsers seems like an overly complicated solution.

    Thanks for the idea though...

  5. #5 On July 19, 2005 09:06 AM Faruk Ateş said:

    The problem with this approach is that you're actually removing semantics from a page, now.

    ID and CLASS attributes have semantic meaning, and while they are often "abused" for creating a zillion-and-one hookups for CSS styling, they can and should still be used properly.

    Example:

    <ul id="menu">
    ...
    </ul>

    This isn't just a matter of convenience for styling but also a semantically correct thing to do. You're identifying your menu list as a menu, using an ID attribute. If screen-reader technology were to do something in particular with id="menu|nav|navigation" for instance, it could interact with your page easily.

    Or imagine the desire to Skip to Menu. That'd just be <a href="#menu"> now, yet it would be impossible without said ID attribute.

    The same goes for CLASS attributes. They can't be interacted with as much as an ID attribute, but they still add semantic meaning when used properly.

    <li class="comment"> ... </li>
    says more about what kind of content is within the List Item than just
    <li> ... </li>

    And that is semantics. :-)

  6. #6 On July 19, 2005 09:20 AM Matt Wilcox said:

    I've been thinking about this overnight, and I'd tend to agree with what's been said in the comments above.
    I think for a website which is reasonably static this 'ghosting' method will work well - but when you start getting into generated content where the divs move up/down the HTML heirarchy, i can see this method starting to struggle. I'm going to have to try it out and see if my guesses are right, and if they can be worked around.

    It's a great way of advancing seperation of content/presentation/behaviour, but i'm not completely sold on the benefits, or even how correct it is to remove divs and ids/classes. Why? - because id's/classes are actually semantic. Not in terms of the information being presented to the end user, but they are semantic to me the coder - they explain an attribute of the information contained within. They provide context. They are also unobtrusive to the end user, and if they help define the content better...I don't see a problem with them.

    On the other hand, my wages depend on it - so kiss goodbye to those id/class attributes!

  7. #7 On July 19, 2005 09:21 AM Matt Wilcox said:

    lol - Faruk beat me to it on the Semantics argument.

  8. #8 On July 19, 2005 09:31 AM paul haine said:

    I haven't really read the article but I just wanted to point out that Ghost Town by The Specials is a really good song.

  9. #9 On July 19, 2005 09:39 AM Ben said:

    I may be missing a trick, but what is so bad having classes/ids in your mark-up - to me it allows developers to cleary see what part of content is where, and makes style sheets a lot easier to use and work with. In addition, bolting on javascript functions is a lot easier when you have classnames to pick up on.

    With your solution, what happens with js off in IE - I assume the CSS won't be picked up - if this is the case, is the world ready for CSS that IE can only see with javascript... ?

  10. #10 On July 19, 2005 11:55 AM Faruk Ateş said:

    I responded to this whole issue in rather full detail in my newest article:

    Identifying classy semantics :)

  11. #11 On July 19, 2005 12:09 PM Strict said:

    I agree with the comments about the semantic meaning of classes and IDs but I think that the experiment is still very intresting. It shows the possibilities that we would have if IE was to add support for pseudo and adjacent sibling selectors.
    They are indeed very powerful for headings, paragraphs and lists, more than for divisions: for example I found myself more than once in the condition of having to add an ugly "first" or "last" class to a paragraph to set a bottom border without wrapping the text in a useless div.
    So is it possible to hack the startDivIds function in order to work with every tag? I tried this but with my poor javascript skills I could not be able make it work and I did not find anything like this browsing around.

  12. #12 On July 19, 2005 02:15 PM Malarkey said:

    Hi guys,

    Interesting responses. In general I agree completely that this approach has many drawbacks and I'm not advocating it as a production methodology.

    I don't completely agree that a div id or class name adds to the semantics of the document. I see a difference in importance between naming a div as 'branding' and the importance of naming for Microformats.

    On another level I firmly believe that we should now be moving coding XHTML and CSS to a higher level. The tools exist (such as the selectors I use) for many modern browsers and I am considering all sorts of safety nets for older browsers with incomplete support. This is just one experiment.

    The one thing that this experiment shows (and it IS an experiment rather than a tutorial) is that there is a whole world of excitement made possible by this stuff. I can't wait to see what is going to happen.

    (Oh and yes, Ghost Town is a reaaaaallly cool song!)

  13. #13 On July 19, 2005 03:03 PM Ryan said:

    As for the comment CLASS semantics that people have been mentioning: Wouldn't it be just as semantic and less cluttered if the entire ordered (comment) list had an ID attribute?

    I mean, that's what I would do, anyway. I do try to avoid CLASS attributes whenever possible, because they are overabused.

  14. #14 On July 19, 2005 03:28 PM Faruk Ateş said:

    Malarkey:
    True, true, it's important to experiment and try and produce new techniques and concepts entirely, using the fun things CSS2 (for instance) has to offer to browsers that support it.


    Ryan:
    Classifying similar items together can still make more sense than not having any class at all, or using only an ID on its parent element.

    For instance, in my site, each comment is a LI with multiple P elements. At least one P for the comment (but more if people use multiple paragraphs) and one P for the meta data: name, timestamp, website link. I can't specify through a parent element in that situation that that one particular P element contains metadata and that all the others are the actual comment.

  15. #15 On July 19, 2005 03:45 PM Matt Wilcox said:

    I think a lot of the issue with ID's/classes are to do with how they are used. To my mind an ID/class ought to indicate the context of content encapsulated by the ID/class, not indicate the styling that might be applied in the CSS. So, I wouldn't want to ID a div as 'sidebar', because that doesn't relate to the content, only to positioning of the content. I'd call it 'article-additionals' or something similar. IDs and class names really ought to be thought of in context of the HTML only, and not in terms of how you'll use the hook in the final layout.

    With regard to MicroFormats - I don't think there's any difference in the weighting. A microformat is nothing more than an agreed method of class/id naming so other applications can leverage more meaning from the HTML. It's kind of like a gentlemans agreement, but the methods used are nothing special, and if the principles are good enough to create a microformat then they're good enough to use outside of a microformat too.

  16. #16 On July 19, 2005 03:57 PM Malarkey said:

    A couple of previous columns on the topic of naming conventions from way back when.

    What's in a name
    What's in a name (pt2)

  17. #17 On July 19, 2005 04:01 PM Chris Hunt said:

    Oh, oh, using the awesome power of modern CSS we can eschew all that boring div#footer stuff, and apply styles to the fourth div within the body element instead (provided you're not using IE with JS switched off).

    Great.

    Why on earth would you want to do that? Unless you really hate the person who has the job of maintaining the site, that is. I think this is the CSS2 equivalent of filling a site with animated gifs, purely because we can, without any thought as to whether we should.

    Sure, a lot of people use a lot more ids and classes than they need to, but attempting to remove all of them is gonna cause way more trouble than it solves.

    There are loads of way-cool things that you can do with advanced selectors. Want to make the first paragraph of each article bold with a dropped capital first letter? Easy. Want to apply styles to checkboxes that you don't apply to textboxes? No problemo! Want to obfuscate which styles apply to which parts of the layout? Are you sure you want to do that?...

    I like that trick with the negative left-margin though. Very nifty.

  18. #18 On July 19, 2005 04:14 PM Matt Wilcox said:

    I still think this is an awesome demonstration of the power of CSS selectors in modern browsers, and a good reminder that the way we do things isn't the only way to do them, and might not be the best way either.

  19. #19 On July 19, 2005 05:32 PM Faruk Ateş said:

    Matt,

    With no offense to Andy's commendable experimentation, I must say that I've seen far cooler uses of CSS2 Selectors (in modern browsers).

    LiteraryMoose's CSS Destroy has some great bleeding-edge CSS stuff that shows the power of CSS2 much better.

  20. #20 On July 19, 2005 05:57 PM Malarkey said:

    @ Faruk:

    "LiteraryMoose's CSS Destroy has some great bleeding-edge CSS stuff that shows the power of CSS2 much better."

    Oh yes! Moose is a legend. I, and I'm sure many others would be interested in some links to your cool examples. As I said before, we should be thinking of taking our CSS to the next level in modern browsers. Not just for blogs, personal sites or experiments but in real live commercial sites.

    @ Molly:

    "From an educator standpoint, I fear we're pushing too far too fast. It's really cool to be on the bleeding edge, and I'm certainly not suggesting that people shouldn't experiment because that's how innovation occurs.

    Sure. I know that this site gets read by people just starting as well as code gods like Faruk. It's important to experiment at all levels. It was experimenting that got me into this game and I don't intend to stop now.

    But this is for a very select audience, not the people on the frontlines. I'm reminded every day in my work how little people know about how to write markup or CSS well in the first place.

    Yes indeedy, but we have a plan for that don't we? ;)

    @ Matthew Wilcox:

    I think you're right. We should be always be re-examining the way we do things. That's what makes this industry so interesting. I'd much rather write stuff like this and be deafened by the chorus of "You're wrong Malarkey!" I learn a great deal from both the experiments and the replies here.

  21. #21 On July 19, 2005 06:42 PM Matt Wilcox said:

    There's a way of looking at things which I try to remember as often as possible:

    "There's no such thing as failure, only feedback. 'Failure' is just feedback that you were not aiming for. 'Failure' is a dead end, feedback you can learn from."

    Bring on the experiments!

  22. #22 On July 19, 2005 07:36 PM Ryan said:

    Faruk,

    Indeed, it is quite suitable to use a CLASS attribute when marking up something like comment metadata (especially when the markup element used is something that the user leaving the comment may also use). I just felt that an ID attribute on the parent (<ol>) element would eliminate a lot of (in my opinion; I'm not here to step on any toes) unnecessary markup clutter compared to classifying every comment (<li>) as a comment (class="comment").

    I mean, both are saying the same thing: The ID attribute on the parent element says "Every list item inside of this list is identified as part of a collection of comments", while the CLASS attribute on every list item is saying "This is a comment. This is a comment. This is a comment. ..."

  23. #23 On July 19, 2005 10:59 PM Faruk Ateş said:

    @ Malarkey,

    I fully intend to create cool CSS experiments and techniques soon, and if you keep in mind the vast increase in update frequencies on my site, it's not entirely unsafe to expect that to happen soon. For now, some patience please :) Or, for those who haven't drooled at it yet, Stu Nicholls' CSS playground.


    @ Ryan,

    I agree, one single ID on the <ul> would be much better than a class attribute on each list item. My example above was poorly chosen (I was trying to come up with an example in a hurry, didn't think it through enough. Shame on me!)

  24. #24 On July 22, 2005 02:27 AM Nick said:

    Nice experiment! You could also remove the container division and let the body have its CSS declarations. After all, the body element is a container itself, so semantically it would make more sense (Why make a division of the whole body content?) - and you have even less markup.