Semantic HTML/CSS Development Guideliness

by M. David Green - www.mdavidgreen.com

What are HTML and CSS?

A basic HTML page skeleton should tell the browser what kind of content to present, in what order the content should appear, and what to do with it.

I start with a !DOCTYPE to tell the browser what our page will consist of; for example, a public HTML document that complies with w3C standards for HTML 4.01 Strict.

Next I have the HTML element, which consists of a HEAD and a BODY element. Note that you have to close the HTML, HEAD, and BODY tags (/HTML, /HEAD, /BODY)at the end of each definition.

In the HEAD I include the title, the encoding standard, and references to external stylesheet CSS files, starting with a CSS reset script, a possible CSS script with code for all the shared elements across a set of pages, a CSS script with code specific to this particular page, and then CSS scripts for displaying the page in other media, such as in print.

(You may notice that the media="Screen" attribute uses a capital S. Generally these attributes should be all lower-case. However, to overcome a potential limitation in the way Windows Mobile browsers decide which stylesheets to apply to handheld devices, it is a good practice to capitalize the S in Screen.)

In the BODY I create elements of semantic HTML and fill them with content.

At the end of the BODY tag I include SCRIPT tags. (These may also be included at the end of the HEAD section of the document if the HTML content is fairly short, as long as we remain consistent about where they live.) These tags load external JavaScript libraries, such as JQuery, or contain document-specific Javascript.

The code for the page defined below looks like this.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
<head> 
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Hello Page</title> 
	<meta http-equiv="Content-Type" content="text/html;charset=ansi" >
    <link rel="stylesheet" href="css/reset.css" type="text/css" media="Screen">
    <link rel="stylesheet" href="css/hello.css" type="text/css" media="Screen">
    <link rel="stylesheet" href="css/handheld.css" type="text/css" media="handheld">
    <link rel="stylesheet" href="css/print.css" type="text/css" media="print">
</head> 
<body> 
    <p class="description">The box on this page is ten lines down and has a dotted border.</p> 
    <div id="mainContent"> 
        <p>Hello World!</p> 
    </div> 
		<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
		<script type="text/javascript">
	    $(function() { 
	        $("#mainContent").click( function() { 
	            alert("You clicked me"); 
	        }); 
	    }); 
	</script> 
</body> 
</html>

The visual style of the elements on this page is defined in the hello.css file inlcuded, which is coded like this:


/* Formatting for the hello.html page */ 
#mainContent {width:50%;position:relative;top:10em;margin:0.5em;padding:0.5em;border:2px dotted #ff0;} 
 
