Traas.org site design philosophies and implementation details

Ok... this site is fairly far-reaching. My goal is to develop a completely modular and portable content-management system using PHP and MySQL. I want this site to manage everything -- all of my contacts, bookmarks, photos, journal, email, projects, music, DVD's. Obviously, there's more not done than done. Here are the design specs I have so far:

More to come as I develop the site further, and have additional time to write. Additional topics will include:

  • Full themeability via switching stylesheets
  • Alternate media types (print, etc.)
  • Portability of codebase (to any server running PHP 4 and MySQL 4)
  • Separating static content from structure.
  • Advanced end-user features (AJAX).

But for now, enjoy. If you have anything to add, as well as any corrections to my code or spelling/punctuation, feel free to let me know.

100% Standard compliance

What standards, you ask? I'm currently implementing XHTML 1.1 and CSS 2. For a site like this, that's a tad harder than it sounds. In addition to just having the document validate as valid XHTML, but I also have to check the user-agent to see what MIME-types it can accept. If it can accept such, I send the document as MIME-type application/xml+xhtml, otherwise send it text/html. What this boils it down to is that Microsoft Internet Explorer gets to parse it as tag-soup HTML, while every other modern browser can actually treat it as an XML document, which it is.

if( stristr( $_SERVER["HTTP_ACCEPT"], "application/xhtml+xml" ) ) {    
    header( "Content-type: application/xhtml+xml" );    
    print( '<?xml version="1.0" encoding="ISO-8859-1"?>' ); 
} else {
    header( "Content-type: text/html" ); 
}

Why do I want it to be sent as XML? XML parsers are simpler and more predictable than SGML parsers (HTML is SGML-based, while XHTML is XML-based). XML is also far more strict. So if I'm even slightly incorrect in the form of the code I generate, the XML parser rejects it, which aides in debugging. It forces me to generate clean code -- or else!

This actually leads to a lot of complications as well. For instance, this site allows anyone to leave comments. The problem is, a single unsupported character in a comment can render the entire page broken, as can poorly-formed HTML in the comment. So I have to make sure that I strip out all such offending bits, or convert them to XHTML entities. As you may have guessed, I do the latter.

Unfortunately, this all means that it generates code that IE does not adequately know how to deal with. So it guesses. Sometimes incorrectly. It also, not understanding any flavor of XML, parses the document as basically a group of non-related tags, and handles their positioning individually, rather than viewing the document as a whole. Finally, it's box-model is horribly broken! So I have to use various CSS hacks that only IE can see. Maybe I'll eventually separate said hacks into a separate CSS document, and only load it if we're speaking to IE.

For development, I do everything first in Firefox. Though IE makes up about 90% of the market, it's actually easier to code in something standards-compliant and coax it to render well in IE than the other way around. Also, if I develop in Firefox, it generally renders well in all non-IE browsers (I test in Opera, Safari, and Konqueror in addition to Firefox and IE.) Finally, Firefox has the most excellent Web-developer Toolbar (highly recommended -- it allows you to pick apart the document through the browser, dynamically edit the HTML and CSS code, and many other terribly useful things.)

back to top

Structure and data must be seperate from presentation

This is a VERY important point, and underscores the foundation of all the other points. Why, otherwise, would I want to use XHTML and CSS? How, otherwise, would I enable themeability, make sure it renders on multiple different classes of user agents, and make it accessible? By defining the structure of the document, populating it with content, and then defining the presentation of said document separately.

As I've mentioned before, the standards I'm using are XHTML 1.1 and CSS 2. Let's start with the former. In good page design, it's not enough that your document validates and parses cleanly, the structure should be simple, clean, flexible, and elegant. In the pre-CSS days, presentation was all that mattered. Entire pages were laid out using nested <table>'s, transparent GIF shims, such abominations as <font>, and used <h1> through <h6> merely to change the font size. Again, the only focus was presentation. Who cared if Lynx could make it readable?

Well, those are all poor practices. The real beauty of semantic languages like XHTML is their ability to describe the data. The code itself should contain meaning. If I use the <i> tag, I imply nothing about the data, but by using the <em> tag, I imply emphasis. The user agent can display it how it wants, either by italicizing it (default in most browsers), or telling the screen reader app to read it in a different tone of voice for a deaf individual.

The basic structure of all the pages at traas.org is quite simple and straight-forward:

<html>
    <body>
       <div id="container">
           <div id="header">
               <!-- page header info and page title -->
           </div>
           <div id="content-container">
               <div id="column-main">
                   <!-- main content of the page -->
               </div>
               <div id="column-sidebar">
                   <!-- links and navigation -->
               </div>
           </div>
           <div id="footer">
              <!-- page footer and links -->
           </div>
       </div>
    </body> 
</html>

The above is a slightly simplified version of the structure of every page in traas.org as defined by the XHTML source. As you can see, there's really only 4 places I've defined to put content: the header, the main column, the sidebar, and the footer. There is nothing in this structure which implies page layout, except for the names specified in each <div>'s id property. And those names have no intrinsic meaning in XHTML. They're names I chose to make my life easier. And since I created these names, I can then define them... using CSS:

