Basic webstandards Workshop

Date: 25 May 2005
Author: Russ Weakley

Part 1 – the standards

The Web Standards

The W3C (World Wide Web Consortium) and other standards bodies have established technologies for creating and interpreting web-based content. The actual standards are:

Structural Languages

Presentation Languages

Object Models

Scripting Languages

Additional Presentation Languages (Markup)

What are Web Standards about?

These ‘Web Standards’ are designed to:

  • deliver the greatest benefits to the greatest number of web users
  • ensure the long-term viability of any web document
  • simplify code and lower the cost of production
  • deliver sites that are accessible to more people and more types of Internet devices
  • continue to function correctly as browsers evolve, and as new devices come to market

For web designers and developers, Web Standards are about using standards (Structural, presentational, Object and Scripting languages) and best practices (valid, semantic and accessible code) to benefit your users, your clients and yourself.

Ideal page structure

Ideal page structure is made up of a series of layers – separating structure, presentation and behaviour. Presentation and behaviour should fail gracefully, so that devices that do not support them will not miss information or critical interaction.

External resources:

Part 2 – (X)HTML

What is valid code?

Validation is a process of checking your documents against a formal standard, like those published by the W3C. A document that has been checked and passed is considered valid.

Why use valid code?

  • Valid code will render faster than code with errors
  • Valid code will render better than invalid code
  • Browsers are becoming more standards compliant, and it is becoming increasingly necessary to write valid and standards compliant HTML

How do you check if your code is valid

How do you make your code valid?

  • Start with the right doctype
  • Be aware of doctype modes (standards compliant, quirks mode etc)
  • Use a character set
  • Close HTML elements
  • Use alt attributes for images
  • Avoid HTML hacks
  • Use HTML validators regularly
  • Fix any bugs you find before you go live
  • Make validation part of your normal work process

External resources:

Understanding elements and attributes

A lot of validation problems stem from a lack of understanding about the correct elements and the use of attributes.

HTML Elements

HTML Elements are the basic components that are used to create the structure of an HTML document. Examples of elements are headings, paragraphs, lists, etc.

<ul>
	<li><a href="#">Item one</a></li>
	<li><a href="#">Item two</a></li>
	<li><a href="#">Item three</a></li>
</ul>

HTML Attributes

An attribute is a name-value pair used with an HTML element to assign additional properties to the element being defined.

<img src="05.gif" alt="" width="100" height="100">

External resources:

Doctypes

What are they and why are they important?

  • All HTML and XHTML documents must have a doctype declaration to be valid.
  • The doctype states the version of HTML or XHMTL is being used in the document.
  • Doctypes are used by the validator when validating, and by web browsers to determine which rendering mode to use.
  • Doctypes affect the way devices render web pages.
  • If a correct and full doctype is present in a document, many web browsers will switch to standards mode, which means that they will follow the CSS specification closer.
  • Documents with correct and full doctypes will also render quicker because the browser doesn’t have to interpret and try to compensate for invalid HTML.

HTML 4.01 Strict

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
	"http://www.w3.org/TR/html4/strict.dtd">

HTML 4.01 Transitional

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
	"http://www.w3.org/TR/html4/loose.dtd">

HTML 4.01 Frameset

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
	"http://www.w3.org/TR/html4/frameset.dtd">

XHTML 1.0 Strict

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

XHTML 1.0 Transitional

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

XHTML 1.0 Frameset

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">

XHTML1.1

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
	"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

Standards compliant (or strict) and quirks modes

Most browsers run in two modes: quirks mode for the old rules and strict mode for the standard. Mozilla, Safari, Opera, Mac/Explorer, Windows/Explorer 6 implemented these two modes. Windows/Explorer 5 and older browsers like Netscape 4, are permanently locked in quirks mode.

There are some very important reasons to use strict, or standards compliant mode. For example, Windows/Explorer 6 will use the correct box model when in strict mode, but the incorrect box model when in quirks mode. Also, many modern browsers will not allow fonts to be inherited when in quirks mode.

Is the XML prolog necessary?

Using the XML prolog in XHTML documents is a practice that is recommended but not required by the W3C. So, it’s up to developers whether to use it or to leave it out. If the prolog is included, Windows/IE6 will revert to quirks mode regardless of the doctype used. The prolog looks like this:

<?xml version="1.0" encoding="utf-8"?>

External resources:

The XHTML dilemma

If you use XHTML, you should deliver it with the application/xhtml+xml MIME type. If you do not do so, you should use HTML4 instead of XHTML. The alternative, using XHTML but delivering it as text/html, causes numerous problems that are outlined below.

Unfortunately, IE6 does not support application/xhtml+xml (in fact, it does not support XHTML at all).

Sending XHTML as text/html Considered Harmful

Developers have three choices when it comes to using XHTML:

  1. Use XHTML 1.0 with content negotiation – serve the XHTML document as either text/html or application/xhtml+xml depending on the user-agent’s capabilities
  2. Use XHTML 1.0 with backward compatibility mode to allow one to use XHTML 1.0 while maintaining compatibility with the legacy browsers. If you follow these guidelines, you are allowed to serve your XHTML as text/html. The backward compatibility mode defines some syntactic tricks which allows an XHTML document to be understood by most HTML browsers.
  3. Use HTML 4.01 Strict or Transitional

External resources:

Part 3 – Semantic markup

What is semantic markup?

In English, the word semantic means “of or relating to meaning”… In markup, semantics is concerned with the meaning of an element, and how that element describes the content it contains.

Integrated Web Design: The Meaning of Semantics (Take I)

