BackBuild your own Website:  Session 4   Previous session  Course Index  Next session


Cascading Style Sheets

The basic principle of CSS is simple and good — to separate content from layout.  For instance, you may have a number of horizontal lines in your web pages, and you want them all to be purple and two pixels high.  You could specify each one as:<HR Color=Purple Size=2>But if you later decide to change to a Red colour scheme you have to go through and change all of them.  It's far better to have one file containing all (or most) of the style information for the whole site.  I call mine style.css — the choice of name is yours, but I strongly recommend .css for an extension.  Part of it (or this could be the entire file) says:HR {Color: Purple; Height: 2px}Of course, each page of HTML has to say that it's using this style sheet.  You do that with a line in the <Head> section:<link href="style.css" rel="stylesheet">This specifies the file name, says that its relationship to the HTML page is that it's a style sheet, and gives the type of data found in it.  Don't worry about what other possibilities you might have for the rel option — just put the line in as it stands.  It really is as simple as that.  Similarly you could specify that all the headings are red, and that all the pages have a light yellow background and use a specific font.H1, H2, H3, H4, H5, H6 {Color: Red}
Body {Font-size: 85%; Font-family: Grunge FS, Arial, Sans-serif;
      Color: #FFFFC4}

CSS Syntax

As you can see, the syntax is very different from HTML.  HTML has attributes of the form keyword=value with the value in quotes if it contains blanks or other special characters, and the elements are separated by spaces.  CSS has properties of the form keyword: value (with or without spaces before and after the colon) without any quotes, and the elements are separated by semicolons.  On many occasions I've left out a semicolon and wondered why the option was being ignored, so WebEdit now checks for this.  The part before the curly brackets is called the Selector, because it selects which element or elements of the HTML will use this CSS element.  Technically the value Grunge FS should be in single or double quotes because it contains a blank space, but that's not considered an error.  CSS also goes out of its way to use different keywords from HTML, though since I haven't taught you any of these you'll have less to unlearn than I did.

Notice that Font-family can have a list of fonts: the browser will choose the first one which is present on the user's machine.  You might think that Grunge FS is a great font — and indeed the site may look great on your machine — but if people don't have it they'll be viewing the page in Arial.  And if they don't have that (on a Unix machine or an Apple Mac, for instance), the browser will choose whatever has been designated as the basic Sans-serif font for that machine.  So make sure you put a generic font as the last one in the list.  These are Serif (e.g. Times), Sans-serif (e.g. Helvetica), Cursive (e.g. Zapf-Chancery), Fantasy (e.g. Western) and Monospace (e.g. Courier).

As with HTML, the layout is for the benefit of you and other people reading it; the browser doesn't care if the whole thing is on one line with no spaces.  Many people lay it out with each option indented on a single line:Body {
  Font-size: 85%;
  Font-family: Grunge FS, Arial, Sans-serif;
  Color: #000000;
  Background-color: #FFFFC4;
}
H1, H2, H3, H4, H5, H6 {
  Color: Red;
}
In fact WebEdit will reformat it just like this.  If you don't like my formatting please tell me, and I can probably add an option to do it your way.

You might think that a value in the Body section of the CSS would apply to absolutely everything in the page, but it doesn't apply to input tags.  If you want that, you have to replace the first line byBody, Input {

Note that I didn't say LightYellow for the background colour, I said #FFFFC4.  There is a LightYellow, but I wanted it slightly darker than that.  There's an argument that you should always specify colours by number rather than by name, as a name may mean different things to different browsers, or indeed they may not recognise the name at all.

So how did I know what value to specify?  If you want to work it out manually, after the # sign the next two characters specify how much Red there is in the colour, using hexadecimal (base 16) digits from 00 (no red) to FF (maximum red).  The next two are Green and the last two are Blue.  But in practice I use WebEdit, position the cursor somewhere in the colour value and click Edit|Colour or simply double-click the mouse.  This displays a colour palette and I can vary the colour as required.  Other HTML editors such as Dreamweaver have similar options.  Let me warn you in advance: when you choose a background colour which you see in a little square, you're bound to make it too dark!  To get round this problem, WebEdit has Options|Colour CSS and if this is active and you position the cursor in a CSS section which contains Color or Background-color the whole screen will be displayed in the specified colour(s).  If the sections contain only one, WebEdit will try and choose something sensible for the other, but it's not perfect!

  Exercise

Write CSS which will display <H1>, <H2> and <H3> headers in the Verdana font, or a generic sans-serif font if that is not available, with purple text on a red background.

Div and Span tags

