CSS tutorial

The educational technology and digital learning wiki
Jump to navigation Jump to search


Learning goals
  • Understand the structure of cascading stylesheet (CSS) rules
  • Learn how to include CSS in HTML files and/or how to associate a CSS file with HTML
  • Understand how to use moderatly complex selectors
  • Learn how to style text elements
  • Deal with different media (and browers)
  • Be able to find CSS documentation (selectors, properties, compatibility tables)
More detailed tutorials
Level and target population
  • Beginners
  • This tutorial is intended for students in educational technology or any other field that is technology intensive and presents an overview of CSS. For people who need less, there exist many easy CSS tutorials on the web. This text is intended for students who also must learn principles and who are willing to learn more CSS by looking at CSS code and online reference manuals. Ideally, a teacher also should introduce CSS through hands-on lab activities (after, during or before assigning this tutorial for reading). Also, some topics are explored in more depth in other CSS tutorials and articles
  • This a first version - It needs some work - Daniel K. Schneider 19:26, 8 September 2009 (UTC).
  • In any case, this tutorial is not a reference manual and will never be. Therefore, you also must adopt at some point some on-line reference (see out pointers at the bottom), buy a CSS book or learn how to read the specifications.
  • Some of the contents will not print well in PDF (lack of CSS 3 support of the PDF rendering extension / sept 2009

The executive summary

A CSS Style sheet is set of rules that describe how to render (X)HTML or XML elements. In essenence, HTML defines the content structure of a page and CSS defines how contents should be displayed (and sometimes at which position)

Each CSS rule has two parts:

  • The selector: defines which elements are styled with this rule
  • The declaration: defines rendering (the looks of these elements). Technically speaking, it defines values for various style properties.

Here is a simple example with two CSS rules for HTML:

 P  { font-face: Verdana, sans-serif; font-size: 12pt; }
 H1, H2, H3 { color: green; }

As we shall see later, the first rule defines that <P> should use a 12pt Verdana font (or a default sans-serif font, if Verdana is not available on the system). The second rules states that all H1, H2 and H3 titles should be green.

Usually, CSS rules are defined in a separate file which then is associated with the HTML file. This way one can reuse one stylesheet for many different HTML pages.

Cascading Style Sheets principles

Purpose of CSS and status of the CSS 2 implementation

Today, CSS has three related main purposes

  • Define rendering of HTML and (text-centric) XML elements
  • Define page layouts
  • Support for interactive and animated pages, e.g. CSS3 animations, dynamic HTML (DHTML), or dynamic SVG. More precisely, either pure CSS3 or JavaScript programs can alter CSS properties of HTML elements in order to move them, change their shape or have them appear/disappear, etc. Animation is about changing properties of objects over time, and there are different technologies to do so.

Advantage of using CSS for styling web pages

CSS is the modern way to define HTML styles (including positioning of elements in the page). Older HTML dialects include special tags for styling, i.e. the <font> tag, but their use is now strongly discouraged.

  • The Separation of content and style makes web sites easier to maintain
  • CSS allows for multiple rendering of the same contents, i.e. adaptation to media and people (screen size, font size, print, etc.)
  • In addition, CSS can be used to render contents of any text-centric XML vocabulary, e.g. one that you could invent on the fly (see the CSS for XML tutorial).

Disadvantages and problems of CSS

The lack of text-transformation in CSS1/CSS2 makes CSS rather unsuitable for data-centric XML or long HTML "articles" (e.g. you can't automatically create a table of contents).

Implementation of CSS 2 was bad in IE 6 / 7, i.e. there were several bugs and in addition some selectors and properties were not implemented. For example IE 6/7 did not implement the content property which would be needed to display attribute values and/or to add extra text to output. CSS 2 support is better in IE8, however CSS 2.1 is not yet fully implemented. Other browsers have a better track record in supporting standards, but none is totally perfect (although some claim to be).

Implementation history

CSS 1 (1996): Worked ok in Firefox 1.x / Opera and more or less OK in IE 6
CSS 2 (1998, revised 2008): Worked more or less ok in Firefox 2.x/Opera, well in Firefox 3.x, not too good in IE 6/7, well in IE8.
CSS 2.1 (2009). As of Sept. 2009, implemented in the latest versions of most browsers. However, as of summer 2010, there are some remaining issues. Please, consult a a compatibility table, e.g. Quirksmode.
CSS 3 (under construction). As of 2014 most features already are implemented in several browsers, but most often through vendor-specific tags.

Hint: Use browser compatibility tables when you plan for a larger audience

Syntax of CSS declarations

A style sheet is a set of rules (also called rule sets) that describe how to render XML or HTML elements. Each rule has two parts:

  1. The selector (before the curly braces) defines to which elements a rule applies
  2. The declaration block (inside the curly braces) defines rendering, i.e. values of CSS properties

The syntax can be summarized as follows:

  selector { property:value; property:value; .... }
  • Each declaration block includes at least a property name and a value, separated by a colon (:)
  • Each property:value pair must be separated by a semi-colon (;)
CSS selectors and declarations

Here is a CSS for HTML or XHTML example:

 h1 { color: red }
 p  { font-face: Verdana, sans-serif ; font-size: 12pt}
 h1, h2, h3 { color : blue }
 h1.Chaptertoc, h2.PeriodeTOC, h2.ExerciceTOC, h2.SectionTOC  {
         display: block;text-indent: 30pt;    
         text-align: left; font-size: 14pt;
         font-weight: Bold; font-family: Times;

As you can see h1 is defined more than once and the ground rule is that the last definition will apply, e.g. in our example, h1 will be blue.

CSS comments syntax

In computer speak, comments are lines of code that (usually) are ignored by the computer. Coders use comments to document the code in order to communicate and/or to remember what it does. In CSS, comments are inserted between /* .... */ and may extend over several lines. But don't use comments within the braces of the property declaration.

Here is CSS example that includes two comments:

 /* I love HUGE titles */
 h1 {size: 50px ; }
 para {display:block;} /* para elements are blocks */

Associating styles with HTML

There exist three main methods for associating style with HTML:

  • Use one ore more external CSS files and the HTML <link> tag.
  • Use the HTML style tag. (also called page level styling)
  • Use the HTML style attribute (also called inline styling)

You also can combine all three methods. In that case, inline styling has priority over page level styling over external styling for the same kind of rule (more about this cascading principle later).

Associating external CSS files with an HTML file

The CSS file is associated using the HTML link element. In the most simple case, we need to define three attributes:

  • rel defines the type of file. Its value normally is "stylesheet"
  • href defines the link to the URL of the CSS file
  • type defines the kind of stylesheet. For CSS you must use "text/css".

This link element must be included in the head section of an (X)HTML file.

Here is a simple example:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 <html lang="en">
 <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
 <title>Just So Stories, by Rudyard Kipling</title>
 <link rel="stylesheet" href="just-so-stories.css" type="text/css">

The file css-intro.css sits in the same directory as the HTML file.

In the following example, the CSS file sits in a "sibling" directory.

<link rel="stylesheet" href="../styles/css-intro.css" type="text/css">

In the following example, the CSS file is define with an absolute local path. I.e. it sits on the same server.

<link rel="stylesheet" href="/lib/css/css-intro.css" type="text/css">

Definition of Mediatypes

The media attribute allows to define a stylesheet for a different medium, e.g. a printer

<link rel="stylesheet" href="css-intro-print.css" type="text/css" media="print">
<link rel="stylesheet" href="css-intro-print.css" type="text/css" media="handheld, tv">

See the section below on alternate stylesheets for more information about media types.

Use of multiple stylesheets

You may include several stylesheets. Typically, in portalware, several stylesheets are loaded. Each one defines rules for a given set of elements, i.e. default styles for the portal, followed by styles for various modules. Often, programmers also load default styles first and then load administrator-defined styles on top.

Example from Zikula:

<link rel="stylesheet" href="themes/TecfaBreeze/style/style.css" 
      type="text/css" media="screen,projection" />
<link rel="stylesheet" href="modules/News/pnstyle/style.css"
       type="text/css" />
<link rel="stylesheet" href="javascript/style.css"
       type="text/css" />

Example from Moodle (styles are dynamically generated with PHP files):

<link rel="stylesheet" type="text/css" href="theme/standard/styles.php" />
<link rel="stylesheet" type="text/css" href="theme/standardblue/styles.php" />

Importing style sheet files within a CSS file

To import a CSS file within another CSS file or the script element (page level styling) you may use a so-called at-rule.

 @import url (base.css);

Important: These at-rules must be defined on top of a CSS file or HTML style element, i.e. before you define any CSS rule. Also, some at-rules are buggy in IE 6/7.

These at rules can be used for other purposes, e.g. to specify that one or more rule sets in a style sheet will apply only to certain media types (see below)

Style definitions with the HTML style tag

CSS rules may be inserted within the HTML STYLE tag (it must be in lower case in XHTML). Generally speaking, you should avoid this method because if you define your CSS with an external file you can use it with many other HTML pages.

HTML code that is generated on the fly often includes style definitions at page level. But this programming practise also should be avoided, since it is better policy to include all stylesheets in a special directory structure from where the programs then can load them in. Personally, we only use page level styling for teaching purposes (since the CSS code sits next to HTML code) and in situations where were we only want to carry a single file, e.g. in collaborative HTML writing via email...

Example of a page level (or embedded) style definition in the head of an HTML5 file:

<!DOCTYPE html>
    <title>Simple CSS demo</title>

   <style type="text/css">
      body 	{background: white; font-family: Arial, sans-serif;}
      H2        {color: blue;} /* will be overriden by an other rule below */
      H2, H3	{font-family: Arial, sans-serif;}
      H2 	{color: red; text-decoration: underline;}
      P.intro 	{color: blue; margin-left: 4em; margin-right: 2em;}
      .default  {margin-left: 2em;}	

In true XHTML (served as "application/xhtml+xml"), the contents of style must be inserted within a CDATA declaration. Otherwise, you will get an error when you validate your code.

<style type="text/css"><![CDATA[
  body { .... }
  h1 ....

XHTML is XML. Inside an XML tag, you can't have another markup language like CSS. Put simply, <![CDATA[ ... ]]> tells the XML parser not to look "inside". If you just use XHTML syntax but serve the file as HTML so that IE can understand it, the CDATA section is not needed.

Inline HTML style definitions

Inline HTML style definitions like page level style definitions should generally be avoided for the same reasons, i.e. maintenance costs and division of labor. Therefore - again - only use it for testing and demonstration purposes.

Most (or all?) HTML tags allow the use of a style attribute like in the following example. As you can see, there is neither a selector nor curly braces. For obvious reasons, you only will define property-value pairs separated by a semi-colon (;) if CSS is used inside an HTML element.


 <p style="color:green;font-weight:bold;">Green fat grass</p>

Alternate stylesheets

You can define alternate stylesheets to meet various user preferences. Often, designers define different stylesheets for different media types. But nothing prevents you to design several different styles for the same medium...

The CSS 2.1 specification distinguishes the following media types

  1. all - suitable for all devices.
  2. braille - for braille tactile feedback devices.
  3. embossed - for paged braille printers.
  4. handheld - for handheld devices (typically small screen, limited bandwidth).
  5. print - for paged material and for documents viewed on screen in print preview mode.
  6. projection - for projected presentations, for example projectors.
  7. screen - primarily for color computer screens.
  8. speech - for speech synthesizers. Note: CSS2 had a similar media type called 'aural' # for this purpose.
  9. tty - for media using a fixed-pitch character grid (such as teletypes, terminals, or portable devices with limited display capabilities).
  10. tv - Intended for television-type devices (low resolution, color, limited-scrollability screens, sound available).

There exist three methods for defining alternative stylesheets:

(1) You may define alternative stylesheets, e.g. one that uses a bigger font for people with bad eyesight. Most browsers allow users to select from alternative stylesheets. E.g. in Firefox through the View->Page Style menu.

Now, these stylesheets have to be linked in a special way unless they are media specific. In the example below we define two stylesheets for the screen medium. The 2nd and 3rd are alternate stylesheets that the user can choose.

 <link rel="stylesheet" type="text/css" media="screen"
        title="Default style" href="default.css" />
 <link rel="alternate stylesheet" type="text/css" media="screen"
        title="Friendly fonts" href="friendly.css" />
 <link rel="alternate stylesheet" type="text/css" media="screen"
        title="bigtype" href="big.css" />

In addition, you should provide JavaScript code that will allow the user to switch style (a typical user may not know how to do this manually). A older very popular and free example is available from AlistAPart. A simpler, more elegant more sophisticated 2004 version also exists.

(2) The @import at-rule allows to specify a media type, i.e. you may use this strategy to load various CSS variants from a single CSS file.

 @import url(print-style.css) print;

Also, you often will find the @import CSS at-rule as replacement of the HTML link tag. E.g. the two following expressions are identical:

(1) Import a style-sheet with @import

<style type="text/css">
 @import url(css-intro.css)

(2) Import the normal way

 <link rel="stylesheet" href="css-intro.css" type="text/css">

(3) Media-specific alternatives also can be defined within a single style sheet using the @media at-rule.

@media print {
  body {
    padding: 3cm;

@media screen, projection {
  body {
    padding: 1cm;

Read more in CSS media and alternative style sheets tutorial

CSS woes

Despite the global acceptance of CSS, it took many many years before CSS 2 (defined in 1998) worked reasonably well. E.g. it took Microsoft over 10 years to produce a CSS 2 compliant browser (IE 8). In the past, in particular in the late nineties, page styling was a nightmare. In the early 2000s, simple use of CSS just worked fine, but sophisticated designs didn't and web designers had to use various ugly tricks. Web designers who code sophisticated pixel-precise code for all browsers on the market still have to do this, but "normal" people now can quite safely ignore browser specific code. As of summer 2009, you just may avoid using CSS 2.1 and CSS 3 and stick to CSS 2.0.

An additional problem is that most browsers have different CSS modes. I.e. IE8 can behave like IE7 or Firefox 3 like Netscape. To make sure that browsers will use modern CSS, the strategy is fairly simple: Use correct detailed HTML declarations on top of your HTML files. Read on ...

Dealing with bad implementations

“Quirks mode and strict mode are the two "modes" modern browsers can use to interpret your CSS. [...] when standards compliancy became important browser vendors faced a tough choice. Moving closer to the W3C specifications was the way to go, but if they’d just change the CSS implementations to match the standards perfectly, many websites would break to a greater or lesser extent. Existing CSS would start to show odd side effects if it were suddenly interpreted in the correct way. [...] In other words, all browsers needed two modes: quirks mode for the old rules, strict mode for the standard. IE Mac was the first browser to implement the two modes, and IE Windows 6, Mozilla, Safari, and Opera followed suit.” (Quirksmode.org, retrieved 19:26, 8 September 2009 (UTC)).

There are two strategies for dealing with compatibility issues:

  • You just don't care and develop according to recent standards (e.g. academics can do this)
  • You spend a few days documenting yourself making sure that you will not adopt strategies that will break in future browsers. Below we just provide a few hints. For more information read CSS compatibility

The ground rule for modern browsers is the following:

  • Most doctype declarations will trigger "strict" mode in most browser. This is a sort of commonly accepted heuristic adopted by browser makers and definitely not standardized. DocTypes are not about style ...
  • In addition, always close all tags (even if you work with HTML 4x transitional !)

Henri Sivonen provides a detailed explanation, plus an overview table that show what various browsers do with various doctype declarations. We shall just mention here that most of the following kinds of declarations will trigger "strict" or almost strict CSS in most browsers:

  • All XHTML DTDs
  • The HTML 5 declaration (<!DOCTYPE html>)
  • HTML 4 declarations that include a URL
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

Checking the mode in your browser

  • Firefox: use the command View/Page Info
  • IE: type javascript:alert(document.compatMode)

So what DTD declaration should you use ?

HTML5 (recommended as of 2015)
<!DOCTYPE html>
Standard 4.01 HTML strict
Transitional 4.01 HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
XHTML 1.1 strict
Alternatively, no DocType: XML doesn't need a DocType and the HTML version is defined in the namespace declaration
XHTML transitional
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
Alternatively, no DocType: XML doesn't need a DocType and the HTML version is defined in the namespace declaration

Legacy Internet Explorer hacks

Since IE 6 and 7 were known for really faulty CSS implementations, you may use the following HTML comments to force IE to load a IE-specifc stylesheet. Sine IE 8 works just fine, we suggest that you simply ignore IE 6/7 problems (unless you will have to design a website for a very large audience). IE8 has four modes: IE 5.5 quirks mode, IE 7 standards mode, IE 8 almost standards mode and IE 8 standards mode. Understanding under which conditions IE falls into what mode is really complicated. According to Henri Sivonen “The choice of mode depends on data from various sources: doctype, a meta element, an HTTP header, periodically downloaded data from Microsoft, the Intranet zone, settings made by the user, settings made by an intranet administrator, the mode of the frame parent if any and a UI button togglable by the user. (With other apps that embed the engine, the mode also depends on the embedding application.)”. The lucky thing is that IE8 uses doctype sniffing roughly like other browsers if you did not do anything of the above, i.e. if you own a "normal web site" and create "normal standards-compliant" pages you should do fine.

Another strategy that you see a lot when you look a computer generated pages (i.e. in portalware) is to use HTML conditional comments that only work in Explorer on Windows. You can read more at Quirksmode. Example that shows how to load specific stylesheets for specific IE versions.

<!--[if IE 7]>
    <link rel="stylesheet" type="text/css" href="theme/standard/styles_ie7.css" />
<!--[if IE 6]>
    <link rel="stylesheet" type="text/css" href="theme/standard/styles_ie6.css" />

Have a look at the styles used by this wiki page. In Firefox 2 and 3 use menu View-> Page Source or type ctrl-U. In IE 8, right click or use the Page menu and then "View Source". You will see IE specific comments. Anyhow, I suggest not to adopt this kind of informal markup, unless you really do have trouble creating good looking contents for older IE browsers.

Read CSS compatibility if you must learn how to use CSS hacks, i.e. deal with all sorts of issues related to bad CSS implementations.

The HTML div and span elements

Lets recall from the HTML and XHTML elements and attributes tutorial that we may roughly distinguish between block and inline elements. Basically, block elements start on a new line (e.g. titles, paragraphs or lists) and inline elements are inserted on the same line (e.g. some bold text or a picture).

CSS designers often use two specific HTML elements to define "custom" blocks and inline regions:

  • <div>...</div> allows to define a block (that most often includes a region of normal HTML block elements)
  • <span>...</span> allows to define a region within a block element, e.g. a few words in a paragraph.

Since these two elements play a critical role in modern web page design, we shall introduce these two elements again with some short example code. In addition, we suggest to install the View Source Chart Firefox extension. It allows to display the block structure of a web site and to understand how the layout is done.

The div tag

You may look at the source of a Mediawiki page (e.g. a Wikipedia or EduTechWiki page) to understand how portals might the structure contents of a page (if you are reading this online, view the source of this page). Simplified, the "div structure" of a page looks like this:

   <div id="globalWrapper">
      <div id="column-content">
	<div id="content">
	  <div id="bodyContent">
	    ... lots of other nested divs inside, e.g.
	    <div class="printfooter">
	<div id="column-one">
	  ... lots of other nested divs inside, e.g.
	    <div class='generated-sidebar portlet' id='p-navigation_and_help'>
	      <h5>navigation and help</h5>
	      <div class='pBody'>
		  <li id="n-Mainpage"><a href="/en/Main_Page">Main Page</a></li>
		  <li id="n-about"><a href="/en/EduTech_Wiki:About">About</a></li>
		  <li id="n-Help"><a href="/en/Help:Contents">Help</a></li>

Those many "divs" allow to position and style each "box". E.g. all the boxes of the class "generated-sidebar portlets" are positioned to the left and the "pBody" class is used to render the contents of these little menu boxes, e.g. draw a border with a margin.

Now, to make it a bit simpler. If you plan to style a whole section of your HTML in a given way, e.g. make it blue, then just wrap a div tag around the elements that make up this section. But make sure to respect the HTML "boxes within boxes" principle.


<div class="intro">
    <p>I am happy to introduce CSS now.</p>
    <p>CSS was introduced .... </p>
<h2>Next section</h2>

Bad (closing div sits inside an p tag)

<div class="intro">
    <p>I am happy to introduce CSS now.</p>
    <p>CSS was introduced ....</div> </p>
<h2>Next section</h2>

We shall see below how we then could render the whole "intro" region in blue for example.

Important notice to absolute beginners: Don't think that you must use divs each time you do some complex CSS like positioning. The div tag is like any other tag, except that it is legal to put it around any other set of tags. E.g. you could have h1 titles inside a div, but you can't do that with the very similar <p> tag.

The span tag

The span tag has the same function as the div tag inside a block element.

Here is a little example that shows how to use span with inline styling.

<p> <span style="font-weight:bold;">This article <i>or</i> section is a stub</span>.
A stub is an entry that did not yet receive substantial attention .....</p>

Introduction to CSS 2 selectors

Let's recall that a selector identifies the element(s) that we want to style by defining property values. In other words, in order to style a given set of elements we must be able to identify these elements.

CSS 2 selectors work for HTML, XHTML and any text-centric XML (XML needs a navigator that supports at least partially CSS 2.0 and XML). Each of the following sections will introduce a class of CSS selectors and we shall start with the most simple one.

Note: While explaining selectors we also will use property:value definitions in order to make the examples a bit more interesting. Don't worry, if you don't understand all of these. Or if you do, just look up the property definion in an online reference manual.

Simple selectors for HTML elements

Selection of an element


The following example, says that all dd (definition list elements) should be numbered.

 dd {
    display: list-item;
    list-style-type: decimal;

You may start learning CSS just by styling various HTML element names, e.g. you may decide to change the font of all title elements. Instead of styling just one kind of element you also may include a list of elements as the following example shows:

The following example states that all h1 to h4 title elements should use Arial.

 h1,h2,h3,h4 {font-family: Arial;}

The universal default selector

The universal selector matches any element type. As we will see later you then can add pseudo-selector components to it.

universal selector


The following example tells that by default all elements will use a 12pt Arial font.

* {
   font-family: Arial /* By default all fonts will be Arial */
   font-size: 12px /* Make them big enough */

Warning: The universal selector doesn't work in IE 6. There may be problems in IE7. A work-around strategy is to style the html or the body element, but you also may encounter problems with that in some older browsers.

 body	{
	margin:	0;
	padding: 0;
	color:	black;
	background-color: #003399;
	font: 11px/1.5 Verdana, sans-serif;

Children, cousins and other family

You also may define styles according to the position within which they may be found within a a text. E.g. you may style differently a p element inside a li element than a "normal" p element as you can see in the example just below.

Selection of a child element

mother_element > child_element

In the following example, a normal paragraph will have a line height of 1.5, but if the p is found withing an li, then line height will be 1.3.

 p { line-height: 1.5 }
 li > p { line-height: 1.3 }

Selection of descendant element (child, great-child, etc.)

mother_element element


 li p { .... }

All p elements that sit somewhere at any level of nesting inside a li tag will be affected




Selection of siblings (elements next to each other sharing the same parent)

sister_element + sister_element

In this example H2 follows H1:

 H1 + H2 { margin-top: -5mm }

Selection of elements through their attributes

Sometimes, one would like to discriminate elements according to their attribute use and/or attribute values.

selection of an element that has a certain attribute


The following example sets all <h1 font="..."> elements to color blue.

 h1[font] { color: blue; }

Selection of an element that has an attribute with a given value


The following example sets all <div class="draft"> elements to color red.

 div [class="draft"] { color: red; }

selection of an element that has an attribute with a value in a space separated list


 div[status~="draft"] { color: blue; }

This selector would for instance work with the following HTML code:

 <div status ="draft ugly important">

but not with the following one:

 <div status ="ugly-draft">

There exist even more sophisticated attribute selector tricks, but we since have shown you enough with respect to a beginners tutorial we shall just list a few examples. A more complete list can be found for example at W3S Schools

[class^=ex] { background-color:red; }/* Every element whose class starts with "ex" */
[class$=ple]  { text-decoration: underline; }/* Elements whose classe ends with "ple" */
[class*=amp]  { margin-left: 4em; }/* Elements whose class contains "amp" */

Class selectors

Frequently, designers define a class attribute value for various HTML elements in a text. Let's show this with an example. In the HTML fragment below, we use two p elements. The first is a normal paragraph. The second includes a class="draft" attribute and value.

<p>I now got over a decade of CSS experience and understand fairly well how CSS works and how it can be used</p>
<p class="draft">But on the other hand I really don't care much about style</p>

The class selector


On the CSS side we now can render the second paragraph in a different way. E.g. we could define a rule like this to make it red:

 p.draft { color: red; };

A class selector is just an abbreviation for the attribute selector introduced above. E.g. we could have written the same rule as:

 p [class="draft"] { color: red; };

Now let's assume that we got other HTML elements with a class="draft" and we want them all to be red. In that case we just could use the following syntax:

 .draft { color: red; };

Alternatively, this could have been written with the Universal selector spelled out:

 *.draft { color: red; };

To summarize, a "." means that you are referring to given class, i.e. a set of elements that includes an attribute class="something_you_define".


Classes with spaces

You may assign more than one class to an element using spaces between class names.

 <p class = "problem">This text is no so good</p>
 <p class = "killed">This is removed text</p>
 <p class = "problem killed">This text is so bad that we should remove it</p>
 <p class = "problem killed embarrassing">This text should be killed and its hardly visible</p>
 p.problem { color: red; };
 p.killed { text-decoration: underline; }
 p.embarrassing { color: yellow; }

The ID selector

In SGML and XML and therefore in HTML and respectively XHTML, 'ID' attributes allow to uniquely define an element in a given page. An ID attribute is declared as ID in its document type definition (DTD) or similar. E.g.

  • in HTML, the ID attribute is id or ID
  • in XHTML, the ID attribute is id
  • in your own XML, the ID attribute can be anything.

The ID selector is usually used for complex CSS layouts, in particular the positioning of boxes that include menus and other items that are not in the main flow of the text. Each of these boxes must be uniquely positioned and there have a unique identifier.

The ID selector



 #mainmenu { ..... }

E.g. for HTML code like this:

 <div id="menubox">

We could use CSS like that:

 #menubox {
	margin:	0px 2px 2px 2px;
	color: #000;
	background-color: #ffc;
	border:	dotted black 2px;

See the CSS positioning tutorial for more details.

Cascading and inheritance

If several rules affect an element, there must be a rule ordering principle. In simple CSS, roughly speaking, the last rule found will win. : E.g. if you define text color in more than one place, the color: property found in the last rule encountered will be used. However, this principle is only true for rules that have the same complexity.

Additionally, you must understand that properties are inherited from parent elements. More precisely, child elements (that is elements that occur within other elements) usually inherit properties from the parent elements as the following example shows.

In the following HTML fragment h1 and p are child elements of a div.

   <h1>Here is a title</h1> 
   <p>Here is a paragraph </p> 

Now, in the following CSS, the p element will be affected by the property rule for the div tag. It will use Arial font because its div parent uses Arial.

 div {font-family:Arial}
 h1  {font-family:Helvetica}
 '''/* para will inherit font-family from div, i.e. Arial */'''

Cascading is a complex issue and professional web designers understand that Cascading refers to the fact the rendering properties of a single element and its attributes may "trickle down from many sources. Let's recall the basic principle:

  • More than one rule may define properties of an element.
  • Most CSS properties (but not all) of a parent element will be inherited by its children.

According to SitePoint's Cascade article (which at some point you might read in detail), the CSS cascade involves these four steps:

  1. For a given property, find all declarations that apply to a specific element, i.e. load all CSS files that are declared for a given media type
  2. Sort the declarations according to their levels of importance, and origins. Other than the HTML page, the user plus the navigator (user-agent) also can add stylesheets. E.g. if you install the Greasemonkey extension to Firefox, you may install JS client-scripts that can override the original CSS. Declarations are sorted in the following order (from lowest to highest priority):
    1. user agent declarations
    2. normal declarations in user style sheets
    3. normal declarations in author style sheets
    4. important declarations in author style sheets
    5. important declarations in user style sheets
  3. Sort declarations with the same level of importance and origin by selector specificity. Typically, inline element specifications have the highest specificity. I.e. if the default style of a paragraph is normal, then it is logical that a span defining a bold part has higher priority.
  4. Finally, if declarations have the same level of importance, origin, and specificity, sort them by the order in which they are specified; the last declaration wins.

Cascading can be very tricky, however this is not the case for the kinds of simple style sheet a beginner or myself would write ...

The important keyword

  • By adding important! to a property, you can override default cascading rules
  • The !important keyword (or statement) is placed at the end of the declaration before the semicolon.


 text-indent: 0em !important;

Pseudo classes and pseudo elements

Pseudo-classes relate to user interaction with the document. For example, they allow to specify what happens when the user clicks on a link or moves the mouse over an element. Web designers use these pseudo classes in two ways:

  • to change the way links and visited links are rendered (not really recommended)
  • to implement dynamic HTML pages with CSS, DOM and JavaScript

We will discuss pseudo classes in another tutorial. In the meantime, we just quote from the excellent Sitepoint online reference: “CSS1 introduced the :link, :visited, and :active pseudo-classes, but only for the HTML a element. These pseudo-classes represented the state of links—unvisited, visited, or currently being selected—in a web page document.”

Pseudo-elements identify virtual elements that are not really appearent in the HTML code such as the first line of a block or the first letter of a block.

Two popular pseudo elements are :first-letter and :first-line

  • :first-line is the first line of an element
  • :first-letter is the first character an element
before and :after are CSS 2 elements and are explained in the CSS for XML tutorial

Here is an example that makes the first line of a p tag green and the first letter 5 times as big as the others:

 P:first-letter { font-size: 500%; color: green }
 P:first-line { color: green }

Other very popular pseudo tags allow to style links, for example:

  • a:hover styles the link when the user moves the mouse or another pointing device over the link
  • a:visited styles links that have been visited by the user

Summary of CSS2 selectors

* Matches any element.
E Matches any E element (i.e., an element of type E).
E F Matches any F element that is a descendant of an E element.
E > F Matches any F element that is a child of an element E.
E:first-child Matches element E when E is the first child of its parent.


Matches element E if E is the source anchor of a hyperlink of which the target is not yet visited (:link) or already visited (:visited).



Matches E during certain user actions.
E + F Matches any F element immediately preceded by an element E.
E[foo] Matches any E element with the "foo" attribute set (whatever the value).
E[foo="warning"] Matches any E element whose "foo" attribute value is exactly equal to "warning".
E[foo~="warning"] Matches any E element whose "foo" attribute value is a list of space-separated values, one of which is exactly equal to "warning".
E[lang|="en"] Matches any E element whose "lang" attribute has a hyphen-separated list of values beginning (from the left) with "en".
DIV.warning HTML only. Matches all DIV elements of class="xxx warning yyyy" or class="warning". The same as DIV[class~="warning"].
.warning HTML only. Matches all elements with class="xxx warning yyyy" or class="warning".
E#myid Matches any E element ID equal to "myid".
#myid Matches any element that has an ID equal to "myid".

CSS properties

Let's recall the syntax of CSS property definitions:

: property:value; 
: property:value,alternative_value1,alternative_value2,...;

What can be styled ?

So what can be styled ? One way of superficially answering this questions is to look at the specification. CSS 2.1 includes the following chapters:

  1. 8 Box model (properties for defining borders and margins)
  2. 9 Visual formatting model (properties for positioning and display)
  3. 10 Visual formatting model details (as above)
  4. 11 Visual effects
  5. 12 Generated content, automatic numbering, and lists
  6. 13 Paged media
  7. 14 Colors and Backgrounds
  8. 15 Fonts
  9. 16 Text
  10. 17 Tables

Websites that produce manuals for end-users may organize things a bit differently. E.g. the exellent 1-page CSS 2 Cheat sheet from David Child includes the following sections:

  1. Positioning
  2. Dimensions
  3. Color/Background
  4. Text
  5. Fonts
  6. Boxes
  7. Tables
  8. Paging
  9. Interface
  10. Aural
  11. Miscellaneous

The excellent SitePoint CSS Reference (retrieved 09:49, 10 September 2009 (UTC)) includes:

  • Box Properties
  • Layout Properties
  • List Properties
  • Table Properties
  • Color and Backgrounds
  • Typographical Properties
  • Generated Content
  • User Interface Properties
  • Paged Media Properties

In this tutorial we will just provide a very short overview of some important basic CSS properties, but no details. Have a look at the Manual links we provide in our CSS links entry.

Furthermore, we will introduce layout properties that are used to position elements in the CSS positioning tutorial and dicussion creation of interactive web pages in tutorials like DHTML

To conclude this short overview of CSS properties, we may mention that there are three increasingly complex ways of using CSS:

  • Style text, e.g. fonts size and type, colors, margins and indentations (not very difficult)
  • Position elements on a page, e.g. menu elements
  • Create dynamic pages (animation of CSS properties with JavaScript and AJAX real-time webserver connectivy with the JavaScript XMLHttpRequest object)

Units / values

Before we start introducing some of these properties, let's talk about units, i.e. values that you can define for sizes, distances, colors and so forth. CSS units are fairly intuitive and good online CSS references usually specify what units you may use for what properties.


Most properties are defined in terms of a length or size. As a designer you can pick from several kinds of units.

Firstly, there exist a series of so-called relative units

  • em refers to the current font width, typically the size of an "m"
  • ex refers to the current font size height, typically the height on an "x"
  • px refers to pixels (on a screen the smallest unit that can rendered, on a printer very complicated ...)
  • Other relative units for fonts (only) include: xx-large (h1), x-large (h2), large, medium, small, x-small and xx-small.

Second, there exist absolute units, i.e. something that you may measure with a meter. These include "normal" and "typographic" units.

  • mm
  • cm
  • in (for Americans)
  • pt: Points are an old typographic measure. I suggest to use these only when you deal with Fonts, since you can "see" what a font of X pts leads to. In CSS, a pt is 4.23mm (or 1/6th of an inch)
  • pc: A pica is another typographic measure, i.e. 1 Pica = 12 Points.

Using absolute units do not guarantee the same effect on all screens since computer screens have different density of points/inches.

Thirdly, you may use just a number in certain cases.

  • number - E.g. for line-height, you may use 1.3 (means that there is 30% of empty space with respect to the 100% of the current line height.

Below a few examples:

h1 { margin: 0.5em }      /* margin is half an "m" */
h1 { margin: 1ex }        /* ex */
p  { font-size: 12pt }    /* p's use a 12pt font size */
h1 { font-size: 1.2em }   /* h1 uses a 1.2 * "m" size with respect to the inherited default font size */
p { line-height: 1.2 }  /* 120% of 'font-size' */

Percentages are very useful to defined distances and sizes with respect to an other item/element/box.

  • n%, e.g. 50%, 150%, 0.5%

The means of what a percentage refers to, depends on the property.

 body {
 h2+p:first-letter {
      font-size: 200%;

There are two way of defining colors. Either by its name (but the official list only includes 17 colors) or by a so-called RGB value. The latter can be specified in four different ways as we shall show in the example below. The 17 pre-defined color names in CSS 2.1 are the following, according to the CSS 2.1 specification from which we made a screen shot:

The 17 official CSS 2 color definitions

Otherwise, you may choose from several RGB numerical colors specifications as the following example shows. The following example will set the color of a text:

em { color: #f00 }              /* #rgb = Red-Green-Blue shortcut for rrggbb*/
em { color: #ff0000 }           /* #rrggbb */
em { color: rgb(255,0,0) }      
em { color: rgb(100%, 0%, 0%) }

In order to set the background-color use something like:

em { background-color: #f00 }              /* #rgb = Red-Green-Blue shortcut for rrggbb*/
em { background-color: #ff0000 }           /* #rrggbb */
em { background-color: rgb(255,0,0) }      
em { background-color: rgb(100%, 0%, 0%) }

E.g. The following CSS code

  <p style="background-color: #0000ff; color: #ffffff;"> Blue background and white foreground</p>

would show like this:

Blue background and white foreground

CSS 3 implements far more sophisticated color models. Read the CSS color tutorial and maybe computer colors tutorial article for a more detailed introduction.


CSS uses URLs in several places, e.g. to load background pictures, icons, or other CSS stylesheets. You may include the url within quotes or not.

 body { background: url("http://www.example.com/pinkish.png") }
 li { list-style: url(http://www.example.com/redball.png) disc }
Font names

Font names are both an easy and a difficult matter.

Firstly, you must understand that not all fonts are available on all systems. As we shall explain below, you always should make sure that there is a "universal" fall-back font if your preferred font isn't available. In other words, always specify a list of fonts, and not just a single one. Since font names can have spaces as in Times Roman, font names need to be separated by commas and surrounded with quotes.

  • font name, font name, ....

Here is a sans serif example:

* { font-family: Calibri, Verdana, Arial, sans-serif; }
Other keywords

A certain number of properties take keywords. Keywords 'are not enclosed withing "quotes". We already introduced color keywords as in color:red.

An other example are the specification of borders. E.g the border-style property can be one of none hidden dotted dashed solid double groove ridge inset or outset.

Short hand properties

Some properties are so-called shorthands, i.e. you may specify several properties with a single one. These properties are separated by spaces. There are two kinds: some shorthands allow you to specify properties of the same kind, others to specify properties of different kinds.

For example the "same kind" margin property allows to set all four sides of a box (vs. using margin-top, margin-right etc.)

 margin:0.5cm 1cm, 0.5cm 1cm

CSS shortcut multi-typed properties include: border, border-top, border-right, border-bottom, border-left, outline, background, font, and list-style. An example of these "several kinds of value" properties would be the border property. It's syntax is:

border: { [ border-width ]   [ border-style ]   [ border-color ] | inherit } ;

Here is an example:

#h1 {
  border: 2px dotted black;


The exist many kinds of values and there is an underlying logic to the scheme which allows you to guess what kind of values you should use for simple properties. However, people who rarely code CSS have to consult the documentation. Fortunately several web sites (e.g. the ones we list in the Resources on the web section do that very well...

In addition, read both the CSS text styling tutorial and the CSS color and background tutorial

The display and visibility attributes

Let's recall the most important typographic element types:

(1) Blocks, i.e. elements that should start a new paragraph

 HTML examples: <p>, <h2>, <div>

(2) Lists and list elements

 HTML example: <ul>, <ol>, <li>

(3) Inline elements

 HTML examples: <b>, <strong>, <span>

(4) Tables

 HTML examples: <table>, <tr>, <td>

By default, HTML will display each element as either a kind of block, list element, inline or table element. Each of these use the so-called boxing model we shall introduce below. Yut you are free to change the way these boxes behave. "Raw" XML on the other hand doesn't include any styling information. Therefore, the first operation when dealing with your own XML is to define the display property for each element. Otherwise, in HTML web design, you'd mostly use the display attribute to deal with all sorts of list items, e.g. menus.

In CSS 2, there about 15-20 different display types, some of which don't work yet in some browsers. Examples that should work with all browsers:

display: block;
display: inline;
display: list-item;
display: none;

As we said, it is perfectly feasible to change the way HTML renders an element, e.g. you could display <li> elements of a list in a row, separated by dashes (CSS 2.1 needed for the dashes).

The display feature, can be used to censor the rendering of en element.

 @media print {
    #menu { display: none; }

An other useful property is visibility. E.g. to hide a menu in an alternate simple style you could say:

    #menu { visibility: hidden; }

The visibility property can be either: visible, hidden, collapse. It may be used to build scroll down menus and other interactive user widgets.

Typographical properties

We only shall shortly introduce these properties, since detailed explanations can be found on numerous web sites.

Overview of font properties

Typical values
Name of font
font-family: Helvetica;
Generic name of font
font-family: serif;
pt, cm
font-size: 14pt;
font-style: italic;
number between 100 and 999
font-weight: 500;
value = 400
font-weight: normal;
value = 700
font-weight: bold;

Text alignment properties


Paragraph alignment

text-align: left;
text-align: center;
text-align: right;
text-align: justify;
pt, cm
First line indent
text-indent: 1cm;
pt, cm
line height
line-height: 14pt;
relative value
font-height * value
line-height: 1.2;


Using fonts is both fairly simple and tricky. Simple, because the font-family property is easy to use. Tricky, because most fonts are not available on all machines and because you could fine-tune display with kerning and other font adjustment techniques.

CSS defines five generic font families that each browser must implement. However, letter dimensions do not need to be the same and this means trouble for designers who aim at pixel precise complex layouts. The five generic families are:

  • serif
  • sans-serif
  • monospace
  • cursive
  • fantasy

Typically, in order to ensure that fonts can be displayed you always should include a generic fall-back font by using a so-called "font stacks" like this:

  * {
     font-family: Cambria, Georgia, serif;

This property specification means that by default the browser should use Cambria. This font doesn't exist on some machines (e.g. Ubuntu) so they could then use Georgia or eventually the serif system font if Georgia is missing too.

Below we list a few popular stacks

 font-family: Cambria, Georgia, serif;
 font-family: "Times New Roman", Times, serif;
 font-family: Calibri, Verdana, sans-serif;
 font-family: Arial, Helvetica, sans-serif;
 font-family: "Courier New", Courier, monospace;
 font-family: "Comic Sans", fantasy;
 font-family: "Comic Sans MS", cursive;

Let's just look at the third stack. Calibri is a modern Microsoft font that is good for both screen and print and not available on many system. Verdana is a fairly modern irregular font for screens. Arial is fairly ugly but ok and widely available. Sans-serif would be the default sans serif font of your web browser

Selecting a font that both looks good and is readable is not an easy matter.You may have a look at the font readability article.

If you really must make sure that all users are experiencing the same font, there is a technical solution, i.e. you can embed font files like this.

@font-face {
 font-family: "Cambria";
 font-style: normal;
 font-weight: normal;
 src: url("fonts/Cambria.otf") format("opentype");

However, this is not a foolproof solution either, since many older browser don't support this, since you may have to buy a license and finally since several font file formats exist and not all browsers support these.

Safari, Firefox and Opera support .ttf, .otf and IE supports .eot. That can be solved by providing several URLs for loading a font file, e.g.:

@font-face {
 font-family: "Cambria";
 font-style: normal;
 font-weight: normal;
 src: url("fonts/Cambria.otf") format("opentype"),
      url("fonts/Cambria.eot") format("embedded-opentype");

CSS Box structure

Each HTML element is a box, defined by CSS, with a margin (outside), a border, a padding between the border and content. Each of these "components" are defined by some properties you can set for each side.

In addition, there are shortcuts to set all four sides. Shortcuts that allow to specify all four sides do it clockwise, starting from the top: top, right, bottom, left (The mnemonic to remember this is "TRouBLe").

CSS selectors and declarations

Borders, margins and colors properties (there are many more!)

pt, px, cm, %
Shorthand for all 4 margins
body {margin:1cm;} body {margin:1cm 0.5cm 1cm 0.5cm;}
on top
p {margin-top:10px;}
h3 {margin-bottom:3pt;}
to the left
img {margin-left:50px;}
to the right
p.citation {margin-right:10pt;}
border-width, border-style, border-color
is a so-called shortcut
p {border:2px solid red;}
h1 {border-top:0.2cm;}
solid dotted dashed double etc.
simple line
p {border-style:solid;} h1 {border-style:double;}
padding size
p {padding: 5px;}
value hexa or color name
text color
#menu {color:#000000;}

body {color:blue;}

background color
section, h2 {background:blue;}

Simple example

<p style="margin:0.5cm; padding:0.5cm; border:2pt; border-style:groove">
   <strong style="border-style:dotted;">HELLO</strong> YOU.

Will show like this:


Read the CSS box model tutorial for more information about the boxing model.

As we said before, please do adopt a good a online reference manual such as the SitePoint CSS Reference or HTMLPedia in order to find all properties of a given kind and to learn what values you may use.

Floats, positioning and layout

The float property allows to position elements, e.g. a picture so that text can float around it. In addition floats are used to create so-called fluid layouts that adapt very well to both large and small screens.

CSS 2 then defines four positioning properties: left, right, top and bottom. These allow to position an element with respect to its "normal" position, or with respect to the viewport (what the user sees on the screen) and with respect to a parent element. To define one of these modes, use the position property.

Learn use of floats in the CSS float tutorial and more about positioning in the CSS positioning tutorial

Printing with style

CSS 2 is not really made for printing. However in modern CSS 2.1 browsers, there are some features that you should use. All modern browsers do support CSS 2.1.

Firstly, as we already explained you may use alternative stylesheets or the @media at-rule to define specific styles for printing. In particular, you may get rid of all menus and other stuff that you don't need on paper. In addition, the @page at-rule allows to specify margin values for the "page" box.

Simple example:

 @page {margin: 2.5cm}

Example that sets margins for various page types:

 /* The default rule set a 2.5cm margin on top,bottom,left,right */
@page { margin: 2.5cm; }

@page :left { margin-left: 3cm; } /* left pages */ 

@page :right { margin-right: 3cm; } /* right pages */

@page :first { margin-top: 5cm; } /* first page has an big top margin  */

The CSS3 specification includes additional facilities for styling print. Check browser support before you use these features, e.g. following the links in the CSS compatibility article.

Read more about CSS for print in the CSS for print tutorial.

If your stylesheet doesn’t display as it should

Firstly, please validate your CSS (e.g. upload the CSS file): http://jigsaw.w3.org/css-validator/

Typical syntax mistakes (easy to detect)

  • Missing punctuations in property declaration (":" or ";" or ",")
  • misspelled property names
  • missing brace { ....

Syntax mistakes that are hard to find:

  • Check spelling of HTML element names, the on-line CSS validator will not detect this ! Therefore, start by validating your HTML code first, e.g. use the excellent W3C Markup Validation Service !

Compatibility issues:

  • Check compatibility of your browser or at least check with Firefox or IE8. A very good web site is Quirksmode.
  • If you still must plan for older browsers like IE8, you might avoid CSS 2.1 and stick to CSS 2.0. E.g. IE8 has some problems with a few 2.1 selectors and properties. In particular (I don't know why) CSS 2.1 selectors won't work with CSS for XML.

Logical issues:

  • Remember that most properties are inherited from parent elements and that the last (same kind of) rule defined wins. I.e. the rule that defines what you get may not be the one that you are looking at ...
  • If you use several stylesheet files, make sure to load these in the right order. Selectively load CSS files to see the effect of each.
  • You may use the Firefox Web developper extension to analyse the CSS on a page. This extension is fairly complex and there exist simpler tools that do less, but enough for you probably.

Tools for CSS editing

See also Web authoring system. We recommend using a CSS-aware text editor like Brackets or Bluefish.

There exist browser-based tools, for example:

  • Each navigator includes developments tools that allow to inspect CSS and to make changes. On y Windows systems, try hitting F12 and search for "inspector", "style editor", etc.
  • There exist various browser addons.

As of 2014, we recommend exploring various online tools that allow to exploring and generating CSS3 code. For example

CSS3 animations
Animation tools
Css Sandbox
Code modifiers (to generate all these proprietary properties)
Validation (as alternative to the official w3c validator who tends to produce too many CSS3 "not yet implemented" warnings)

Resources on the web

See CSS links for tutorials and other interesting links. Here we just include a short selection

FireFox extensions that are useful
  • Web developper allows to examine each CSS box on a page and display the CSS code that affects this box. (menu: Tools->Web developer->CSS->View Style Information, then click on box in the page and watch the side pane)
  • Codeburner for Firefox provides searchable reference information and code examples for HTML and CSS.
Online Manuals
Compatibility tables
http://www.quirksmode.org/css/contents.html (consult this for IE 6/7! in particular)
CSS Validator (use it please !)
In EduTechWiki
CSS category