Semantically markup is about using html elements to give content meaning. This is important for a wide range of user agents (browsers without style sheets, text browsers, PDAs, search engines etc.)

You should use standard HTML elements for your markup and avoid styling HTML elements to look like other HTML elements. In simple terms, this means:

  • for headings, use heading elements starting with H1
  • for paragraphs of text, use a paragraph element
  • for lists, use a list elements

External resources:

Marking up content with no meaning

Two tools that can be used to test semantic meaning

Marking up content with incorrect meaning

Possibly even worse that providing content with no meaning is marking up content with incorrect meaning.

Blockquote

Often used for indenting content. Should be used to contain quotations that are a paragraph or more in length – a block of a quote.

Table

Often used for presentational layout. Should be used for tabular data only.

Definition lists

Sometimes used to indent content. Has a wide range of uses for items that have a direct relationship with each other (name/value sets). Should be careful not to use as a replacement when marking up tabular data.

External resources:

Forgotten HTML elements

Abbreviation (abbr)

A shortened form of a word or phrase used chiefly in writing to represent the complete form, such as Mass. for Massachusetts or USMC for United States Marine Corps (e.g., WWW, HTTP, URI, Mass., etc.).

<abbr title="World Wide Web">WWW</abbr>

Acronym (acronym)

A word formed from the initial letters of a name, such as WAC for Women’s Army Corps, or by combining initial letters or parts of a series of words, such as radar for radio detecting and ranging (e.g., WAC, radar, etc.).

<acronym title="Women's Army Corps">WAC</acronym>

Definition (dfn)

A statement of the meaning of a word, phrase, or term, as in a dictionary entry. The DFN element can be used to mark up the defining instance of a term. In an article, the DFN can be used the first time we mention something and explain what it means. DFN indicates that this is the defining instance of the enclosed term.

<dfn title="Open grassy plains with minimal trees">Rangelands</dfn>

Cite

Cite is an element and an attribute.

As an element, it can be used to cite other references, such as book titles, people, movie titles etc.

<cite>Designing with Web Standards</cite> is by Jeffrey Zeldman.

As an attribute, cite can be used with blockquote and q to provide additional information.

<blockquote cite="http://www.mycom.com/tolkien/twotowers.html">
	<p>
		They went in single file, running like hounds on a 
		strong scent, and an eager light was in their eyes.
	</p>
</blockquote>

External resources:

Heading levels – the great debate

The finer details of semantic markup come down to personal opinion. Often semantic markup details are hotly debated. Commonly debated topics include:

  • Can you have multiple h1′s in one document?
  • Can you skip a heading level?
  • Should site title or page title be considered the h1 within a document

Can you have multiple h1′s in one document?

The short answer is no – you should only have one h1 per document.

Can you skip a heading level?

This will depend on the overall site in which the document sits. If you define your heading levels across a site, there many be times when a heading level is missing on a specific page, but to change it up or down a level may then take it out of context with the rest of the site.

Should the page title be considered the h1 within a document?

There are two schools of thought on this. Some people believe that the site name is the most important information and should be wrapped in an h1 element. Others believe that the page title (which should match the document title) should be wrapped in the h1, and the site title sits above this with no real semantic meaning.

Part 4. Accessibility

Why bother with accessibility?

1. Legal reasons

2. Moral reasons

The internet is a place of equality. It gives us all power and choice at the same level – but only if our access to it is equal to everyone else’s

Royal National Institute of Blind People (article no longer online)

3. Public service reasons

The public sector has an obligation to serve the public. You aren’t doing that if the only people you’re serving are people without disabilities

Web Essentials ’04 notes

4. Commercial reasons

The 2003 SDAC estimates that one in five Australians (3,951,000 or 20%) had a disability. This rate was the same for males and females. The rate increased with age, reaching 81% for those aged 85 years and over.

4446.0 – Disability, Australia, 2003

5. Accessible web pages benefit everyone

Disabled groups

1. Visual impairment

  • Blindness
  • Low vision
  • Colour deficiency
    • Deuteranopia – Red-green deficiency
    • Protanopia – red deficiency
    • Tritanopia – blue/yellow deficit
    • Achromatopsia – Total colour blindness

2. Mobility or dexterity impairment

  • Total or partial paralysis
  • Parkinson’s disease
  • Arthritis
  • Cerebral palsy
  • Lack of limb movement

3. Cognitive impairment and learning difficulties

  • Cognitive disabilities
    • Loss of brain function
    • Short term memory loss
    • Multiple Sclerosis
    • Alzheimer’s disease
    • Parkinson’s Disease
    • Old age
  • Learning difficulties
    • Attention Deficit Disorder
    • Dyslexia
    • Other non-verbal learning difficulties

4. Hearing impairment

Devices and software

Input devices and software used to access web content

Output devices and software used for web content

Skip links

What are they?

Skip links are designed to allow certain users the ability to skip over one section of content so that they can quickly get to another section of content. This may mean skipping over site navigation links in order to get directly to the content of the site, or skipping over the content in order to get to the site navigation, or other content.

Some examples:

<a href="#content" title="skip to content">Skip to content</a>
<a href="#content" title="skip to navigation">Skip to navigation</a>

Visible skip links

Where possible, skip links should be made visible, rather than hidden within the source code. This allows users who rely on keyboard functions (no mouse) to tab to the skip link first, and decide whether they want to skip over the content or navigation.

Positioning skip links

Visible skip links can be positioned at the top within the source code, but visually positioned anywhere on the page using absolute positioning within CSS.