These tags come into their own when you use CSS.  <Div> means a division, and is similar to a paragraph except that it doesn't have a blank line after it.  On the other hand, you can have a <Div> within a <Div>, which you can't do with a paragraph.  The <P> tag is odd anyway, since you can put in a closing </P> tag or leave it out as you wish, and I don't like that.  In fact WebEdit can't validate a file containing </P> tags and will ask permission to take them out.  If you really want the closing tag for some reason, the solution is to replace <P> by <Div>, and then you do have to close it with a corresponding </Div> tag.  You can give a Class or ID to each Div and then specify in the CSS how you want it to look:.Box1   {Color: Green; Font-weight: Bold}
#Error  {Color: Red; Background-color: Yellow}
<Div Class=Box1>This is green bold text</Div>
<Div ID=Error>This is red on yellow</Div>
If you put a dot at the start of the definition it means you're referring to the Class keyword in the body, so .H2 is quite different from H2.  If you're using XHTML (which I haven't talked about yet and no longer use) or HTML 4.01 and above, the name is case-sensitive: if your CSS says .Box {.. and your HTML says class="box" you won't get an error message — it just won't work!  If you know you will only have one occurrence of an item in each page (for instance the main heading or the menu) you can replace the dot with “#” and use Id instead of Class — I don't know whether this has any real advantage, but Id is something you will need if you write dynamic code.

If you don't want the sections separated by a blank line, use <Span> --- </Span> instead.

  How would you make the first paragraph of each page stand out?<Div Class=Intro>
This is my first paragraph.
</Div>
.Intro {Font-size: 140%; Background-color: #E6E6E6}If you have selectors separated by commas, the list of properties applies to all of them.  Here's an example from my site:.Box TD, .Box TH {
  Padding: 1px 4px;
  Border: 1px Solid Black;
}
This says that I have a class called Box (which I use for tables), and all the <TD> and <TH> elements in such a table have some padding and a solid black one-pixel border.

If you have selectors separated by spaces, the list of properties applies to selectors within selectors.  In other words, if you haveTable {Background-color: LightYellow}
Table Table {Background-color: LightBlue}
this says that normal tables have a light yellow background, but a table within a table has a light blue background.  They needn't both have been the same tag — I could have specified that all lists within a table have a green background.

Three places to put CSS

I've been talking about the first and most general place to put the style information: in a separate file which is linked to by all your HTML pages.  If your site contains a number of Sales pages which use some of their own style settings, these might contain to link to two stylesheets:<link href="sales.css" rel="stylesheet">
<link href="style.css" rel="stylesheet">
For instance, style.css might say that headings were Blue, whereas for the Sales pages you want Red headings, so you would specify that in sales.css.  Because that one comes first, the Red value will be used.  Other keywords which appear in style.css but not in sales.css will use the values from style.css as before.

The next place, getting more specific, is in the <Head> of a page.  You may know that a couple of styles will be used only in a single page — maybe a slide-show of your photos — so there's no point putting them in the general style page.  Instead the same information goes within <Style> tags.  I'm not going to explain all this — it's just an example!<Head>
  <Title>Photographs</Title>
  <Style>
    .H {Background: #E0E0E0 None; Border: white 2px solid;
        Height: 64px; Width: 74px; Padding: 3px;
        Float: Left; Text-align: Center; Padding-top: 14px}
    .V {Background: #E0E0E0 None; Border: white 2px solid;
        Height: 74px; Width: 64px; Padding: 3px;
        Float: Left; Text-align: Center; Padding-top: 4px}
    #Thumbnails {left: 200px; top: 130px; width: 550px;
        position: absolute}
  </Style>
  <Link Href="style.css" Rel=stylesheet>
</Head>
<Body>
<Div Id=Thumbnails>
  <Div Class=H><A Href="image.htm?3"><Img Src="thumbnails/IMG_0677.jpg"
  Alt="" Border=0 Width=72 Height=54></A></Div>
  <Div Class=V><A Href="image.htm?4"><Img Src="thumbnails/IMG_0679.jpg"
  Alt="" Border=0 Width=54 Height=72></A></Div>
  * * *
Here I have three style elements which are specific to this web page, and then the link to my general style sheet.  The rule is that the more specific overrides the more general, though an item can pick up attributes from more than one style sheet — that's why they're called Cascading, though it's not the image the word conjures up for me!  So any value in H2 in the <Head> section overrides the corresponding value in style.css.  Of course, if you later find that you want the same styles in several pages, you just put the definition into style.css and remove it from the HTML pages.

And the third, most specific place, is in the tag itself.  You can add style to any tag (though some people say you should never do this):<h1 style="color: orange; font-weight: bold">So there we have CSS within HTML — make sure you understand the distinction.

There are about 200 CSS properties; I haven't used a fraction of them.  There are many websites which list them all — I use blooberry.com/indexdot/css/propindex/all.htm which also talks about quirks in the way they work in various browsers.  A newer reference is reference.sitepoint.com/css.

