Homegrown CSS Standards

The following is a brief outline of a few tips, tricks, and personal preferences for standardizing your HTML/CSS websites and web applications. These suggestions have been pulled from personal experience and tend to fit 99% of the projects I’ve been involved in. Remember, even though I’m calling them standards, there are always exception, so don’t simply mimic any set of standards – evaluate the situation and apply the most appropriate solution.

Good Foundations

It is generally easier to begin style implementation with div’s. A CSS-based HTML design typically will have appropriately used div’s to section off major groupings of HTML data. For example:

…
<body>
	<div class=”container”>
		<div class=”header”>
			<h1>My Example HTML</h1>
		</div>
	
		<div class=”nav”>
			<ul>
				<li>Microsoft</li>
				<li>Yahoo</li>
			</ul>
		</div>

		<div class=”content”>
			<h2>My Example Subheader</h2>
			<p>Some lorem ipsum goes here…</p>
			<p>And now a bit more…</p>
		</div>
	</div>
</body>
…

As you can see, there are no tables being used for design purposes, table should generally be used for tabular data and not design layout. HTML with heavily used tables limits the ability for design to be fully manipulated by a CSS style sheet.

Now that we’ve written HTML that is geared to a CSS-based design, we can use the “hooks” we created to manipulate the CSS however we need and it will be readable for both an HTML designer/developer and a CSS developer.

For an example of design being completely dictated by CSS see CSSZenGarden for more. The HTML is always the same and only the CSS file changes in each example.

HTML that is developed in Visual Studio under the default validation settings for HTML will provide warnings/errors of invalid or inappropriate HTML. Please heed these warnings to provide the cleanest amount of HTML to work from. This is the foundation of any web application and for all other aspects such as CSS, JavaScript, and even code-behind to function properly, HTML should be sound. After all warnings have been addressed through Visual Studio, take time to also validate the HTML in an HTML Validator provided by W3 Consortium.

CSS File Organization

When developing a hierarchy of style sheets, separate styles into common and specific categories, then create a common.css file to store all common styles and individual specific CSS files for other major collections of CSS styles. See below example:

If I have a website that consists of three major portals, Public, Vendors, Administration; I would most likely create four CSS style sheets; one for each major portal, as well as one common.css file for common styles used in all portals.

Example: Use of Multiple Cascading Style Sheets

Common.css

a img 
{
	border: none;
}

Public.css

@import url(“common.css”);

body 
{
	background-color: #CCC;
}

Vendors.css

@import url(“common.css”);

body 
{
	background-color: #AAA;
}

Administration.css

@import url(“common.css”);

body 
{
	background-color: #FFF;
}

This allows us to gain the true benefits of “cascading” style sheets, as each style sheet is importing and thus inheriting (or overloading, when appropriate) the parent style sheet(s).

Use discretion as to the number of CSS files to import against. In most cases, there is only need for a single import per CSS file. Several imports can become unwieldy and difficult to track down CSS class inheritance.

CSS Formatting

When adding CSS styles to a CSS style sheet, format the document in the following general sections:

Import CSS file(s)
HTML overloads
Custom CSS styles

Example: External CSS Sample

Example.css
import url(“common.css”);

body 
{
	background-color: #FFFFCC;
}

input, textarea, select 
{
	background-color: #FFFFAA;
}

/*Content found within the main content placeholder.*/
.content 
{
	padding: 15px;
}

/*Main navigation section.*/
.nav 
{
	border: 1px solid #000;
}
.nav ul 
{
	list-style-type: none;
}
.nav ul li 
{
	margin-left: 10px;
margin-right: 10px;
}

All HTML overloads are located first and grouped together, and custom styles make up the rest of the document. Notice, that all custom styles have comments as to what they affect to assist in maintaining changes. HTML overloads can have comments as well, but are not really necessary. Additionally, styles either as HTML overloads, or custom, that are cascading within a document should be grouped together without vertical spacing as demonstrated with “.nav”. Please note that there are no CSS styles applied to ID elements! These are commonly used as follows:

Example: CSS Style Based on Element ID

#nav 
{
padding: 15px;
}

The reason for this is that we want only class declarations in the HTML because it specifically tells the HTML observer (developer) that this object/tag has a CSS style applied to it, whereas the use of CSS against an ID tag does not convey this. When CSS is complex and uses repositioning or floats, etc. this can become very difficult to identify where HTML issues are occurring verses applied CSS. ID tags in HTML should be used for identification of objects/tags (for use with javascript/codebehind, etc.) and not for CSS styling.

Miscellaneous Formatting