If skip links need to be contained within a parent container, this parent can be set to position: relative, and the skip link can then be set to position: absolute. This allows the skip linked to be positioned anywhere – in relation to its parent container.

Access keys

What are they?

The Accesskey attribute assigns an access key to an element. Elements that support the accesskey attribute include: a, area, button, input, label, and legend, and textarea.

While it seems that Accesskeys is a great idea in principle, implementation brings with it the possibility that it either will not be available to all users, or that the keystroke combination encoded within the web page may conflict with a reserved keystroke combination in an adaptive technology or future user agent.

http://www.wats.ca/articles/accesskeys/19

The only way forward is to adopt a standard across all websites

The UK Government provides accessibility guidelines to which all its websites should comply – including the use of the same access keys:

  • S – Skip navigation
  • 1 – Home page
  • 2 – What’s new
  • 3 – Site map
  • 4 – Search
  • 5 – FAQs
  • 6 – Help
  • 7 – Complaints procedure
  • 8 – Terms and conditions
  • 9 – Feedback form
  • 0 – Access key details

External resources:

Accessible code in action

Adding accessible code to a form

Take a poorly structured form and add fieldsets, legends, label for’s, ids and titles. Then style these elements as needed.

Adding accessible code to a data table

Take a poorly structured data table and add a summary, caption, thead, tbody, th, id, headers, scope and abbr. Then style these elements as needed.

Building a simple accessible form

No accessible markup

In this example, the form is marked up with paragraphs, and presentational elements like <br> and <strong>.

<form action="#" method="get">
	<p>
		<strong>Personal Details</strong><br>
		Name:
		<input type="text" name="details-name" size="15">
		Phone Home:
		<input type="text" name="details-phone" size="15">
	</p>
	<p>
		<strong>Select the fact sheets you want</strong><br>
		<input type="checkbox" name="roses" value="checkbox">
		Roses
		<input type="checkbox" name="daffodils" value="checkbox">
		Daffodils
		<input type="checkbox" name="tulips" value="checkbox">
		Tulips
	</p>
</form>

Step 1 – grouping form information using Fieldsets and legends

<form action="#" method="get">
<fieldset>
</fieldset>
<fieldset>
</fieldset>
</form>

Step 2 – labelling groups using legends

<form action="#" method="get">
<fieldset>
	<legend>Personal Details</legend>
</fieldset>
<fieldset>
	<legend>Select the fact sheets you want</legend>
</fieldset>
</form>

Step 3 – tying a text label to a specific form input using “label for” and “id”

<form action="#" method="get">
<fieldset>
	<legend>Personal Details</legend>
	<label for="details-name">Name:</label>
	<input id="details-name" type="text" name="details-name" size="15">
	<label for="details-phone">Phone Home:</label>
	<input id="details-phone" type="text" name="details-phone" size="15">
</fieldset>
<fieldset>
	<legend>Select the fact sheets you want</legend>
	<input id="roses" type="checkbox" name="roses" value="checkbox">
	<label for="roses">Roses</label>
	<input id="daffodils" type="checkbox" name="daffodils" value="checkbox">
	<label for="daffodils">Daffodils</label>
	<input id="tulips" type="checkbox" name="tulips" value="checkbox">
	<label for="tulips">Tulips</label>
</fieldset>
</form>

Step 4 – adding titles

<form action="#" method="get">
<fieldset>
	<legend>Personal Details</legend>
	<label for="details-name">Name:</label>
	<input id="details-name" type="text" title="type your name" name="details-name" size="15">
	<label for="details-phone">Phone Home:</label>
	<input id="details-phone" type="text" title="type your home phone number" name="details-phone" size="15">
</fieldset>
<fieldset>
	<legend>Select the fact sheets you want</legend>
	<input id="roses" type="checkbox" title="rose factsheet" name="roses" value="checkbox">
	<label for="roses">Roses</label> 
	<input id="daffodils" type="checkbox" title="daffodil factsheet" name="daffodils" value="checkbox">
	<label for="daffodils">Daffodils</label>
	<input id="tulips" type="checkbox" title="tulip factsheet" name="tulips" value="checkbox">
	<label for="tulips">Tulips</label>
</fieldset>
</form>

Building a simple accessible table

No accessible markup

In this example, the table is marked up with without accessible features.

<h5>
	Pricing for screws, Flat nails and Dyna-bolts
</h5>
<table>
	<tr>
		<td><strong>Item</strong></td>
		<td><strong>Threaded screws</strong></td>
		<td><strong>Flat nails</strong></td>
		<td><strong>Dyna-bolts</strong></td>
		<td><strong>Spring washers</strong></td>
	</tr>
	<tr>
		<td><strong>Kilo</strong></td>
		<td>$2.50</td>
		<td>$3.50</td>
		<td>$4.50</td>
		<td>$2.50</td>
	</tr>
	<tr>
		<td><strong>Pound</strong></td>
		<td>$2.00</td>
		<td>$3.00</td>
		<td>$4.00</td>
		<td>$2.00</td>
	</tr>
</table>

Step 1 – Removing presentation

<h5>
	Pricing for screws, Flat nails and Dyna-bolts
</h5>
<table">
	<tr>
		<td><strong>Item</strong></td>
		<td><strong>Threaded screws</strong></td>
		<td><strong>Flat nails</strong></td>
		<td><strong>Dyna-bolts</strong></td>
		<td><strong>Spring washers</strong></td>
	</tr>
	<tr>
		<td><strong>Kilo</strong></td>
		<td>$2.50</td>
		<td>$3.50</td>
		<td>$4.50</td>
		<td>$2.50</td>
	</tr>
	<tr>
		<td><strong>Pound</strong></td>
		<td>$2.00</td>
		<td>$3.00</td>
		<td>$4.00</td>
		<td>$2.00</td>
	</tr>