Font properties

Here's a list of some I use, with some of their possible values:

Some properties also have shorthand versions — you can specify three or four properties in one if you wish.  For instance, instead of:font-weight: bold;
font-style: italic;
font-variant: small-caps;
font-size: 1em;
line-height: 1.5em;
font-family: verdana,sans-serif
you can use this CSS shorthand property:font: bold italic small-caps 1em/1.5em verdana,sans-serifThis CSS shorthand version will allegedly only work if you're specifying both the font-size and the font-family.  The font-family command must always be at the very end of this shorthand command, and font-size must come directly before this.

I find CSS harder work than HTML.  I can see it's a good idea, but I often find it frustrating trying to get things to work the way I want, and some of the rules seem pretty bad!  I hope you can profit by my mistakes though.

Padding, Border and Margin properties

A source of endless confusion.  It's all explained at w3.org/TR/2004/CR-CSS21-20040225/box.html or if you want even more detail see w3.org/wiki/The_CSS_layout_model_-_boxes_borders_margins_padding.

In essence, each “Box” has its contents which can then be surrounded by Padding, then Border, then Margin.  Border is the only one where you can specify the colour and style.  Padding is the same background colour as the box, and Margin is the same colour as the background of the containing box.  I find I use all three of these.  There are many possibilities.  You can specify all four values:.MyBox {Margin-top: 12px; Margin-bottom: 8px; Margin-left: 2px;
  Margin-right: 2px}
Or if they're all the same you can just say:.MyBox {Margin: 8px}Or if top and bottom are the same and left and right are the same you can specify the values in the order Top, Right:.MyBox {Margin: 12px 2px}Or you can specify the values in the order Top, Right, Bottom, Left:.MyBox {Margin: 12px 2px 8px 2px}Don't be intimidated by all the choices — they're designed to make your CSS shorter.

Similarly with Borders you can specify Border-top-color, Border-right-color, Border-bottom-color and Border-left-color if you want to create a 3-dimensional effect, or just Border-color to make all four the same colour.  The third Border attribute is Border-style, and I use Solid — others may work, but it depends on the browser.  You can even combine the size, style and color in one go:.MyBox {Border: 1px Solid Blue}and that is what I recommend unless you're doing the 3-D stuff.  If you're specifically giving the width of the borders you could specify.MyBox {Border-top-width: 12px; Border-bottom-width: 8px;
    Border-bottom-left: 2px; Border-right-width: 2px}
but if you leave out the “width” you're using the shorthand and it will still work, so you could condense it to:.MyBox {Border: 12px 2px 8px 2px}

I found IE7 was putting in a horizontal scroll-bar and couldn't work out why for some time.  Eventually I realised that to get a margin on each side of my main block of text I had it in a div which specified left: 10px; right: 10px and what I needed was margin-left: 10px; margin-right: 10px — yet another case of telling it like it is!

Alternative stylesheets

You can specify several stylesheets and let the user choose.  For instance:

<HTML>
<Head>
  <Title>Alternative stylesheets</Title>
  <Link Href="Standard.css" Rel=stylesheet>
  <Link Href="Red.css" Rel="alternate stylesheet"
    Title=Red>
  <Link Href="Green.css" Rel="alternate stylesheet"
    Title=Green>
  <Script Src="styleswitcher.js"></Script>
</Head>
<Body>
<H1>Colour schemes</H1>
<A OnClick="setActiveStyleSheet(''); return false;">Standard</A>
<Br><A OnClick="setActiveStyleSheet('Red'); return false;">Red</A>
<Br><A OnClick="setActiveStyleSheet('Green'); return false;">Green</A>
</Body>
</HTML>

I don't want to get involved in trying to explain JavaScript — just accept that if you click on the “Red” or “Green” link it calls a routine “setActiveStyleSheet” which makes the specified stylesheet active.  My stylesheet Red.css specifies a dark red colour and a light red background, etc.  The routine is hidden away in the file styleswitcher.js — the <Script> tag tells the browser where to find it — and there are others which save the user's setting as a cookie on his machine, so that if he goes to another page of your website, or indeed if he comes back to your website in a week's time, he will still be using the style he selected.  Don't question me about it — just accept it as a useful bit of magic!

The article explaining all this is at alistapart.com/articles/alternate and you can download the JavaScript routines from alistapart.github.io/ code-samples/alternate/ styleswitcher.js  In the example he puts this in a scripts folder, but I'm just putting it in the same folder as the HTML files.



  Homework for this session: Create file style.css and link it into your web pages.  Specify that the pages will use the Lucida Sans Unicode font if this is available.  Give a background colour to your pages (not too violent) and try out some other things.  Don't be afraid to experiment — you won't break anything!