CSS Standards

Written by Christian Heilmann 01/2004

Introduction

Cascading Style Sheets (CSS) are there to define the look and feel of one or several (x)HTML documents. By using CSS we separate content from presentation. Anything that is visual should be achieved via CSS (granted the targeted browsers permits that).

CSS should reside in its own document and should only be mixed with HTML when absolutely necessary. Furthermore, CSS should enhance the current markup and not replace it.

Applying CSS to documents.

CSS can be applied to one or several documents in different ways:

  1. Linked in the document head via the LINK element
  2. Linked in the document head via a STYLE element and the @import directive
  3. Added directly to the head via the STYLE element
  4. Inline in the HTML element via the STYLE attribute
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="ltr" xml:lang="en" lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> 
	<title>CSS standards</title>

	<!-- Standard LINK (works in all CSS able and half able browsers -->
	<link rel="StyleSheet" href="basic.css" type="text/css" />

	<!-- @import does not work for NS4.x -->
	<style type="text/css">
		@import url(advanced.css)
	</style>
	
	<!-- We can also mix imported style sheets and CSS definitions -->
	<style type="text/css">
		@import url(advanced.css)
		HTML,BODY {
			font-family:Arial,Sans-Serif;
			font-size:80%;
			color:#333;
			background:#fcc;
		}
		H1 {font-size:120%;margin:0;}
		P {margin:.5em 0 0 0;}
	</style>
</head>
<body>
<!-- Inline styles should ONLY be used in dire emergencies -->
<a href="/contact/" style="text-decoration:none;color:#c00">Contact</a>

Generally, style sheets should be added via a LINK element. If you want to use alternative style sheets you'll need to add a title to each. Alternative style sheets are supported by some browsers (Mozilla for example) and allow the user to change to the style most appropriate for him. Style switcher scripts, written in various languages, can simulate this feature for IE.

<link rel="stylesheet" type="text/css" 
href="sheet1.css" title="Default" />
<link rel="alternate stylesheet" type="text/css" 
href="bigtext.css" title="bigger font" />
<link rel="alternate stylesheet" type="text/css" 
href="contrast.css" title="high contrast" />

If we want to ensure that Netscape 4.x also gets a style sheet (by right it shouldn't, Netscape never claimed Communicator supports CSS, a shame that it does, partly at that), we can take a two track approach. The main stylesheet gets added via LINK (body font and colours) and the more sophisticated CSS gets added to a second style sheet that gets applied via @import.

<link rel="StyleSheet" href="basic.css" type="text/css" />
<style type="text/css">
	@import url(advanced.css)
</style>

Depending on the project at hand, we might want to add the main style settings into one CSS document and special settings into smaller documents that get added should they be needed.

Style definitions in the head of the document should only be added when they are absolutely necessary, it is an unclean way of applying CSS, as it once again means mixing content and presentation. The HTML document should only contain the text and the necessary markup.

Inline styles are only to be used for hacks or when a fast fix is necessary, normally there is no need for them. CSS should be CSS, not a FONT element on steroids.

Style Definitions

Styles are defined in a simple enough syntax:

Selector {property:value;}

The selector can be one of the following:

You can group selectors with a comma in between.

H1, P, DIV, SPAN {font-family:Verdana,Arial,Sans-Serif;margin:.5em 0 .5em 0;}

The property is what you want to set. For a whole list of which properties are there, check the CSS guides.

The value is the value you assign to the property. Depending on the property it can be.

Each property-value pair ends in a semicolon, let's also add one after the last one, to make it easy to extend at a later stage.

Keeping CSS documents lean and mean

Let's ensure that we don't make the CSS documents overly long. It is pretty frustrating trying to fix another developer's CSS and searching for the problem by scrolling a lot.

Line syntax

General rule: If there is only one property, the curly brackets should appear on the same line. If there is more than one property, they should appear in separate lines and get indented.

wrong:
H2 {
	color:#ff0000;
}
P {font-family:Verdana,Sans-Serif;font-size:120%;background:#cc0000;}
right:
H2 {color:#ff0000;}
P {
	font-family:Verdana,Sans-Serif;
	font-size:120%;
	background:#cc0000;
	color:#ffffff;
}

Using contextual selectors instead of classes

Let's avoid using classes in our markup unless there is a very good reason for them. A better option is to use contextual selectors and the correct markup. Also ensure to inherit as much as possible from the parent element.

wrong:
<div id="menu">
	<p class="blueback"><a class="white" href="">Link1</a></p>
	<p class="blueback"><a class="white" href="">Link2</a></p>
	<p class="redback"><a class="yellow" href="">Active</a></p>
	<p class="blueback"><a class="white" href="">Link3</a></p>
	<p class="blueback"><a class="white" href="">Link4</a></p>
	<p class="blueback"><a class="white" href="">Link5</a></p>
	<p class="blueback"><a class="white" href="">Link6</a></p>
</div>
.blueback{background-color:blue;}
.white{
	color:#ffffff;
	font-family:arial,sans-serif;
	font-size:14px;
}
.redback{
	background-color:red;
}
.yellow{
	color:#ffff00;
	font-family:arial,sans-serif;
	font-size:14px;
	font-weight:bold;
}
right:
<div id="menu">
	<ul>
		<li><a href="">Link1</a></li>
		<li><a href="">Link2</a></li>
		<li><a href=""><strong>Active</strong></a></li>
		<li><a href="">Link3</a></li>
		<li><a href="">Link4</a></li>
		<li><a href="">Link5</a></li>
		<li><a href="">Link6</a></li>
	</ul>
</div>
#menu {
	background:blue;
	font-family:arial,sans-serif;
	font-size:14px;	
}
#menu li,#menu ul{
	list-style-type:none;
	margin:0;
	padding:0;
}
#menu a{
	display:block;
	color:white;
}
#menu a strong{
	display:block;
	color:yellow;
	background:red;
}