</table>

Step 2 – Adding a summary

<h5>
	Pricing for screws, Flat nails and Dyna-bolts
</h5>
<table summary="Table of screws, Flat nails, Dyna-bolts and 
Spring washers, in kilos and pounds">
	<tr>
		<td><strong>Item</strong></td>
		<td><strong>Threaded screws</strong></td>
		<td><strong>Flat nails</strong></td>
		<td><strong>Dyna-bolts</strong></td>
		<td><strong>Spring washers</strong></td>
	</tr>
	<tr>
		<td><strong>Kilo</strong></td>
		<td>$2.50</td>
		<td>$3.50</td>
		<td>$4.50</td>
		<td>$2.50</td>
	</tr>
	<tr>
		<td><strong>Pound</strong></td>
		<td>$2.00</td>
		<td>$3.00</td>
		<td>$4.00</td>
		<td>$2.00</td>
	</tr>
	</table>

Step 3 – Changing the heading above into a caption

<table summary="Table of screws, Flat nails, Dyna-bolts and 
Spring washers, in kilos and pounds">
	<caption>
		Pricing for screws, Flat nails and Dyna-bolts
	</caption>
	<tr>
		<td><strong>Item</strong></td>
		<td><strong>Threaded screws</strong></td>
		<td><strong>Flat nails</strong></td>
		<td><strong>Dyna-bolts</strong></td>
		<td><strong>Spring washers</strong></td>
	</tr>
	<tr>
		<td><strong>Kilo</strong></td>
		<td>$2.50</td>
		<td>$3.50</td>
		<td>$4.50</td>
		<td>$2.50</td>
	</tr>
	<tr>
		<td><strong>Pound</strong></td>
		<td>$2.00</td>
		<td>$3.00</td>
		<td>$4.00</td>
		<td>$2.00</td>
	</tr>
	</table>

Step 4 – Adding thead and tbody

<table summary="Table of screws, Flat nails, Dyna-bolts and 
Spring washers, in kilos and pounds">
	<caption>
		Pricing for screws, Flat nails and Dyna-bolts
	</caption>
	<thead>
		<tr>
			<td><strong>Item</strong></td>
			<td><strong>Threaded screws</strong></td>
			<td><strong>Flat nails</strong></td>
			<td><strong>Dyna-bolts</strong></td>
			<td><strong>Spring washers</strong></td>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td><strong>Kilo</strong></td>
			<td>$2.50</td>
			<td>$3.50</td>
			<td>$4.50</td>
			<td>$2.50</td>
		</tr>
		<tr>
			<td><strong>Pound</strong></td>
			<td>$2.00</td>
			<td>$3.00</td>
			<td>$4.00</td>
			<td>$2.00</td>
		</tr>
	</tbody>
</table>

Step 5 – Adding th

<table summary="Table of screws, Flat nails, Dyna-bolts and 
Spring washers, in kilos and pounds">
	<caption>
		Pricing for screws, Flat nails and Dyna-bolts
	</caption>
	<thead>
		<tr>
			<th>Item</th>
			<th>Threaded screws</th>
			<th>Flat nails</th>
			<th>Dyna-bolts</th>
			<th>Spring washers</th>
		</tr>
		</thead>
		<tbody>
		<tr>
			<th>Kilo</th>
			<td>$2.50</td>
			<td>$3.50</td>
			<td>$4.50</td>
			<td>$2.50</td>
		</tr>
		<tr>
			<th>Pound</th>
			<td>$2.00</td>
			<td>$3.00</td>
			<td>$4.00</td>
			<td>$2.00</td>
		</tr>
	</tbody>
</table>

Step 6 – Adding “id” and “headers”

<table summary="Table of screws, Flat nails, Dyna-bolts and 
Spring washers, in kilos and pounds">
	<caption>
		Pricing for screws, Flat nails and Dyna-bolts
	</caption>
	<thead>
		<tr>
			<th>Item</th>
			<th id="screws">Threaded screws</th>
			<th id="nails">Flat nails</th>
			<th id="bolts">Dyna-bolts</th>
			<th id="washers">Spring washers</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<th id="kilo">Kilo</th>
			<td headers="screws kilo">$2.50</td>
			<td headers="nails kilo">$3.50</td>
			<td headers="bolts kilo">$4.50</td>
			<td headers="washers kilo">$2.50</td>
		</tr>
		<tr>
			<th id="pound">Pound</th>
			<td headers="screws pound">$2.00</td>
			<td headers="nails pound">$3.00</td>
			<td headers="bolts pound">$4.00</td>
			<td headers="washers pound">$2.00</td>
		</tr>
	</tbody>
</table>

Step 7. Adding abbr

<table summary="Table of screws, Flat nails, Dyna-bolts and 
Spring washers, in kilos and pounds">
	<caption>
		Pricing for screws, Flat nails and Dyna-bolts
	</caption>
	<thead>
		<tr>
			<th>Item</th>
			<th id="screws" abbr="screws">Threaded screws</th>
			<th id="nails" abbr="nails">Flat nails</th>
			<th id="bolts" abbr="bolts">Dyna-bolts</th>
			<th id="washers" abbr="washers">Spring washers</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<th id="kilo">Kilo</th>
			<td headers="screws kilo">$2.50</td>
			<td headers="nails kilo">$3.50</td>
			<td headers="bolts kilo">$4.50</td>
			<td headers="washers kilo">$2.50</td>
		</tr>
		<tr>
			<th id="pound">Pound</th>
			<td headers="screws pound">$2.00</td>
			<td headers="nails pound">$3.00</td>
			<td headers="bolts pound">$4.00</td>
			<td headers="washers pound">$2.00</td>
		</tr>
	</tbody>