#container {  
    margin: 30px auto;  
    width:  800px; 
} #header {  
    width:  800px; 
} #content-container {  
    float:  left;  
    width:  780px;  
    margin: -3px 10px 0 10px; 
}  
#column-main {  
    float: left;  
    width: 600px; 
} 
#column-sidebar {  
    float: right;  
    width: 140px;  
} 
#footer {   
    width: 800px;  
}   

As you can see above, I defined each of the identifiers that I assigned in the XHTML structure. I gave each element a fixed width. The #container contains everything, and I gave it a width of 800 pixels, and am having it center itself on the page. There are three elements that go inside, and act as rows: #header, #content-container, and #footer. The #header and #footer each are 800 pixels wide, and the #content-container is 780 pixels wide (800 - 20 for its margins).

here's where it gets REALLY interesting, however... the two elements contained within #content-container, #column-main and #column-sidebar, have their float attributes set to left and right respectively -- and that's where they lie. Notice, that on this page, your main content is in the left column between the header and the footer, whereas the navigation is in the right. The browser knows just where to put them. You could easilly swap those values, and they'd be swapped on the page as well. It frankly doesn't matter the order which they're defined in the XHTML document.

Magic...

back to top

Renders pixel-perfect in all modern browsers

Well, I guess I have to narrow this one down a bit. By "modern browsers", I'm referring to all browsers currently in development for Windows, MacOS X, and/or desktop Linux. I'm obviously not talking about Lynx, or the browser built into your cellphone, or other wonky contraptions. I'm talking about Internet Explorer 6, the various Mozilla browsers (Firefox, Netscape, Camino, etc.), Opera 8+, Safari, and Konqueror. By "pixel-perfect", I don't mean every pixel on the page has to be rendered identically (this would be impossible due to differing fonts and renderers), but instead that the placement of each block element (<div>, <table>, etc.) is placed and sized perfectly on every browser, down to the pixel. And to date, this site meets that on all of the aforementioned browsers.

In my not-so-humble opinion, the best way to do this is to develop in Firefox, check all of the other non-IE browsers, and if everything is good, fix the rendering in IE. Why? Well, Firefox has the best developer tools, hands down. It's also very standards compliant. Yeah, it doesn't pass Acid2 yet, but it's pretty good. Since it, as well as each other non-IE browser, implements XHTML and CSS2 well, any problems that show up on them will be serious fundamental problems with your code, or at least general sloppiness, if it works on some but not others.

Internet Explorer, well, is special. Short-bus special. So special that a) it can't understand XHTML (it treats it instead as HTML 4.0), b) can't understand much CSS 2, c) it's box model is beyond broken, and fundamentally different than any of the standards. So this means you have to write IE specific code, and use syntax in CSS that only IE understands, so that other browsers ignore it. Let me show you what I mean:

#content-container {  
    float:  left;  
    width:  780px;  
    margin: -3px 10px 0 10px; 
} 
/* IE Fix -- IE calculates dimensions with respect     to margins incorrectly */ 
* html #content-container {  
    margin: 0 5px;  
    width:  800px; 
}   

As you can see, I've created a second selector definition after the first. This is legal in CSS; any properties defined in a selector simply override what was already the default or prior definition. Since Internet Explorer likes to do things its own way, it allows one to define selectors starting with the "* html" prefix, whereas other browsers will ignore this definition. So we keep the "float: left" defined previously, but we override the width and margins.

Play around — I'm sure there's plenty of little stuff you'll have to redefine for IE. If you designed your page cleanly, it shouldn't be too bad.

back to top

Renders well without any graphics and/or CSS

This is actually a touchy one, as it really makes one think about the structure of the document as a whole, and what each piece of content means. The most important skill you can develop here is to look at the page content as an outline, and build it into your structure. For instance, your web site title should be your first-level heading. Each sub-section should be a second-level heading, and so on. Think about the news entries on my front page: what are they? They're little summarries of larger entries, viewed more or less as a list. That makes them <li>'s, does it not? But they don't look like <li>'s, do they? That's because I've re-defined what <li>'s look like in my style sheet in that context. In your fully rendered page using CSS, elements don't have to look like what they are.

Yet without the context defined in CSS, it's nice to know that the page will flow nicely, rather than just be a mash of text.

What about images? Well, for normal <img> tags (which are thankfully being deprecated in XHTML 2), you can simply make sure to set the alt= attribute to something meaningful (if the image is meaningful) or nothing at all (if the image is just there to look pretty.) Simple enough, right? Well, what about background images, you ask? Without the background images, your text may be unreadable, because its color may not line up too well with what's under the background image. The simple solution is to give everything with a background image also a background color. Why? The background color is painted under the background image. So the color will be painted, and then the image will load and be tiled on top. I use this extensively in traas.org. Although the background images contain all the pixels needed to act as all the colors I use in the background of my site, I still define everything in such a way that it renders nearly identical without these images -- the only really perceptible difference is that there's no drop shadows.

(P.S. — if someone is viewing your site on a computer with a slow connection, chances are good that the entire site will render before the images load, so by setting your background colors properly, your site will appear to gracefully load incrementally, rather than pop onto the screen as a bunch of gibberish and then fix itself 2 minutes later.)

back to top
Copyright © 2005-2009 Aaron Traas. All rights reserved.
Any problems, questions, or comments, email aaron@traas.org