/* Styles for the hello.html page */ 
body {color:#fff;background-color:#005;} 
#mainContent p {color:#fcc;text-align:center;font-family:impact,helvetica,sans-serif;font-size:3em;}
.description {text-align:center;font-style:italic;}

Cascading Style Sheets

CSS styles are usually defined in external stylesheet files, loaded in the head of an HTML document with link tags. (See example below.) They are applied to a page in the order in which they are called. If a single element has two separate style rules applied to it, the attributes that do not conflict are applied together. If the attributes do conflict, any styles defined in the first file loaded may be overwritten by style changes in the next file, and so on. For example, this code would apply the color and font-size attributes specified in the first rule to all paragraphs, including those modified by the second and third rule, but the third rule overwrites the color attribute:


.example p {color:#363;font-size;0.75em;}
.example p.decorative {font-style:italic;}
.example p.urgent {color:#f00;}

<div class="example>
	<p>This is a normal paragraph</p>
	<p class="decorative">This is a decorative paragraph</p>
	<p class="urgent">This is an urgent paragraph</p>
</div>

This is a normal paragraph

This is a decorative paragraph

This is an urgent paragraph

This permits us to make useful cascades by creating a generic reset.css file with rules that make all the semantic HTML elements look the same across different browsers, and loading that file first. Then we can load progressively more specific rules in separate files for the site-specific CSS rules, and then the page-specific CSS rules. Each of these sets of rules will inherit the attributes from previously defined rules.

CSS may also be declared directly in the head of an HTML file, by placing the CSS rules between <style>...</style> tags, as well as directly within the HTML element by adding a style="..." attribute. Styles defined within the page overwrite styles imported from external files, and styles defined within an element, overwrite any previously defined styles. Using these forceful techniques can make your code very brittle, and should be avoided.

When to Use Classes

Classes are used for styles that may be used repeatedly for different similar elements.

In CSS (and JQuery), a class is indicated by a . character.

in HTML, a class is indicated by adding class="classname" to an element.

Use a class as the default method to apply a style to any element on a page.

Classes may be inherited from a parent element, and a single element may use multiple classes by using a space-separated list of classes, so try to re-use existing classes whenever practical.

This is a CSS style definition, for the class "title"


.title {color:#f00;font-weight:bold;}

It will apply to any HTML element with the class "title"


<p class="title">This is a title</p>
<div class="title">
	<p>This title inherits its class from the contining div</p> 
</div>

and make them all look like this:

This is a title

This title inherits its class from the containing div

When to Use ID's

ID's are used to identify page elements that are unique to a page, such as input fields in a form, or header blocks that are only used once on a page, but may be used the same way on every page in a site.

In CSS (and JQuery), an id is indicated by a # character.

in HTML, an id is indicated by adding id="idname" to an element.

Use an id if you are creating a major section of a page, such as a header or a navigation bar, or a form element such as an input field, a select list, or a checkbox. Otherwise, it's preferable to allow the Javascript programmers to assign id's to elements.

This is a CSS style definition, for the id header


#header {background-color:#000;color:#ddd;border:3px solid #ccc;padding:0.5em;font-family:sans-serif;}

It will apply to the single unique HTML element with the id "header"


<div id="header">
	<p>This is the only div on the page with the id of header</p>
	<p class="title">This paragraph inherits both the #header and the .title styles</p>
</div>

and make it look like this:

Javascript is used to change the content of an HTML page, and apply various CSS styles, dynamically in response to user action and other factors. When writing HTML and CSS, consider how you might use Javascript to manipulate the pages. It is important to provide the Javascript code with useful semantic targets which can be used to populate the page with new information, or style elements by applying different CSS. For example, if there is a unique word in your document that you know will be generated in Javacscript, create a ... to contain it, and assign it an appropriate id.

The JQuery Javascript library encourages unobtrusive scripting through external linked documents. It allows programmers to target HTML elements in a page using the same CSS definitions that define the style of the elements. While that is convenient, it is generally more flexible to separate the functionality of the Javascript from the presentation of the CSS. That way, if things change in the style, they are less likely to compromise the program logic. In addition, Javascript takes longer to parse through a document looking for styles that match a specific class definition than it does locating an element by its unique id attribute. Therefore, I recommend generally using unique id's for targeting Javascript to an element, and using classes and inheritance to apply styles to an element. Of course, this is a guideline, not a hard and fast rule.

If the Javascript programmer needs to alter the HTML, move HTML blocks from one place to another using Javascript commands such as the JQuery commands .after() or .before(), or dynamically generate CSS styles not defined in the CSS pages, the application will be more brittle and harder to maintain and customize in the future. The HTML should stand alone, in a semantically logical order, and present the entire skeleton of the page independent of the Javascript.

Knowing how the page will work before coding the HTML skeleton is critical. For example, it allows us to create the spans which the Javascript programmers will fill with information, and the divs which will be shown, hidden, and otherwise manipulated. With Javascript, a single page may change radically over its lifetime on a user's screen. Examine the page carfully to see which elements will change, and which ones will stay the same. We are less likely to break the layout of a page if we replace the content of a single defined header div across the lifetime of the page than we are if we hide that header div and then show another replacement div in the same location.

Start with Semantic HTML

Semantic HTML is at the core of maintainable, plastic, accessible web development. Semantic HTML means using the right tag for the right function.

There are infinite ways to get the page to look the way you want it to look. If you start with a semantically correct HTML skeleton, you should be able to change the layout and the design in CSS, and change the content and the presentation in Javascript, practically without touching the HTML.

The following is a list of useful semantic HTML tags. You will notice that the div and span tags are not included. Div's are used to contain, identify, and target multi-line groups of semantic HTML elements which fill their containers from edge to edge. Spans are used to contain and identify text, as well as groups of semantic HTML elements which fall within a single line in a wrapping manner, like the words in a paragraph.

If there's an HTML tag for a given function, you should use it instead of a <div> or a <span>. For example, use <ul> for a list, <table> for tabular data, <h1> for a header.

Defined HTML elements usually have a default presentation in a given browser, and these default presentations can sometimes be different from what you might desire, or be different in one browser compared with another. For that reason, I recommend the careful application of a reset.css file for cross-browser continuity.

No piece of text should sit directly inside a div. If the text looks like a paragraph or a sentence, it should be placed inside a <p>...</p> block.

As with a lot of HTML elements, different browsers treat paragraph tags differently, altering the amount of spacing above and below. That's one reason why we use a reset.css script, which provides uniform presentation for paragraph elements across browsers, and allows us to define our own custom styles when we want to.

Do this:


<p>This is a paragraph, and this is an <em>italicized word</em> in the paragraph.</p>

not this:


<div>This is semantically incorrect</div>

These tags define different levels of headers on a page, from top-level h1 to lowest-level h6. Most pages provide some visual clue to users about what text is a main header, what text is a subheader, etc. It is important to use these tags instead of styled paragraphs or divs to present headings and subheadings, so that screen readers will understand what function each section of text was intended to serve.

Just like div tags, each of these tags can be styled to match the design requirements of any page. Unlike div tags, these semantic HTML elements are recognized by all browsers, screen readers, and site scrapers to help create outlines and navigation cues to your site.

It can be a good idea to embed the actual text of your header in a span element. This allows you to target font sizing at the text without altering the font-size for the element itself. That can be useful if you are using em-based measurements for sizing and positioning of the header itself.

Do this:


<h2><span>This is a header</span></h2>
<p>This is the text of a paragraph introduced by the header above.</p>

not this:


<div class="headerStyle">This is an undifferentiated div element</div>
<div class="bodyStyle">This is another undifferentiated div element</div>

Both ordered <ol>...</ol> and unordered <ul>...</ul> lists contain list-element<li>...</li> blocks for each item on the list. For accessibility, it is recommended that you add a title attribute to the opening tag of your list.

If you are presenting a set of similar sibling items one after the other, whether they are shown horizontally or vertically, they should be added to the page as list items. An excellent example is a navigation menu, which includes buttons or links to different pages around a site. By styling the elements, it is possible to get a semantically correct simple list to show up as a menu bar across the top, down the side, or as a set of tabs.

An unordered list uses simple bullets for each item by default. An ordered list uses numbers to keep items in a specific order. Consider which one will best achieve your purpose, remembering that each can be styled any way you choose.

Do this:


<ul title="List of items">
	<li>This is an item</li>
	<li>This is another item</li>
	<li>This is yet another item</li>
</ul>

To get this:

  • This is an item
  • This is another item
  • This is yet another item

Or, with a little CSS styling, this:


Definition lists <dl>...</dl> contain term elements <dt>...</dt> and defintion elements <dd>...</dd>. This structure is very useful when creating a nested list such as a glossary or a table of contents with terms and definitions, or representing certin types of related data. For example, the expandable headings on this page are contained inside <dt>...</dt> elements, and the contents are inside <dd>...</dd> elements.

Do this:


<dl title="Web term definitions">
	<dt>HTML</dt>
	<dd>The code used to define the structure of a web page</dd>
	<dt>CSS</dt>
	<dd>The code used to define styles and layout for HTML elements</dd>
	<dt>JQuery</dt>
	<dd>A Javascript library which uses CSS identifiers to manipulate HTML elements</dd>
</dl>

To get this:

HTML
The code used to define the structure of a web page
CSS
The code used to define styles and layout for HTML elements
JQuery
A Javascript library which uses CSS identifiers to manipulate HTML elements

Users interact with the information in a page through form elements. Even in an Ajax application, it is important for the form elements to be presented in a semantically appropriate manner. Otherwise, different screen readers will have problems interpreting what you intend a user to do with your form.

Different browsers render the standard form elements in different ways, but only slightly different. For most purposes, it is not a good idea to style and modify the look and behavior of a form element. Because if this, the CSS options available for most form elements are quite limited. It is generally possible to override css and use Javascript to force styling onto form elements by either obscuring them or replacing them with custom widgets, but that serves to make your forms less accessible and more confusing. (Of course, if that's your intention...)

A form is contained within a <form>...</form> set. The first tag in a form is the beginning of the <fieldset>...</fieldset> set of tags to contain the individual form elements. Each fieldset starts with a <legend>...</legend> where you define what makes this set of form elements related. A single form may have multiple fieldsets, each marked with a different legend to distinguish the set of form elements it keeps together. The use of the form-fieldset-legend combination is essential to accessible form design.

Each form element must have a unique id. Most form elements also require a <label for="formElementId">...</label> element, which is used to make the visual label for the element. (Elements such as submit buttons don't require a label because the label is built into the design of the element itself, using the value attribute.)

Do this:

<form id="contactForm">
	<fieldset>
		<legend>Identity</legend>
		<label for="title">Title: </label>
		<select id="title">
			<option value="select">Select One</option>
			<option value="mr">Mr.</option>
			<option value="miss">Miss.</option>
			<option value="mrs">Mrs.</option>
			<option value="ms">Ms.</option>
		</select>
		<label for="firstName">First Name: </label>
		<input id="firstName" />
		<label for="lastName">Last Name: </label>
		<input id="lastName" />
	</fieldset>
</form>

An HTML element should contain the type of content its label describes. The <strong> and <em> elements can be thought of as the semantic replacements for the older HTML tags <b> and <i> if you like. These labels describe how the information is intended, rather than specifically how it should be styled. That said, these elements do have default styles in most graphical browsers. They can also be styled in CSS to display in any way you desire. These tags are placed at the beginning and end of a span of text which flows with a paragraph, and should not be used to enclose paragraph-like block elements such as <p> and <div>.

Proposed standards for HTML 5 have revived the <b> and <i> tags, applying to them the semantic meaning which they have gained from their popular use on web pages. The <b> element will identify text intended to be stylistically highlighted as a focus of attention among other sibling spans without indicating any particular level of importance, and will usually be represented in graphical browsers as bold text. The <i> element will designate a span as text to be interpreted with an alternate voice or mood, and will usually be represented in graphical browsers as italicized text.

A conceptual break between sub-sections of an article can be represented by a self-closing <hr /> element. The default look of this element in graphical browsers is a solid line across the width of the section being divided. In CSS, you can style the look of this element to support the design and message of your page.

A line-break element is another self-closing tag, usually represented as <br />. This tag can be useful for splitting sections of raw text, but should never be repeated to create white space. There are CSS styles such as padding and margin which will usually accomplish the same goal without forcing extra elements into the HTML.

You may want to be careful about how you use <br /> in pages that you wish to have the same formatting across multiple browsers. In particular, Firefox is fond of rendering these breaks with the full height of a line, while IE will render the breaks as if they had no height. These particular HTML elements can be difficult to target with appropriate styles. If you are creating a list of items separated by line breaks, you may be better off using a <UL> list and a series of <LI> elements instead. These can be styled much more reliably.

Tables are used for information which is best understood as a grid of columns and rows. In the old days, tables were the only way to get page layout to work across browsers. The problem was that the information being presented in that way didn't usually make sense as a table. Now we have semantic HTML and CSS, which are both more flexible and more uniform than tables for defining the presentation of a web page. The advantage of reserving the table element for tabular data is that it gives us the ability to isolate and interact with the information in useful ways, without confusing users who may want to access our pages through tools such as screen readers, text-only browsers, page scraping technologies, etc.

There are a few accessibility conventions which need to be addressed when using a table. Following these guidelines also offers you the ability to style and target header, body, and footer rows directly in the CSS:

  • The opening tag of a table should always include a summary attribute, describing the content of the table.
  • The <caption> element comes immediately after the opening tag for the table. It may be styled like a paragraph, and is preferred over using a separate header element above the table.
  • The <colgroup> and <col> elements are useful for styling cross-browser compliant columns widths; particularly when multiple tables need to align to each other, as when a table with just headers is used to provide fixed headers for a scrolling table body, as in this example. Multiple The <colgroup> groupings may be defined in theory, but since the <col> element is only minimally stylable through CSS, the practical uses are negligible. By applying the same class name to this element and the cells that make up the associated column, complex styles that will work across all browsers seamlessly can be targeted to a column of elements through the class name.
  • The header rows of a table should contain <th> cells, and should be placed inside of a <thead> element. (If you want to set the width on a column, set it only on the th element at the top of that column.)
  • The body rows should contain <td> cells, and should be inside of a <tbody> element.
  • The footer rows should contain <td> cells, and should be inside of a <tfoot> element.

table.fruit th {width:33%;background-color:#cde;border:1px solid #333;}
table.fruit td {background-color:#edc;border:1px solid white;}

<table class="fruit=" summary="This is an example of a fruit table">
	<caption>Fruits and their Categories</caption>
  <colgroup>
    <col class="column1" />
    <col class="column2" />
    <col class="column3" />
  </colgroup>
	<thead>
		<tr>
			<th class="column1">Nightshade</th>
			<th class="column2">Citrus</th>
			<th class="column3">Berry</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td class="column1">Tomato</td>
			<td class="column2">Orange</td>
			<td class="column3">Banana</td>
		</tr>
		<tr>
			<td class="column1">Eggplant</td>
			<td class="column2">Lemon</td>
			<td class="column3">Apple</td>
		</tr>
		<tr>
			<td class="column1">Pepper</td>
			<td class="column2">Kumquat</td>
			<td class="column3">Kiwi</td>
		</tr>
	</tbody>
</table>
Fruits and their Categories
Nightshade Citrus Berry
Tomato Orange Banana
Eggplant Lemon Apple
Pepper Kumquat Kiwi

There are CSS rules which can target styles at groups of columns, or at columns and rows based on their location in a table, using the <colspan> element. This is not supported across all browsers yet, and should not be relied upon.

Best practices for clean and maintainable HTML and CSS:

Standards help the next person to see your code--who might be you, six months later!

There are an infinite number of ways to format code correctly. They will all work. Everyone has some conventions they prefer. But we need to work together as a team. That means we need to share code. That's much easier to do if we all follow the same formatting conventions.

The decision about what standards to use needs to be made just once, and then adopted. Which standards get adopted is almost arbitrary. The value is in having made a choice. So I'm proposing some standards to improve readability and consistency. It's not because I think this is the only way that works. It's so that we can work together without re-learning the formatting and coding style every time.

By default, graphical browsers are very tolerant of white space. The following two examples of HTML code are rendered exactly the same way, but the second one is much easier to understand:

<ul title="List of items"> <li>This is an item</li> <li>This is another item</li> <li>This is yet another item</li> </ul>

<ul title="List of items">
	<li>This is an item</li>
	<li>This is another item</li>
	<li>This is yet another item</li>
</ul>

A semantically complete HTML page should allow positioning of any element anywhere on the page using CSS alone. While there may be need for some browser-specific hacks to get floated, resized, or padded elements to play together nicely in defective or buggy browsers, it is not recommended to use Javascript to move an element from one place in the hierarchy to another.

In general, if you find yourself using .before() or .after() a lot in your Javascript, you might want to consider whether what you are doing will alter the structure of the HTML page.

This is single-line formatting for CSS


.title {color:#000;font-size:1.5em;font-weight:bold;}

This is multi-line formatting for CSS


.title 
{
	color:#000;
	font-size:1.5em;
	font-weight:bold;
}

There are arguments for both approaches. For example, multi-line CSS is better for tracking changes in version control systems, and some people find it easier to read. Single-line CSS fits more information cleanly on a single screen, making it easier for some people to scan the code visually for identifiers and settings. Either one will work, as long as it is used consistently. For the sake of consistency, I recommend amd use single-line CSS.


.neutral {color:green;}
.peaceful {color:blue;}
.alert,
.warning,
.important {color:red}

This is actually an accesibility requirement. (see the ADA Amendments Act of 2008, which goes into effect on January 1, 2009). It provides a way for vision-impaired visitors to understand the content being presented on a page.

But <img> tags should only be include if you are actually displaying an image in the page, as in a catalog or a gallery. Graphics used as bullets, labels, and for page design should all be placed using the CSS background-image property of a block-level element. And these background images managed by the CSS should ideally live inside of an images folder within the css folder, rather than the root directory, to facilitate future application skinning.


<img src="/images/bottle.jpg" alt="medicine bottle" />

Use CSS class names like .alert instead of .redText for items with a semantic meanting, such as alert boxes. Maybe someday, the alert class will need to be blue. And keep in mind that every item worthy of having a class should have some semantic meaning if you are designing your page correctly.

Classes should be defined at the appropriate level of the cascade for the type of element being styled. For example, an alert message class will probably be the same for all pages in a site, and should be defined in the CSS file that covers the entire site. If it needs to change on one page, the CSS cascade can be used to revise the aspects of the rule that change on that one page, such as the color, while still inheriting the shared aspects, such as the font style.

It is important to leave a place for Javascript to insert the result of an operation for dynamically generated content. Similarly, it is important to be able to style the structural elements of the page without affecting the Javascript elements. If the result of a Javascript operation can be presented as plain text, it is preferable to do all the styling and formatting in your HTML and CSS, so the Javascript only has to provide plain text. For better modularity, I generally do not target CSS styles other than font sizing directly at the span, but rather at the containing element.

In this case, the span will inherit the fancy styling of the div, as will the $ at the beginning.


<div class="fancyStyle">
	<p>$
		<span id="uniqueResult">100.00</span>
	</p>
</div>

It is largely for the sake of separating code and presentation that I try to use id's only for form elements and divs that define basic layout across multiple pages of a site. I use classes with deep levels of inheritance for most of the CSS styling requirements. This leaves the Javascript free to target specific divs and spans with id's which relate clearly to any other back-end coding conventions, such as web service calls or database field names. If I need to change the styles at some point, I will work primarily with the classes instead of the id's.

In the CSS files, I will frequently use the names of the divs to distinguish sets of related rules that should only apply in a specific, unique part of the application. I will generally format a section of the CSS with rules that all start with the id of the containing div for easy scanning. Within that block of CSS, I will place rules in order of cascade importance from top to bottom, allowing inheritance to dictate which rules get defined first.


#header .title {padding:1em;}
#header .title h1 span {font-size:0.8em;}
#header .logo {width:200px;height:35px;margin:0;overflow:hidden; background: url(./images/logo.gif) no-repeat top left;}

Adding extra span tags does increase the weight and clutter of your HTML code. However, having a span sitting inside of a wrapper tag allows you to target the wrapper with style rules such as positioning, margins, padding, etc. while targeting font-size to the span directly. If you are using ems for relative sizing, you won't have to recalculate your page layout every time you need a piece of text with a different font size. The spans are also very useful for separating content from presentation, since they can be named and targeted for text replacement independent of the design.

Do this:


h1 {padding:1em;}
h1 span {font-size:75%;}

<h1><span>This is a Heading</span></h1>

not this:


h1 {padding:1.33em;font-size:75%;}

<h1>This is a Heading</h1>

There are sometimes a few ways to get a custom sybol such as a "©" (&#169;) or a "&" (&amp;) to show up in HTML text. For some, the convenient code with letters spelling out what it is supposed to display may not be universally supported across all browsers. It is important to know how to use the numerical codes rather than the more intuitive shortcuts.

It is also advisable to style some of these symbols, such as the symbol, with a class that will force the font to "Lucida Sans Unicode" to make sure they display properly on all browsers. Not all fonts support as many special characters and are as universally installed as Lucida Sans Unicode. For convenience, I generall include a class of .unicode in my reset.css file just for this purpose. It's not always necessary, but it's useful for odd or poorly supported symbols

Symbol Meaning Code
® registered trademark &#174;
© copyright &#169;
sound recording copyright &#8471;
trademark &#8482;

Use this to style all h1 elements in all #header divs...


#header h1 { background-color:#fdd }

pageone.html:
<div id="header">
	<h1>This is the Title</h1>
</div>

pagetwo.html:
<div id="header">
	<h1>This is the Title</h1>
</div>

pagethree.html:
<div id="header">
	<h1>This is the Title</h1>
</div>

...instead of redundantly styling each title as a separate named div


#titleForPageOne { background-color:#fdd }
#titleForPageTwo { background-color:#fdd }
#titleForPageThree { background-color:#fdd }

pageone.html:
<div id="titleForPageOne">
	This is the Title
</div>

pagetwo.html
<div id="titleForPageTwo">
	This is the Title
</div>

pagethree.html
<div id="titleForPageThree">
	This is the Title
</div>

Always aim for the minimum number of shared, reusable, and inheritable CSS classes. Elements that share similar styling, like alerts, should all inherit their styling from the same appropriately named class.

Sometimes you will create CSS styles which depend on a specific sequence of HTML elements to achieve the desired effect. Like all languages, CSS includes a comment tag /*...*/ for information you want displayed to people reading your CSS, but ignored by the rendering engine of the browser. These comments can be stripped in production deployments for faster loading.


/* EXAMPLE sliding panel horizontal stretch div, with vertical stretch limited by the graphics:
/* <div class="line article">
/* 	<div class="item articlePanel">
/* 		<div class="articleBody">
/* 			<div class="articleContent">
/* 				<p>Your content goes here</p>
/* 			</div>
/* 		</div>
/* 	</div>
/* </div>
*/
#article .articlePanel {background: url(../images/panel_background_left.gif) no-repeat left top;}
#article .articleBody { width:970px;margin:0 10px;padding-top:2em;
	background: url(../images/panel_background_right.gif) no-repeat right top;} 

You would think that, if you don't set any styles on a simple element like a button or a paragraph, all browsers would display it the same way. Unfortunately, each browser manufacturer sets a number of display defaults as soon as you open a new page, and these defaults form the basis for any future styles you may apply

The most straightforward solution is to over-ride these defaults with a known set of values which display consistently across as many browsers as is practical. To that end, I have provided a file called reset.css. In addition to setting consistent default values for displaying the majority of common page elements, it also provides a number of convenience classes.

<link rel="stylesheet" href="css/reset.css" type="text/css" media="screen" >

Be sure to include the reset.css file first in the list of CSS files being linked to your HTML documents, before adding any further stylesheets. This allows the default styles to cascade through properly.

Printing is not unusual behavior for web users. It is important to consider what elements of your page will be redundant, wasteful, or confusing if included in a printed version, and make plans to hide these when printing. Happily, most modern browsers (including Internet Explorer 6) recognize this need and will apply a print-only stylesheet to pages when a user issues a print command in the browser.

When defining font sizes for print, remember to use pt values for any font sizes which you want to fix manually. There is no consistent relationship between the number of pixels of height on a monitor and the number of points of height on a printer. The pt value will print consistently across all browsers when the page is actually printed, even though the sizes may look very different on the screen if you view the printable version of the page.

Support for many of the more useful CSS attributes which apply to printed pages is spotty at best across browsers. Opera is probably the most compliant. However, there are a few CSS tricks that can help make printing less painful for your users, such as setting the backgrounds to white, and the text color to black. I have provided a file called print.css which shows some of the basics.

To trigger this effect, make sure all your stylesheets are labeled with the appropriate media type. This will usually be "screen" but for printing, it will be "print"

<link rel="stylesheet" href="css/print.css" type="text/css" media="print" >

Be sure to include the print.css file last in the list of CSS files being linked to your HTML documents.

<span class="copyright highlighted">&copy;2008</span>

A popular fomratting convetion knows as camelCase involves eliminating spaces and capitalizing all but the first word in multi-word identifiers for consistency with Java conventions. Personally, I prefer to use only lower-case letters and replace spaces with underscore characters. The most important thing is to be consistent. Avoid acronyms, single-letters, and numbers in names unless there is a logical reason to use them. Name unique elements with complete words or camelCase phrases for clarity.

Do this:


<div class="someLongName" />

not this:


<div class="some_long_name" />

or this:


<div class="SomeLongName" />

Every HTML tag has an opening and a closing structure to label the beginning and end of some content, usually involving repetition of the element name after a "/" character. Certain elements, such as IMG, BR, and HR, don't employ this syntax because they are not designed to contain anything. While HTML 4.01 permits us to leave these as unclosed elements on the page, it will not hurt to add a "/" before the final ">" of the tag. This syntax is required for XHTML, but it is good coding practice, and makes it easier to scan a page for potential unclosed elements.

Do this:


<br />

not this:


<br>

An "em" is a sizing unit which changes with the size of the font on the page. It represents the height and width of the largest letter in the alphabet: capital M. By using ems and percentages to define the width and height of elements, you are allowing users to scale a page to suit their needs without the rish of altering your layout and presentation. Use pixel dimensions only to match fixed-size images and media, or to enforce mandated customer requirements.

Remember that font sizes set in ems and percentages are inherited by child elements. If you set the font size of a div to 1.5em, and then set the font-size of a paragraph inside that div to 2em, the resulting paragraph will actually have a font size of 3em relative to the font sizes outside of the parent div.

It is safest to set font-size only on the last element in a nesting chain that contains text. That is one of the reasons why it is important to put all text inside a paragraph or a span, so it can be targeted independently by CSS when necessary. Having text directly inside a div element with no span or p element to contain it makes consistent font sizes harder to maintain.

The most flexible structure for CSS stylesheets is to have one reset.css file which you use for all projects, one global site-wide CSS file for all the shared elements across pages in a site, and one CSS file for each individual page. In addition, you may want a site-wide or page-specific print.css file (or other media-specific CSS files) for formatting a given page to a different output medium than the screen.

If you find yourself writing in-line CSS, stop and consider how to accomplish what you are trying to do semantically.

Logo images and headers with text displayed against graphic backgrounds can be important design elements, but using them without semantic HTML markup can make pages inaccessible to some visitors. A good way to get the visual effect you want without sacrificing accessibility is to put logos and header graphics into the CSS as background elements, with the text filled in through HTML. Set the margin to 0, and use the width and height of the image to set the width and height of the elements. You can use the CSS attributes for margin-left and font styling on the span inside the element to get the visual placement and effect you desire:


h1.logo {width:200px;height:35px;margin:0;overflow:hidden;
	background: url(./images/logo.gif) no-repeat top left;}
h1.logo span {margin-left:75px;}

<h1 class="logo"><span>Logo</span></h1>

Should give you this:

Logo

If the graphic has embedded text, and the design of the text is critical, the best solution is to include the exact text from the image in the HTML for the element, and use the CSS attribute margin-left:-100em; to push the span with the text off the page. That way, it will be hidden from most users, but visible to people who have their CSS styles turned off, such as people using screen readers.

Notice that I am using an images directory which sits inside my CSS directory for this background image. This lets me keep my background images separate from any other images being used on the page, for convenient skinning down the road. The CSS url attributes can rely on consistent relative paths which start at the root of the css directory from which they are called.

Another nice trick to reduce the number of images on your page is to scan the design for images which are used as in-line icons, and include them as background images in the CSS. This allows an image to move smoothly through a page along with an HTML element without cluttering your HTML code

Do this:


.verifiedIcon {padding-left:10px;background:url(./images/verifiedIcon.gif) no-repeat 0 5px;}

<p class="verifiedIcon">This is a verified sentence.</p>

not this:


<p><img src="./images/verifiedIcon.gif" width="9" height="9" />This is a verified sentence.</p>

To get this:

This is a verified sentence.

We are still in the dark ages of HTML, with browser support issues trumping semantics in some instances. One of the issues we still have to contend with is the use of a line-break as a "clearing" element for some CSS display techniques. This is usually done by adding a line-break element with a style of clear:both after the final <div> element in a set of <div> elements which have been floated. An alternate technique, which also works for eliminating an IE6 bug related to nested floating elements, is to include a <div> element with a style of clear:both, containing a single character, and resized so it is not visible.

In the reset.css file, I have defined the class .clear differently for div's and br's, so they can be used as <br class="clear" /> or <div class="clear"> </div> as needed. The reset.css file contains a class definition called .clearfix which works with modern browsers to add these elements dynamically when applied to a div which contains a float, but that solution does not work for Internet Explorer 6 or 7. As I said, these are still the dark ages.

The W3C standards organization has created a testing tool for validating your HTML files, and a similar tool for validating your CSS files, against established standards. These tools allow you to use a URL, a file upload, or simply paste text into a form, and generate a report telling you how well it complies with the rules for properly structured HTML and CSS.

I use HTML 4.01 strict, and these tools will compare the HTML with the standards established for that flavor of HTML. In addition to catching many issues which could affect cross-browser compatibility, I will also see errors and warnings for self-closed tags (eg: <br />), and target attributes in link tags for opening links in new windows (eg: <a href="newpage.html" target="_blank">new page</a>). These testing tools also flag many CSS hacks designed to circumvent buggy behavior in specific web browsers (eg: .hacked {_width:1em;}).

The self-closing tags convention comes from XHTML, an XML standard for writing HTML documents. Some HTML elements do not have any contents, but XML requires all elements to open and close, and suggests that elements without any contents self-close by adding a slash before the final "<" character of the element. Although self-closing tags are not defined as part of HTML 4.01, they do not break anything, and they enforce the practice of considering each tag as something which must be opened and then closed. I generally use self-closing tags for <br />, <hr />, and <img src="file.gif" alt="image" /> elements, among others.

The target element in link tags is useful, and is recognized and supported in all major browsers, even when the document type is explicitly set to HTML 4.01 strict. The decision not to recognize the target attribute is still considered a controversial one. The alternative is to use Javascript to simulate this functionality, and I prefer not to add extra code to applications for the sake of complying with the W3C standards. However, there are times when a generated browser window needs attributes which can only be set with Javascript.

It's not difficult to build a site so that it complies with current accessibility standards if you start with semantic HTML and CSS. One way to prove that to yourself as you code is to view your site regularly during development with all the CSS turned off. This is how your site will appear to people using alternative accessibility tools such as screen readers.

Many sites include a lot of flashy branding, marketing, and other boilerplate information above the unique content for a page. That stuff is easy for most viewers to scan past, but can be slow and inconvenient for someone using a text-only device or a spoken interface. One nice thing to do for these people is to include special links at the very top of your page that will allow them to navigate directly to the menu and the content area for your site. These links can be hidden off-screen for other visitors, and should also be hidden when printing the page.

/* in your print.css file */
.screenOnly {display:none;}
/* in your reset.css file */
.offScreen {margin-left:-999em;line-height:0;}
<!-- early inside the body of your HTML page -->
<div class="screenOnly offScreen">
	<a href="#content"><span>Jump to Content</span></a>
	<br />
	<a href="#nav"><span>Jump to Menu</span></a>
</div>

... navigation div with an id of nav
... main content div with an id of content

A few tricks to help make your layout work across multiple browsers:

If the programmers who write the browsers and the experts who decide on the HTML and CSS standards were all perfect, and all agreed on everything, there might be no need to worry about making a site look and act exactly the same way everywhere. However, standards are sometimes subject to interpretation, and browsers are sometimes written without adequate support for agreed standards, or with differences driven more by market concerns than presentation consistency. That's why we need to test.

You may not need to support every browser that has ever been made, but you do need to consider what browsers your visitors will be likely to use. Often your customer will propose minimum support requirements. If you have a log with past visitor history, that can help you figure out if you really need to support Internet Explorer 5.5 on Macintosh, or if supporting Internet Explorer 7 and Firefox 3 will be adequate.

You may also not need to support pixel-perfect identical presentation across all the browsers you do choose to support. There must be a balance between the effort involved and the benefit gained.

It is very important to have a test environment which matches the capabilities of the majority of your users. It is generally not easy to install more than one version of any given browser at the same time on the same machine. Virtualization tools such as Virtual PC are very helpful. Microsoft will even provide web developers with free, time-limited installation snapshots of Windows XP or Vista, capable of running Internet Explorer 6, 7, and 8 (currently in beta). With these, you can have multiple environments running simultaneously on one machine.

The choice between conditional comments and CSS hacks is an ongoing debate with strong opinions both pro and con. Hacks live in the CSS and help keep the HTML semantically clean, whereas conditional comments live in the HTML. I have standardized on using CSS hacks because they allow us to leave the HTML markup clean, and maintain all of the styles in files with names and locations driven by the architecture. I always put my hacked attributes at the end of a set of style definitions for any given selector, unless there is a reason why the order needs to be different. There are many useful hacks, and new ones are discovered and debated constantly in blogs and online tutorials. These are not the only ways to accomplish this type of targeting, but they seem the cleanest, and consistency is important:

  • IE6 Only: prefix an attribute definition with a "_" (eg: .gutter {_width:1em;})
  • Exclude IE6: prefix a selector with a "html>body" (eg: html>body .gutter {width:1em;})
  • IE6 and 7: prefix an attribute definition with a "*" (eg: .gutter {*width:1em;})
  • IE7 Only: prefix a selector with "html>body" and the attribute definition with a "*" (eg: html>body .gutter {*width:1em;})
  • IE8 Only: follow an attribute with " /*\**/" and the value with "\9" (eg: .gutter {width /*\**/:1em\9;})
  • IE Only (any version): follow the value of an attribute with "\9" (eg: .gutter {width:1em\9;})
  • Firefox Only (any version): wrap a complete selector in a mozilla-specific selctor (eg: @-moz-document url-prefix() { .gutter {width:1em; } })
  • Firefox 3 and higher: add ", x:-moz-any-link, x:default" to a selector (eg: .gutter, x:-moz-any-link, x:default {width:1em;})
  • Firefox 3.5, Chrome, and Safari Only: prefix a selector with "body:nth-of-type(1)" (eg: body:nth-of-type(1) .gutter {width:1em;})
  • Chrome and Safari Only: wrap a complete style definition in a webkit-specific selector (eg: @media screen and (-webkit-min-device-pixel-ratio:0){ .gutter {width:1em;} })

While CSS provides you with the pseudoclass :hover which allows you to change the look of an element when the mouse cursor is hovering over it, Internet Explorer 6 will only recognize that definition if the element being styled is a <a> link tag. To get other elements to change their style when hovering, you need to use Javascript.

Furthermore, the order in which you declare your psuedo classes matters in CSS. There are four (or five) possible pseudo classes to determine what happens based on user actions:

  1. :link styles clickable elements. (eg: a:link {color:#006;}
  2. :visited styles elements which have been clicked.(eg: a:visited {color:#606;}
  3. :focus styles elements which have focus (as when tabbing through a page with a keyboard). (eg: a:focus {border:1px dotted #ccc;}
  4. :hover styles elements which are directly under the mouse pointer.(eg: a:hover {color:#FF0}
  5. :active styles elements which are currently being clicked on by mouse pointer. (eg: a:active {color:#000}

It is important to define these styles in the order listed above, because these five states cascade logically from one to the next. As in all CSS, the last rule defined overrides any previous rules. If there are cases when an element may take on the characteristics of a later defined CSS style, that style should logically overwrite the definitions from previously defined styles. Whether a given user's browser is smart enough to know what you meant is not a chance you want to take.

If you think about how you treat a link, it will make sense. By default, it's a link. If it's visited, it's a visited link. If you give it focus, it's a focused link. If you hover over it, it's a hovered link. If you are clicking on it, it's an active link.

If you prefer not to think, just remember the order. LVFHA. It's the same as the acronym for the Las Vegas Future Homemakers of America.

Most browsers more modern than Internet Explorer 6 can handle images with smooth gradations of transparency as long as they are saved and served in the PNG format. This allows designers to create gentle drop-shadows and blended colors dynamically in the browser instead of pre-rendering them into static images. Unfortunately, IE6 and earlier versions do not support this functionality natively.

There are a number of hacks that attempt to add transparent PNG support to IE6. Most of these come with caveats about slow performance, incomplete support, and UI issues ranging from unclickable form elements to inconsistent flickering displays. Among the best are the SuperSleight JQuery Pligin for Javascript sites, and the DD Belated PNG Fix for non-Javascript sites. Both of these require a consistent path to a transparent single-pixel GIF file to hack the transparency into the element you are targeting.

However, one less-common trick is to use the obscure PNG-8 format for your transparent images. In most browsers, this format will render all graduated transparency smoothly just like any PNG. In IE6, a PNG-8 file will behave like a GIF with one-bit transparency, rendering all partially-transparent pixels as fully transparent, and all non-transparent pixels as opaque. It's not exactly the same visually when a smoothly graduated drop-shadow is a firm requirement, but it can be adequate when an element has essentially solid edges. This has none of the drawbacks of hacked support solutions, as a PNG-8 is treated just like any native image format in all browsers. The PNG-8 format also generally provides better optimization than GIF when you need an image with one-bit transparency.

Adobe Photoshop (as of version CS4) cannot render a PNG-8 image with transparency, but Adobe Fireworks can. You just need to select the PNG-8 format, choose alpha transparency, click the "rebuild" button under the color palette, and then export as a PNG. The file name will still end in .png, and nothing else will indicate that your PNG-8 file is any different from any other PNG, except for the way it renders in IE6.

Any element can be displayed as a block (like a div or a paragraph) or inline (like a span). The display setting affects whether the browser treats it as a block item which should expand to fill the horizontal space available, or an inline item which should occupy the minimum horizontal and vertical space while wrapping, like a word in a paragraph, along with other items.

Some browsers consider the existence of a margin attribute on an element as a signal that the element should be treated as a block. In the case of a floated item that should line up horizontally with other floated items, this can create a stair-step appearance in some browsers. Using the display:inline; CSS style allows the element to be treated as a span, and occupy the minimum horizontal space, so that it's less likely to be forced down to the next line.

Some versions of Internet Explorer will also double the margin settings of any float on the side that matches the direction of the float. That means that a margin-right of 1em on an element that is floated right will become a margin-right of 2em in IE6. This can best be solved by applying the necessary margin to a nested child element inside the float, but it can also be addressed by using a CSS hack to set a custom margin on the floated side of the floated element that is half the desired value.

You want a scrolling table inside a fixed area of the page. You create a table that is too long to show up inside a div with a pre-defined height, and give the div overflow properties which allow the content to scroll. In Firefox and Internet Explorer 6, the containing div gets a scroll bar which allow the user to see the whole table. In Internet Explorer 7, the table will scroll in response to a mouse wheel, but the scroll bar is invisible. If you resize the browser window, the scrollbar suddenly shows up.

The trick to fixing this known bug is to use a CSS hack so the table width is reset to 99% only for Internet Explorer 7. If you set it to 99% for all browsers, you will see a small margin before the scroll bar in every browser except Internet Explorer 7

.wrapper {height:10em;overflow-x:hidden;overflow-y:auto;}
html>body .wrapper table {*width:99%}

All fieldsets in a form need a legend to explain their purpose. This is usually a good element to use for visual labels to distinguish sets of related elements in a form, such as a group of radio buttons or check boxes. Unfortunately, Internet Explorer has a problem formatting this element as a proper independent block. Adding relative positioning to the element and its parent can help, but it will break if any parent needs to be able to scroll. In that case, all the legends will remain fixed in place as the rest of the form scrolls around behind them.

An odd but effective solution is to include the content of the legend in a <span> (as you always do when adding text inside elements like this, of course), and then apply {float:left; display:inline} to both the legend and its internal span.

In one of the rare instances in which Internet Explorer does a better job than Firefox with standard CSS definitions, Firefox has a known bug which will prevent the content of a div which is longer than a single printed page from printing. The quick fix is to apply the attribute overflow:visible to the offending div in the print.css stylesheet (which you have, of course, already included in your document to handle print output).

Tables have thead and tfoot elements to hold the headers and footers, allowing you to style these differently from the rows of the table. The developers of Firefox decided that it made sense to use these elements to trigger repeating headers and footers as a default when a long table needs to be printed across multiple pages. That way you don't see a printed page with a bunch of rows of data and no context for what they mean. However, this is not the default behavior in Internet Explorer. To add this behavior for IE, apply the style display:table-header-group to your thead elements, and the style display:table-footer-group to your tfoot elements in your print.css file.

At the moment, this behavior cannot be triggered in Safari and Chrome using CSS, so you may also want to disable it in Firefox for consistent behaviour across browsers, or if the repeated headers and footers cause other layout problems for the printed page. To do this, apply the style display:table-row-group to both your thead and tfoot elements.

When you need a fixed-width select list in a form, Firefox is very friendly about allowing the options which show up under the element to extend beyond the width specified. They just float above other elements until one is selected. The select panel at the top stays the same width, and the formatting is untouched. Internet Explorer behaves differently. If the options are wider than the width specified, they are chopped off to maintain the width when they appear.

The solution is to avoid sitations where a select list will need to remain short for layout, but should be able to list longer elements. This isn't always possible, but there is a way to use Javascript to get around the problem:

  1. When the select element acquires focus, you should capture the value of the width and the position attributes from the CSS into local variables, then
  2. set the width for the select element to "auto" and the position to "absolute" (For IE6 you may need to set the width to an actual em value that will contain your longest select list option)
  3. When the select element loses focus, you should restore the value of the width and the position from the local variables

Making a web page compatible with Internet Explorer 6 without breaking more modern browsers or abandoning desired functionality can be tricky. One feature some developers turn to is the non-standard CSS attribute "expression," which is supported only by Internet Explorer.

Expressions are like short in-line scripts to control the values being passed to elements from the stylesheet. They are defined in the CSS, and only work when the client has Javascript enabled. Expressions are ignored by all browsers other than Internet Explorer. Using expressions, it is possible to reproduce some of the useful but unsupported CSS attributes for Internet Explorer 6 users. A classic example is min-height. This attribute allows a developer to define the minimum height that a block element will collapse to if there is not enough content to push the height beyond this point. THe min-height attribute is not supported in Internet Explorer 6, but it is possible to simulate it using expressions:

.wrapper {min-height:400px;_height:expression((this.clientHeight < 405) ? "400px" : "auto");}

The expression defined above checks to see if the element with the classname "wrapper" is shorter than 405 pixels, and dynamically sets its height to 400 pixels. By using the underscore, this expression is limited to Internet Explorer 6, and is ignored by Internet Explorer 7. The use of a slightly higher number for the test value helps avoid some Internet Explorer crashes that can be triggered by this type of expression. However, it does not necessarily prevent all such crashes. If other CSS attributes are also being set on this same element, the expression can still cause a browser crash for Internet Explorer 6 users. For that reason, it is best to avoid expressions when possible.

In this case, it is possible to use a few extra <div> elements and some custom CSS to simulate the min-height effect, although the solution is awkward and may limit some further design options regarding background patterns.

.wrapper {height:100%; min-height:480px;background-color:#fff;}
.wrapper .minHeight {_border-top:solid #fff 480px;}
.wrapper .minHeightContent {_margin-top:-480px;}

For this solution to work, the div with the class "wrapper" is set to the desired min-height for most modern browsers. Nested inside that div is the "minHeight" div, which contains a further "minHeightContent" div. These use CSS attributes with underscore hacks for Internet Explorer 6 to create a div with a fixed border set to the same background color as the wrapper div, and an inner div with a negative margin to offset the positionong forced by the border. This is not an elegant approach, since it forces us to add two unnecessary divs into the HTML document, but it does provide min-height funtionality that is cross-browser compatible.

A cleaner solution, involving no additional inner div elements, can also be made to work for min-height and min-width, assuming you avoid overflow attributes:

.wrapper {min-height:480px;_height:auto !important;_height:480px;}

While it is perfectly correct to create a set of CSS definitions which apply one style when the element has a specific class, and a different style when it has that same class as well as another class, you might find it easier to avoid this scenario. Internet Explorer 6 is very particular about how it applies multiple classes on a single element.

p.relevant {color:#F00}
p.urgent {font-weight:bold}
p.important.urgent {background-color:#FF0;}
<p class="relevant">This is relevant</p>
<p class="urgent">This is urgent</p>
<p class="relevant urgent">This is relevant and urgent</p>

This is relevant

This is urgent

This is relevant and urgent

If you view these three lines in most modern browsers, the first line is red, the second line is bold, and the third line is red, bold, and has a yellow background.

In Internet Explorer 6, the background color from the third CSS line is applied to both the second and the third lines of the HTML. This is because IE6 ignores all but the last class in a multi-class CSS style definition.

The attributes "colspan" and "rowspan" are always set in the HTML of a table, and cannot be manipulated with CSS. This makes sense, since they are tied directly to the tabular data being presented in the table.

Putting these attributes in all lower case will work just fine in a static HTML page. But if you are setting a rowspan on a td in your table through Javascript, remember that Internet Explorer 6 and 7 require that attribute to be called "rowSpan" with a capital "S" or your tables will collapse and be unreadable.

Hiding the overflow in the horizontal dimension maintains the layout of a column regardless of the width of the information it is trying to contain. If you don't want your layout to break content is too wide for a column, or when a page resizes, you may need to sacrifice visibility of your content. Alternatively, if you want your content preserved at the expense of your layout, you may want to consider a fixed layout which forces a user to scroll horizontally in the browser when the window is too small to contain your layout.

In some browsers, tables do not inherit the body font settings. This can be useful, since one generally does not want generic body text formatting for tablular information. Just rememeber to style the text in your <th>...</th> and <td>...</td> elements.

Over the years, many solutions have been proposed to the problem of creating a flexible layout for defining the placement of the elements of a page, so that they will fall in the same locations across different browsers and plaforms. Some of these solutions work better than others, but all of them have their advocates, their detractors, and their quirks.

For non-dynamic templates, one interesting solution is the Faux Absolute Positioning model. The concept is to divide the page into horizontal div slices with the class .line, and arrange divs with the class .item specified percentages from the left side of the page. This is done with a cascade, first moving all of the .item divs off the right edge of the .line div completely, and then bringing them back into the visible space of the .line div with a negative margin-left value.

/* Generic .line and .item classes */
.line {position:relative; float:left; width:100%; display:block; _line-height:0;}
.item {position:relative; float:left; left:100%; _line-height:1.5;}

/* Application-specific placement for .item divs on a #headSection .line div */
#headSection #titleImage { margin-left:-100%;width:40%;}
#headSection #statementInformation {margin-left:-60%;width:25%;}
#headSection #universalNav {margin-left:-35%;width:35%;}

<div class="line" id="headSection">
  <div class="item" id="titleImage">
	<h1 class="logo"><span>Logo Image</span></h1>
  </div>
  <div class="item" id="statementInformation">
	<p><span class="date">Date: July 28, 2008</span></p>
  </div>
  <div class="item" id="universalNav">
	<span class="dropdownWrapper">
		<select id="drop">
			<option value="2008"><span>2008</span></option>
			<option value="2007"><span>2007</span></option>
			<option value="2006"><span>2006</span></option>
		</select>
	</span>
	<p>
		<strong><a href="#">Print</a> | <a href="#">Help</a></strong>
	</p>
  </div>
</div>

See an example of a header layout based on the code above.

This is very effective across multiple browsers when you need to specify the width and positioning of multiple elements within a horizontal stripe. It can also be nested, for creating horizontal segments within other sections of the page. Note that it is not necessary to use this for every section of a page. If a horizontal section of the page does not require specific positioning of its sub-elements, there is no need to define it as a .line.

This technique is best reserved for page layout, and not for dynamic content. If an intended .line or .item might be generated dynamically after the page is loaded, or might contain dynamically updated content, this technique can cause problems for Internet Explorer 6. For an example of this, see how the code above appears in Internet Explorer 6. It works fine in more modern browsers, but all the .item elements hide off to the right in Internet Explorer 6. Then watch what happens when you then resize the window even slightly. I call that the Rocky Horror bug, since it makes the content items which were displayed dynamically after the page loaded "jump to the left."

Logo Image

Date: July 28, 2008

Print | Help

Online Learning and Testing Resources

  • Favelet Suite: page analysis tools
  • ReCSS: a CSS refresher
  • Validate XHTML: W3 page structure analysis (for published sites)
  • Validate CSS: W3 CSS validity analysis (for published pages)
  • BuiltWith: to determine the architecture of a (published) site
  • jQuerify: injects the JQuery library into any page
  • SelectorGadget: helps identify selectors to target elements
  • Aardvark: reports on the selector for a highlighted page element
  • Design: helps you modify page design to match a grid layout
  • Edit Any Website: lets you modify the content of any page
  • XRAY: detailed information about any selected page element
  • MRI: find elements that match a typed-in selector
  • anticss: generate CSS code to reverse the effects of any CSS file
  • Translate: translate the language of a (published) page
  • WTFramework: report on the JS library used on a page
  • Screenshot: capture an image of the current (published) page
  • Browsershots: see what your (published) page looks like in a wide variety of browsers/platforms