</table>

Part 5. Introduction to CSS

Why use CSS to separate content from presentation?

The aim for web developers is to remove all presentation from the html code, leaving it clean and semantically correct.

  • More accessible to a wider variety of devices
  • Easier to make site-wide changes – one css file rather than all pages
  • Smaller files/ faster download – less code on the page
  • Less code on the page – easier to code
  • Allows users to customise to their own needs – style switchers
  • More control over code – can deliver code in preferred order for screen readers

Presentation on all HTML pages

diagram showing presentation on all pages

Presentation in separater CSS file

Separater CSS files for modern browsers, printers and older browsers

Some definitions

The viewport

The viewport is the window or viewing area that displays web pages. When the viewport is smaller than the web page, scroll bars should be available.

The initial containing block

The initial containing block is the entire width and height of your web page – including parts of the page that are outside the viewpoint.

Containing blocks or containing boxes

A containing block is a box or block that contains other elements (descendant boxes). An element’s containing block means “the containing block in which the element lives”.

Block-level elements and block boxes

Block level elements (or block boxes) are elements that are formatted visually as blocks.

Inline-level elements and inline boxes

Inline elements are elements that do not form new blocks of content; the content is distributed in lines.

Normal flow

Normal flow is the way a document will display if you had no positioning or floating applied to elements. The content will flow down the page, starting with the first element in your document and finishing with the last element in your document.

Out of normal flow

When a box is taken out of normal flow, all content that is still within normal flow will ignore it completely and not make space for it.

The document tree – it’s a family thing

All HTML documents are trees. Each level of the tree is described in the same manner as a human family tree, with ancestors, descendants, parents, children and siblings. CSS rules are based on the document tree. If you understand the document tree concept, then CSS selectors will be easy to understand and apply.

Let’s start with a sample of HTML. This sample doesn’t include the head or title, as we are focussing on what is inside the body:

<body>
	<div id="content">
		<h1>Heading here</h1>
		<p>Lorem ipsum dolor sit amet.</p>
		<p>Lorem ipsum dolor <em>sit</em> amet.</p>
		<hr>
	</div>
	<div id="nav">
		<ul>
			<li>item 1</li>
			<li>item 2</li>
			<li>item 3</li>
		</ul>
	</div>
</body>

The document tree diagram for the sample above would be:

tree

Ancestor

An ancestor refers to any element that is connected but further up the document tree – no matter how many levels higher. In the diagram below, the <body> element is the ancestor of all other elements on the page.

Document tree diagram showing ancestor

Descendant

A descendant refers to any element that is connected but lower down the document tree – no matter how many levels lower. In the diagram below, all elements that are connected below the <div> element are descendants of that <div>.

Document tree diagram showing descendant

Parent

A parent is an element that is directly above and connected to an element in the document tree. In the diagram below, the <div> is a parent to the <ul>.

Document tree diagram showing parent

Child

A child is an element that is directly below and connected to an element in the document tree. In the diagram above, the <ul> is a child to the <div>.

Document tree diagram showing parent

Sibling

A sibling is an element that shares the same parent with another element. In the diagram below, the <li>’s are siblings as they all share the same parent – the <ul>.

Document tree diagram showing sibling

What is a rule or “rule set”?

Introduction

A rule or “rule set” is a statement that tells browsers how to render particular elements on an HTML page. A rule set consists of a selector followed by a declaration block.

Rule structure

rule

Selector

The selector “selects” the elements on an HTML page that are affected by the rule set. The selector consists of everything up to (but not including) the first left curly bracket. For example:

h1 { color: blue; margin-top: 1em; }
p { padding: 5px; }
td { background-color: #ddd; }

Declaration block

The declaration block is a container that consists of anything between (and including) the curly brackets. Whitespace inside a declaration block is ignored – so it can be used to lay out rules in any way you want. For example:

h1 { color: blue; }
p { padding: 5px; }
td { background-color: #ddd; }

Or, with whitespace added to aid readability:

h1
{
	color: blue;
}

Declaration

The declaration tells a browser how to draw any element on a page that is selected. A declaration consists of a property and a value, separated by a colon “:”. Although it is not essential to add a semicolon after a single declaration, it is recommended that you finish the last declaration in a block with a semicolon. For example:

h1 { color: blue; }

Property

The property is the aspect of that element that you are choosing to style. There can only be one property within each declaration. For example:

p { padding: 5px; }

Value

The value is the exact style you wish to set for the property. For example:

p { padding:5px; }

External resources

Grouping selectors

Selectors are used to “select” the elements on an HTML page that are affected by rules. When several selectors share the same declarations, they may be grouped together to save writing the same rule more than once. Each selector must be separated by a comma. They can also include a wide range of selectors. For example:

h1, h2, h3, h4 { padding: 1em; }
.highlight p, .highlight ul { margin-left: .5em; }
#main p, #main ul { padding-top: 1em; }

There are two common mistakes that people make when grouping selectors. The first is forgetting to write each selector in full. For example, if you are trying to target two elements within the same containing block, and with the same ID, chances are you will probably want them to be written in the same way. So, this is probably wrong:

#maincontent p, ul { border-top: 1px solid #ddd; }

The correct group selector would more likely be:

#maincontent p, #maincontent ul { padding-top: 1em; }

The second common mistake is to end the grouping with a comma. This can cause certain browsers to ignore the rule entirely.

.highlight p, .highlight ul, { margin-left: .5em; }

External Resources

Shorthand rules

Rules can be combined, allowing you specify several properties with one rule set. The biggest advantage is that your CSS code becomes shorter. For example the two rule sets below have exactly the same effect:

p
{
	padding-top: 1em;
	padding-right: 1em;
	padding-bottom: 1em;
	padding-left: 1em;
}
	
p { padding: 1em; }

If property values are different for all sides, shorthand can still be used. The order of each value is important. Values are applied in the following order; top, right, bottom and left – clockwise, starting at the top. For example the first rule set below can be shortened:

p
{
	padding-top: 1em;
	padding-right: 2em;
	padding-bottom: 3em;
	padding-left: 4em;
}
	
p { padding: 1em 2em 3em 4em; }

You can use one, two, three and four values within a shorthand declaration. For example, the rule below will apply padding to all sides of a box:

p { padding: 1em; }

The rule below will apply 1em of padding to the top and bottom, and 2em of padding to the left and right of the box.

p { padding: 1em 2em; }

The rule below will apply 1em of padding to the top, 2em of padding to the left and right, and 3em to the bottom of the box.

p { padding: 1em 2em 3em; }

The rule below will apply 1em of padding to the top, 2em of padding to the right, 3em of padding to the bottom and 4em of padding to the left of the box.

p { padding: 1em 2em 3em 4em; }

Browser support for shorthand rules varies. For detailed browser support charts, see the Stylemaster – CSS compatibilty Chart

Selectors

Type selectors

The most common and easy to understand selectors are type selectors. Type selectors will select any HTML element on a page that matches the selector, regardless of their position in the document tree. For example:

em {color: blue; }

This rule will select any <em> element on the page and color it blue. As you can see from the document tree diagram below, all <em> elements will be colored blue, regardless of their position in the document tree.

Document tree showing type selector

There are a huge range of elements that you can select using type selectors, which means you can change the appearance of any or every element on your page using only type selectors.

Class selectors

While type selectors target every instance of an element, class selectors can be used to select any HTML element that has a class attribute, regardless of their position in the document tree.

For example, if you want to target the first paragraph and first list items on a page to make them stand out, you could mark up the page in the following way:

<body>
	<p class="big">This is some <em>text</em></p>
	<p>This is some text</p>
	<ul>
		<li class="big">List item</li>
		<li>List item</li>
		<li>List <em>item</em></li>
	</ul>
</body>

The tree diagram would be:

document tree diagram showing classes

The rule used could then be:

.big { font-size: 110%; font-weight: bold; }

Combining class and type selectors

If you want to be more specific, you can use class and type selectors together. Any type selectors can be used.

div.big { color: blue; }
td.big { color: yellow; }
label.big { color: green; }
form.big { color: red; }

For example, you may want to target the first paragraph and first list items on a page to give them a larger font size. You may also want only the paragraph to be bold.

document tree diagram showing different uses of classes

To do this, you could use the following rules:

.big { font-size: 110%; } /* affects p and li */
p.big { font-weight: bold; }/* affects p only */

ID selectors

ID selectors are similar to class selectors. They can be used to select any HTML element that has an ID attribute, regardless of their position in the document tree. Examples of ID selectors:

#navigation { width: 12em; color: #333; }
div#navigation { width: 12em; color: #333; }

The major difference is that IDs can only be applied once per page, while classes can be used as many times on a page as needed.

Descendant selectors

Descendant selectors are used to select elements that are descendants of another element in the document tree.

For example, you may wish to target a specific <em> element on the page, but not all <em> elements. A sample document could contain the following code:

<body>
	<h1>Heading <em>here</em> </h1>
	<p>Lorem ipsum dolor <em>sit</em> amet.</p>
</body>

The document tree diagram (with the <em> element to be targeted) would be:

Document tree showing descendant selectors

If you use a type selector like the example below, you will select all <em> elements on the page:

em {color: blue; }

However, if you use a descendant selector, you can refine the <em> elements that you select. The rule below will only select <em> elements that are descendants of <p> elements. If this rule is applied, the <em> element within the <h1> will not be colored blue.

p em {color: blue; }

You can also jump levels in the document tree structure to select descendants. For example, the following code:

<body>
	<p>Lorem ipsum dolor <em>sit</em> amet.</p>
	<ul>
		<li>item 1</li>
		<li>item 2</li>
		<li><em>item 3</em></li>
	</ul>
</body>

The document tree (with a third-level <em> element highlighted) would be:

Document tree showing descendant selectors

Using the following rule you can isolate any <em> element inside a <ul> element, without having to describe the <li> element. If this rule is applied, any <em> element within a <ul> element will be colored blue. However, the <em> element within the <p> will not be colored blue:

ul em {color: blue; }

Pseudo-classes

So far, all the selectors have been based on elements within the document tree. However, there are times when you may want to style something where there is no CSS selector available, like the state of a hyperlink (eg. active or visited).

Pseudo-classes allow you to format items that are not in the document tree. They include:

  • :first-child
  • :link
  • :visited
  • :hover
  • :active
  • :focus
  • :lang(n)

Styling links

With pseudo-classes, you can style links in different ways in each of the four states.

a:link is the selector for normal links a:visited is the selector for visited links a:hover is the selector for hover state a:active is the selector for active links

Due to specificity, the selector that appears later in the stylesheet will be used if there is any conflict. For this reason, link and link pseudo class selectors should always be used in the following order.

a {} 
a:link {} 
a:visited {} 
a:focus {} 
a:hover {} 
a:active {}

When styling the four link states you should be aware that modifying standard hyperlink behavior (such as underlines) can be confusing for some users, who may not realise that the item is a link.

Inheritance

HTML pages are actually document trees, with ancestors, descendants, parents and children – just like a human family tree.

In a human family, certain traits are passed down from ancestors to descendants. In a document tree, some CSS properties are passed down from ancestor elements to descendant elements. This is called inheritance.

Inheritance is designed to save you having to specify CSS rules for each level of element in the document tree.

For example, if you specify a color for the <body>, this color will be inherited by all other elements on the page, unless they have their own specific styles.

body { color: blue; }

Document tree diagram showing universal selectors

There are certain properties that are not inherited, including margins, padding, borders and backgrounds. There is a very good reason for this. If all CSS properties were to be inherted, we would have to “turn them off” at every level below if they were not required.

Cascade

HTML documents may have three types of style sheets applied to them.

  • The browser’s style sheet
  • The user’s style sheet
  • The author’s style sheet

Browser style sheets

Browsers apply style sheets to all web documents. These are referred to as a “default” browser style sheet.

User style sheets

A user is anyone who looks at your website.

Most modern browsers allow users to apply their own style sheets within the browser.

Author style sheets

Web authors can apply one or more style sheets to an HTML document.

Different Authors

There are three methods that authors can use to add CSS styles to an HTML document

Inline styles are applied to elements in the HTML code using the style attribute.

<h2 style="color: red;">

Header styles are placed in the head of the document using the style element.

<head>
	<title>Document title</title>
	<style type="text/css">
		h2 { color: blue; }
	</style>
</head>

External style sheets are applied using the link element or @import.

<head>
	<title>Document title</title>
	<link rel="stylesheet" href="my-styles.css" type="text/css" media="screen" />
</head>

CSS rule overload!

Browsers have to deal with CSS rules coming from the browser, user and author style sheets.

Browsers also have to deal with CSS rules coming from different types of author style sheets (external, header and inline).

At some point, Browsers have to deal with CSS rules that conflict. This is where more than one CSS rule refers to the same element and property.

Conflict can occur between CSS rules in different types of style sheets. Conflict can also occur between CSS rules in within the one or more author style sheets.

So which CSS rules “win”?

There are four steps to determine which CSS rules will “win” (be applied to an HTML document).

Step 1

Gather all the declarations that apply to an element and property from browser, author and user style sheets

For example, find any declarations that matches:

  • element = h2
  • property = color

For example:

Browser style sheet
h2 { color: black; }

User style sheet
h2 { color: green; }

Author style sheets
h2 { color: blue; }
#nav h2 { color: lime; }

If there are declarations from more than one of these three sources, proceed to step 2.

Step 2

Sort the gathered declarations according to origin (browser, author, user style sheets) and importance (normal or !important).

Authors can assign “!important” to any declaration. “!important” declarations override normal declarations (Normal declarations are declarations that do not contain !important).

h2 { color: red !important; }

Declarationd are sorted from lowest to highest priority:

  • browser styles
  • normal declarations in user style sheet
  • normal declarations in author style sheet
  • !important declarations in author style sheet
  • !important declarations in user style sheet

If declarations have the same origin or importance then proceed to Step 3.

Step 3

If declarations have the same origin or importance then the declaration’s selectors need to be scored, to see which declaration will “win”.

Four scores are concatenated (linked together as a chain) to create a final score:a,b,c,d. This score is referred to as a selector’s specificity.

  • A. Is there an inline style?
  • B. Count the number of IDs in the selectors.
  • C. Count the number of classes, attributes and pseudo-classes.
  • D. Count the number of element names or pseudo-elements.
h2 { color: black; }
specificity = 0,0,0,1
	
h2.navigation { color: blue;}
specificity = 0,0,1,1

h2#main { color: red; }
specificity = 0,1,0,1

<h2 style="color: red;">
specificity = 1,0,0,0

“A” will always beat “B”, which will always beat “C”, which will always beat “D”.

If there is still no clear winner then proceed to Step 4.

Step 4

If two declarations have the same importance, origin and specificity, the latter specified declaration wins

Overview of CSS positioning

Static positioning – A statically positioned box is one that is in normal flow.

Float positioning – A floated box is positioned within the normal flow, then taken out of the flow and shifted to the left or right as far as possible. Content may flow along the side of a float.

Relative positioning – Relatively positioned elements are positioned within the normal flow and then moved. Elements that come after a relatively-positioned element behave as if the relatively-positioned element was still in its ‘normal flow’ position – leaving a gap for it.

Absolute positioning – An absolute positioned box is moved out of the normal flow entirely.

Fixed positioning – Fixed positioned elements are moved out of the normal flow entirely – relative to the viewport. This means that they don’t move if the page is scrolled. Win/IE5 and Win/IE6 do not support this positioning method at all.

Basic float rules

A floated box is laid out according to the normal flow, then taken out of the flow and shifted to the left or right as far as possible. Content can flow down the right side of a left-floated box and down the left side of a right-floated box.

Example of basic floats

Where do they float?

Floated boxes will move to the left or right until their outer edge touches the containing block edge or the outer edge of another float.

Where do they float

Move down to fit

If there isn’t enough horizontal room on the current line for the floated box, it will move downward, line by line, until a line has room for it.

Is width required on floats?

You should always set a width on floated items (except if applied directly to an image – which has implicit width). W3C’s Cascading Style Sheets, level 2, CSS2 Specifications states:

A floated box must have an explicit width…

If no width is set, the results can be unpredictable. Theoretically, a floated element with an undefined width should shrink to the widest element within it. This could be a word, a sentence or even a single character – and results can vary from browser to browser.

Elements around a float

Block level elements above a floated element will not be affected by it. However, elements below will wrap around the floated element.

While content will wrap around a floated element, border, background image and background color will extend underneath.

Clearing floats

Elements following a floated element will wrap around the floated element. If you do not want this to occur, you can apply the "clear" property to these following elements. The four options are "clear: left", "clear: right", "clear: both" or "clear: none".

Floated elements inside a container

Below are examples of floated items inside a container. The floated items are small yellow-green boxes. The containers are grey boxes with darker grey borders.

Floated elements are taken out of normal flow, so their containers cannot determine their height. The grey containers will stretch to fit content inside them – but only content that is in normal flow. The containers will ignore the height of the floated items.

Example 1

If the content inside the container is long enough, the floated item may appear to sit correctly inside the container.

Example 2

If the content inside the container is very short, the floated item may poke out the bottom of the container.

Example 3

If a container has no content inside, it has no height so it should not render the grey background color at all. If there is only a floated item inside, then only this item will render. As you can see, the container will not render around the floated item.

Solution 1 – an extra clearing <div>

You can force the container to clear floated items inside. The container below has short content, but there is also a clearing element inside to push the container below the floated item. In this case, a <div> element is used, styled with “clear: both”.

Solution 2 – float the parent container

You can float the parent container as well as the floated item inside. The parent container will then wrap around the floated item.

Solution 3 – overflow: auto

You can set the parent container to “overflow: auto”. This allows the parent container to spread to fit floated content inside.

External resources

Switching column order with floats

If you float multiple columns you can then change the layout (without changing the html code) so that columns can appear in any order. This is achieved by switching between “float: left” and “float: right”.

Part 7. CSS issues and bugs

Margin collapse

Vertical margins may collapse between certain boxes:

  • Two or more adjoining vertical margins of block boxes in the normal flow collapse. The resulting margin width is the maximum of the adjoining margin widths. In the case of negative margins, the absolute maximum of the negative adjoining margins is deducted from the maximum of the positive adjoining margins. If there are no positive margins, the absolute maximum of the negative adjoining margins is deducted from zero.
  • Vertical margins between a floated box and any other box do not collapse.
  • Margins of absolutely and relatively positioned boxes do not collapse.

Collapsing margins

As you can see in the example below, the vertical margins of block boxes in normal flow will colapse to the largest amount. In the first example, the two margins are the same. In the second example, the top box’s margin is bigger.

Trapping margins

Some browsers will trap top margins within the parent container, and others will allow the top margins to escape outside the container.

There are three ways to force browsers to behave in the same way:

  1. Turn off top margin on the relevant element
  2. Add a border to the parent container (which will trap the margins inside the container)
  3. Add top padding to the parent container (which will trap the margins inside the container)

IE and the box model

Love it or hate it, Internet Explore for Windows is the main browser on the web at present. This means that at some point you will have to deal with IE’s incorrect interpretation of the box model.

In simple terms this means that some versions of IE render the box model to a different width than other Standards browsers. So, your CSS styled list may look narrower in IE compared to other browsers.

The diagram below shows that if a content box is set to 200px wide with 20px of padding and a 20px wide border, the correct method of calculating the overall box width is: content (200px) + padding (20px+20px) + borders (20px+20px) = 280px.

However, some versions of IE calculate the width as: content, padding and borders together = 200px.

Diagram of correct and IE's interpretation of CSS box model

The solutions are to work around the problem using nested divs or use one of many box model hacks.

Double margin bug

One of Windows/Internet Explorer 5′s strange bugs is the double margin bug – it doubles the amount of margin applied to left or right margins of a floated item when this item moves against the edge of a container.

This bug only occurs when the float margin goes in the same direction as the float and is trapped directly between the float and the inside edge of the container box. Any following floats with a similar margin won’t show the doubled margin. Only the first float in any given float row will suffer from the bug. Also, the doubled margin displays symmetry, working the same way to the right as it does to the left.

The solution:

.floatbox
{
	float: left;
	width: 150px;
	height: 150px;
	margin: 5px 0 5px 100px; 
	display: inline;
}

Whitespace between list items in Internet Explorer 5

One of the most commonly asked questions about styling navigation lists is the whitespace bug in Windows/Internet Explorer 5. There are many solutions including:

1. Applying a border-bottom:

li { border-bottom: ?; }

2. Setting the LI to display: inline

li { display: inline; }

3. Setting the LI to float: left

li { float: left; }
li a  { vertical-align: bottom; }

4. Setting the LI to vertical-align: bottom

Three pixel text jog

Windows/Internet Explorer 5 has another weird bug – the Three Pixle Text Jog. Content adjacent to the floated item, no matter how close or far, will be pushed away by three pixels. This can be seen in the following diagram.

There are many solutions including:

Comments so far

  1. THANKS says:

    thanks, the ie5 list bug fixed the bug in ie7 also. ie is sooooo crappy it drives me nuts :)

  2. [...] Standards Coalition – A group advocating widespread use of Web Standards for the good of all. Web Standards Workshop – A great guide to web standards. HTML & XHTML Validator – The official W3c HTML [...]

  3. Thank you! It is a most useful list of info and reference and it helped me a great deal with my work!

  4. Russ says:

    @Kakouris: Glad it was useful