This way the navigation also works without a style sheet (the strong shows the active element in bold) and redesigning it is a lot easier.

Using shortcut notations

To save even more space in CSS documents, we should use shortcut notations whenever possible.

p.warning {
	font-family:arial,sans-serif;
	font-size:14px;	
	line-height:200%;
	color:#ff0000;
	padding-top:5px;
	padding-left:10px;
	padding-right:10px;
	padding-bottom:5px;
	background-color:#ffcccc;
	border-style:solid;
	border-color:#f00000;
	border-width:1px;
}
Can be
p.warning2 {
	font:14px/200% arial,sans-serif;
	color:#f00;
	padding:5px 10px;
	background:#fcc;
	border:1px solid #f00;
}

Explanations:

CSS has to be used safely and wisely

Let's always make sure that CSS is enhancing and styling the document rather than being mandatory for the document to make sense.

Do not simulate markup via CSS

One of the biggest mistakes web developers did and do since CSS was introduced is to use it to design HTML elements to look and work like other elements.

wrong:
<div class="headline">Our new products</div>
<div class="subheadline">Product 1</div>
<p>...</p>
<div class="divider">&#160;</div>
<div class="subheadline">Product 2</div>
<p>...</p>
right
<h1>Our new products</h1>
<h2>Product 1</h2>
<p>...</p>
<hr />
<p>...</p>

Also let's make sure that our CSS provides fall back options, should some of the needed assets not be available:

Specificity

One common question is "if there are conflicting rules, which style takes precendence?" Here the rules of specificity apply. Consider the following example:

.spec {color: purple;}
H1 {color: red;}
<h1 class="spec">Specificity Demo</h1>

Will the H1 be red because all H1ss are marked as red, or purple because of the class attribute?

Because of specificity rules that have been created to deal with such circumstances, the .spec class wins out. Specificity describes the relative weights of various rules. Simple selectors, such as the H1 in the previous example, have a specificity of 1, while class selectors, like .spec, have a specificity value of 10. Following is a list of specificity weights.(The rule with the highest weight would take precedence in case of conflicting rules.)

H1 {(simple selector)} specificity = 1 
P EM {(contextual selector)} specificity = 2 
.grape {(class selector)} specificity = 10 
P.bright {(element/class selector combo)} specificity = 11 
P.bright EM.dark {(contextual element/class)} specificity = 22 
#IDsec {(ID selector)} specificity = 100 

Calculating Specificity

  1. Count the number of ID attributes in the selector.
  2. Count the number of CLASS attributes in the selector.
  3. Count the number of HTML tag names in the selector.

Finally, write the three numbers in exact order with no spaces or commas to obtain a three digit number. (Note, you may need to convert the numbers to a larger base to end up with three digits.) The final list of numbers corresponding to selectors will easily determine specificity with the higher numbers winning out over lower numbers. Following is a list of selectors sorted by specificity:

#id1         {xxx} /* a=1 b=0 c=0 --> specificity = 100 */
UL UL LI.red {xxx} /* a=0 b=1 c=3 --> specificity = 013 */
LI.red       {xxx} /* a=0 b=1 c=1 --> specificity = 011 */
LI           {xxx} /* a=0 b=0 c=1 --> specificity = 001 */

Making definitions more important

CSS has an !important rule to ensure that some settings remain although the user might use an own stylesheet or some inline style gets added via a CMS.

<div id="logo"><img ... /></div>
#logo {background:#f00 !important;}
would render the red colour even if the markup is changed to
<div id="logo" style="background:#fff"><img ... /></div>

The !important directive must be the last before the semicolon!

Naming

IDs and classes of elements should represent what these elements are, not what they look like. One of the main strengths of CSS is that it allows for redesigning a complete web site by changing the stylesheet. If CSS-P is used, you can even re-position elements at will. This is only possible when the selector names are generic rather than descriptive for one layout.

wrong:
#bluerightrectangle
.yellowlink
.topleft
.bottomlinks
better:
#mainnavigation
.specialoffer
.smallproductview
#breadcrumbs

Selector names should not be ambiguous, for example 'special'. What is it? A special paragraph? Link? Image? Names should be English, to avoid causing confusion in other developers who don't speak your language. Names can not contain spaces or special letters like colons or underscores. Let's avoid using dashes aswell.