Use spaces to enhance readability such as the following:

Bad:
.nav{background-color:#000000;}
.header{
	padding:10px;
}

Good:
.nav 
{
	background-color: #000000;
}

.header 
{
	padding: 10px;
}

Always terminate style attributes with a semi-colon, even when there is only one style attribute being applied.

Explicitly write out style attributes for less-common or hard to read attribute values instead of combining them into a single line:

Example(s): Readability

Bad:
padding: 10px 5px 10px 5px;

Good:
padding-top: 10px;
padding-right: 5px;
padding-bottom: 10px;
padding-left: 5px;

Additionally, when managing page layout widths, adjust widths from the highest containing item possible rather than specific nested objects. See the following HTML/CSS example:

…
<body>
	<div class="container">
		<div class="header">This is the header!</div>
		<div class="nav">
			<ul>
				<li>Link 1</li>
				<li>Link 2</li>
			</ul>
		</div>
		<div class="content">
			<p>Here is some content.</p>
		</div>
	</div>
</body>
…
CSS:

Bad:
.header 
{
	width: 780px;
}

.nav 
{
	width: 780px;
}

.content 
{
	width: 780px;
}

Good:
.container 
{
	width: 780px;
}

CSS Style Naming

Some common things to remember while naming styles:

  • Avoid using names which are too specific to the styles being applied, for example: “bluetext” or “leftNav”. Today you may be developing the text to be blue, or the navigation to be on the left, but tomorrow the text may change to green and the navigation may be right or top of the page.
  • Use consistent naming convention: Florida Family will be using camel case (“mainNav” or “nav”).
  • Don’t use acronyms or uncommon abbreviations such as “hlsm” (highlighted sub-menu).
  • Attempt to keep names fairly short, generally less than 15 characters.
  • .

  • Do not prefix CSS styles with “css” such as “cssNav”.

CSS Validation

Don’t forget, it’s never a bad idea to validate your CSS (W3 CSS Validator)!

Thanks for reading, I hope this makes life a little easier when working with your HTML/CSS projects!

Very good benefit, for very little work – IIS Compression for IIS6

I’ve seen quite frequently that many applications have not implemented compression. I personally, think it’s great, simply because processor power is fairly cheap and the faster I can deliver content to my users the better. To me, the negligible difference in processing power is definately worth the increase in user experience when pages load sometimes 2 to 3 times faster.

Before we get started, I think it would be beneficial to take a trip to a compression reporting service to see if your server is currently using compression and if not, what potential benefit you would most likely receive. These compression reports are usually free and only require a URL to do the analysis. I have used PipeBoost in the past to display compression reports.

Ok, now that you can quantify the potential benefit, let’s get started by showing you my personal settings for IIS compression. Many thanks to Frendy who originally turned me on to the benefits of IIS compression and allowing Microsoft’s IIS compression engine to do all the work rather than writing my own HTTP modules for it.

Keep in mind, for your own application you may want to have different settings than what I’ve chosen. I will not go into the detail of each setting, however, this should give you a jumping point to dive a little deeper for your particular application.

Changing IIS to Enable Compression

The first change needs to be made by going to:

IIS Manager > Right click on Web Sites > Click Properties > Click the Service Tab

Change the screen to look similar to the following (Checkmark Compress application files and Compress static files):

Website Properties in IIS

Changing the Metabase.xml

Next, we want to change the metabase.xml file to direct IIS on the compression scheme we want to use. I set up schemes for both gzip and deflate (though gzip is most often used I believe).

You will want to add the following section to your metabase.xml file directly below the <IIsFilter></IIsFilter> section.

Note: This may already be there, if so, simply review the values and match them up appropriately.

<IIsCompressionScheme	Location ="/LM/W3SVC/Filters/Compression/deflate"
		HcCompressionDll="%windir%\system32\inetsrv\gzip.dll"
		HcCreateFlags="0"
		HcDoDynamicCompression="TRUE"
		HcDoOnDemandCompression="TRUE"
		HcDoStaticCompression="FALSE"
		HcDynamicCompressionLevel="9"
		HcFileExtensions="htm
			html
			txt
			js
			css"
		HcOnDemandCompLevel="10"
		HcPriority="1"
		HcScriptFileExtensions="asp
			dll
			exe
			aspx
			asmx
			ashx
			asbx
			axd"
	>
</IIsCompressionScheme>
<IIsCompressionScheme	Location ="/LM/W3SVC/Filters/Compression/gzip"
		HcCompressionDll="%windir%\system32\inetsrv\gzip.dll"
		HcCreateFlags="1"
		HcDoDynamicCompression="TRUE"
		HcDoOnDemandCompression="TRUE"
		HcDoStaticCompression="TRUE"
		HcDynamicCompressionLevel="9"
		HcFileExtensions="htm
			html
			txt
			js
			css"
		HcOnDemandCompLevel="10"
		HcPriority="1"
		HcScriptFileExtensions="asp
			dll
			exe
			aspx
			asmx
			ashx
			asbx
			axd"
	>
</IIsCompressionScheme>       
    

That’s all there is to it. You should get a pretty strong benefit from compression depending on your particular setup; hope this helps!

Someday I Need to Write a JS Library

Unfortunately, I’ve never sat down and written a full blown out JS library; at least not in a really clean and reusable way. However, I do have a few custom Javascript functions that I tend to use in several projects.

The majority of these can be found by doing a quick search on google or some equivalent; but I figured I could keep them here for an easy find and if anyone else happened upon them they might be useful as a small collection.

Javascript Cookie Management

//create cookie
function createCookie(name,value,mins) {
	if (mins) {
		var date = new Date();
		date.setTime(date.getTime()+(mins*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

//read cookie
function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

//erase cookie
function eraseCookie(name) {
	createCookie(name,"",-1);
}

String Manipulation

function inStr(strSearch, charSearchFor) {
	for (i=0; i < len(strSearch); i++)
	{
	    if (charSearchFor == mid(strSearch, i, len(charSearchFor)))
	    {
			return i;
	    }
	}
	return -1;
}

function len(str) {
    return String(str).length;
}

function mid(str, start, len) {
    if (start < 0 || len  iLen) {
        iEnd = iLen;
    }
    else {
        iEnd = start + len;
    }
    
    return String(str).substring(start,iEnd);
}

function left(str, n) {
    if (n  String(str).length) {  // Invalid bound, return
        return str;                // entire string
    }
    else { // Valid bound, return appropriate substring
        return String(str).substring(0,n);
    }
}

function right(str, n) {
    if (n  String(str).length) {  // Invalid bound, return
        return str;                     // entire string
    }    
    else { // Valid bound, return appropriate substring
        var iLen = String(str).length;
        return String(str).substring(iLen, iLen - n);
    }
}

Page Navigation

This is really just shorthand for 99% of the popup pages that I would use when I called window.open().

function openPopup(page, width, height) 
{
    window.open(page,'PopupWindow','width='+width+',height='+height+',resizable=no,scrollbars=no');
}

Page/Form Input Helpers

//**************************************************************//
//Makes input control (form control) a highlighted color.  Works
//specifically for textboxes and textareas.
//
//obj = "this" if being triggered by event or if null is passed 
//      or accepts an overload of any document control object.
//
//className = name of css class for active input box.
//--------------------------------------------------------------//

function doActivateInput(obj) {
    if(obj == "[object Event]" || obj == null) {
        obj = this;
    }
    
    if(obj != null) {
        obj.className="input_active";
    }
}

function doDeactivateInput(obj) {
    if(obj == "[object Event]" || obj == null) {
        obj = this;
    }
    
    if(obj != null) {
        obj.className="";
    }
}
//**************************************************************//


//**************************************************************//
//Preloads images for a page to correct wait time when displaying 
//hidden/new images
//
//imgPathArray = string array of img paths to preload 
//--------------------------------------------------------------//
function preloadImages(imgPathArray) {
    for(i=0;i<imgPathArray.length;i++) {
        var img = new Image();
        img.src = imgPathArray[i];
    }
}
//**************************************************************//


//**************************************************************//
//Helper function for adding textbox activate/inactivate event listeners
//
//obj = the object (textbox/input box) to perform action on
//--------------------------------------------------------------//
function doHelperAddTextboxEventListeners(obj) {
    if (obj.addEventListener) {
       obj.addEventListener("focus", function () {doActivateInput(this);}, false);
       obj.addEventListener("blur", function () {doDeactivateInput(this);}, false); 
    } 
    else if (obj.attachEvent) {
       obj.onfocus = function () {doActivateInput(obj);};
       obj.onblur = function () {doDeactivateInput(obj);};
    }
}
//**************************************************************//


//**************************************************************//
//Helper function for adding buttons hover state event listeners
//
//obj = the object (button) to perform action on
//--------------------------------------------------------------//
function doHelperAddButtonEventListeners(obj, activeImgPath, inactiveImgPath) {
    if (obj.addEventListener) {
       obj.addEventListener("mouseover", function () {this.src=activeImgPath;}, false);
       obj.addEventListener("focus", function () {this.src=activeImgPath;}, false);
       obj.addEventListener("mouseout", function () {this.src=inactiveImgPath;}, false);
       obj.addEventListener("blur", function () {this.src=inactiveImgPath;}, false);   
    } 
    else if (obj.attachEvent) {
       obj.onmouseover = function () {this.src=activeImgPath;};
       obj.onfocus = function () {this.src=activeImgPath;};
       obj.onmouseout = function () {this.src=inactiveImgPath;};
       obj.onblur = function () {this.src=inactiveImgPath;};  
    }
}
//**************************************************************//

Check out Script.acul.us!

For a really fun (and useful) Javascript library try out: Script.aculo.us, which does a wide range of client-side effects to really provide a richer UI and better web-applications.

Firebug! Why develop without it!

If you haven’t seen Firebug then you’re definately missing out. Firebug has been out for quite a while, it’s nothing new; but I think it never got the attention (especially in .NET developer circles) it deserved.

Once, at a convention I brought up that Firebug had javascript debugging capability for a long time while Visual Studio waited until 2008 to really offer it.

Let me make sure I’m not confusing anyone, Firebug is just an addon to FireFox and is not a development environment. It is however a great tool for developers working on multiple browsers to debug javascript and peak under the covers of their web resources and clientside processing.

Here are some nice screenshots I just made of how I use Firefox:

Screenshot of Resources Loading Clientside

You can list your resources that are loading (images, external files, etc.). By doing so, you can see load times as well as broken links or clientside errors (marked in red) while loading.

Debug Firebug

Screenshot of Javascript Debugging in Firefox

Javascript debugging has always been a bit of a pain. With Firebug you can use a familiar system of breakpoints and even an Immediate-style window to check variable values, etc.

Javascript Debugging in Firebug

More than one way to skin a cat… and a webpage

This is a multi-series blog posts regarding one of many ways to take a graphic design and convert it into HTML. This is the current method that I tend to use when doing fairly basic website designs.

Please note, that there are several different ways to do this and their are advantages and disadvantages to each approach; not all of which are technical in nature, such as maintainability, cost of skilled labor when dealing with highly complex CSS methods versus more typical CSS/HTML use, SEO, etc. Many individuals/companies have turned towards developing very strong CSS based designs while others have remained in table-based layout. For the purpose of this post, we will be approaching slicing graphic designs using CSS but from a more “boxed” approach.

The term “boxed” that I am using, simply refers to the majority of the design being segregated out into box regions. I will try and demonstrate this with screenshots.

The design

Let’s begin by starting with our graphic design. The following is a very simply design I started for a friend of mine who sells motorcycle parts. This design was never finalized, so it will work perfectly for our demonstrative purposes and we can continue to build upon it in future posts.

Demo Website Homepage Screenshot

Ok don’t laugh too hard at my attempt at graphic design, I’m not a graphic designer and this is not a production site (but I gave it a shot right?).

Conceptualizing Regions

Now when I view this, I tend to break everything apart into boxed regions. First, major regions starting vertically. For this particular design, I view it as 5 regions which are as follows:

  • Header (logo, search box)
  • Navigation, (navigation, login link)
  • Intro Content (intro/promo text, supporting image)
  • Tabbed Content (what’s hot, browse catalog, search products)
  • Footer (footer links, text logo)

It is perfectly acceptable to do more or less specific regions. For example, I could have made the tab and the content in the tabs seperate regions, or make the header and navigation a region, Intro and Tabbed Content a section, and footer.

Let’s visually demonstrate the region’s we’ve chosen for this example:

Demo Website Homepage Overlay Screenshot

Now, keep in mind, these are not slices. These are for conceptualizing only. We don’t want to slice this in this manner for several reasons; we don’t want to mix images which should be optimized as .gif versus .jpg, we don’t want to use graphics when we can use text, etc.

HTML Conversion

Now that I pretty much know how i want to begin grouping everything, I am going to work top-down to begin converting this design into HTML. I want to stay within each region and work from left to right using a CSS to create a tableless design.

Here is the HTML for the regions that we’ve just seperated:

<div id="header"></div>
<div id="navigation"></div>
<div id="promocontent"></div>
<div id="tabbedcontent"></div>
<div id="footer"></div>

Ok, we’ll expand on this quite a bit in upcoming sections so stay tuned to find out more about conceptualizing, slicing, and building basic html from graphic design mockups.

Teaser

In the next section we will be covering how to build out each section (header, navigation, promocontent, tabbedcontent, and footer) based on the current design.