2010-12-11

Writing CSS style sheets


Writing CSS1 style sheets
A short guide

The aim of this guide is to show, with examples, the principles you should follow when writing style sheets, so as to not risk your documents hard or impossible to read for some users, as well as providing solutions to some specific problems.


This guide is not intended to give a complete overview of all the features in style sheets, the W3C has the authoritative specification, and at the WDG is a guide to Cascading Style Sheets you can find much useful information, and the document CSS Pointers contains links to other useful resources. Nor will it deal with how existing browsers render, or fail to render, documents with style sheets.
The article Effective Use of Style Sheets is written by an expert on usability, so reading it before implementing style sheets is strongly recommended.
I'm not an expert, but I've tried to write down the things I'd liked to have available, in addition to the existing resources, when I started using style sheets (it might have been and may be now, but when I started writing this I hadn't found it). If it had been, I'd have been spared a lot of problems and embarrasement with badly written style sheets.

List of contents

Why I like style sheets

To sum it up in one sentence: Style sheets separate content from presentation. Or to put another way: "If you lie to web clients, they will get their revenge".
For example, headers should always be marked up as headers and not as "large text", if you use DL for anything but definition lists, some browsers and users will be, at least, confused. With style sheets, you can separately from the content suggest how it should be rendered, which is why I hope and think it will encourage authors to correctly mark up their documents.

Is nothing wrong with style sheets?

Yes, unfortunately there are problems with the CSS1 specification. For example, I don't like that author specified important properties takes precedence over those deemed important by the user. The the normal order of precedence is authors' rules first is natural, as the author is the one who knows which elements are present in a document, and therefore can specify them all.
Nor do I much appreciate that it's possible with "hacks" to create documents that are dependent on style sheet support in order to be readable at all. Hopefully this will never become popular.
Additionally, it's too easy to by mistake create documents which will render unexpectedly, sometimes hiding information, depending on browser settings, especially personal style sheets.
For example, for you a document may render in the way you expect, because elements inherit properties, but a user may have a personal style sheet which goes into greater detail than yours, so you may set a property for H3 and expect H3 STRONG to look similar, but a user may have set properties for both H3 and H3 STRONG, which clashes with your suggestions. Yes, one might assume the user has done so on purpose and understand what's happening, but not that she is likely to see documents without any author style sheets or those with properties for both H3 and H3 STRONG in a more pleasing way.
Some people think style sheets are inherently harmful and while not agreeing wholly, I do agree that by using some features the readability and usability of documents may decrease, so you should be aware of the potential problems before starting to using style sheets, so read that document!

Some things to do, and not to do

Most advice here is equally valid both for authors' style sheets and personal style sheets.
(You will need style sheet support so see how the examples are rendered. What looks like links in the examples, isn't.)

Don't build in style sheet dependence

One thing you must always keep in mind, is that you must never write a document which relies on its style. It must always be useable without your styles, or with any other valid style sheet.
Another way to say this is that the styles must never say what something is, only how it looks!
So, for example headers should always be marked up as headers, not something else.
For example, this style sheet declaration
H5 { color: Maroon; background: White; font-size: 140%; font-family: Arial, Verdana; }
together with this markup
<H5>This is a header</H5> This is some normal text.
will produce something like this
This is a header
This is some normal text.
A similar style sheet declaration, like this
.header1 { color: Maroon; background: White; font-size: 140%; font-family: Arial, Verdana;}
could be used together with markup like this
<DIV CLASS=header1>This may look like a header, but it isn't</DIV> This is also some normal text.
to produce a result like this
This may look like a header, but it isn't
This is also some normal text.
but only if used in conjunction with this specific style sheet declaration!
If the user uses no, or another style sheet, the two examples might look something like:
This is a header
This is some normal text.
This may look like a header, but it isn't
This is also some normal text.

What can go wrong with colours

One area where conflicts between browser settings, personal and author style sheets is very likely to result in (partly) unreadable documents is colours.
What you must do if you specify colours is:
  • If you specify a colour for an element, also specify that element's background colour, at the same level of importance and specificity.
  • If you specify a colour (and background) for any of the elements BODY, A:link, A:visited or A:active then specify both colour and backgrounds for them all.
Should you wish, you can set also set these colours with the <BODY> statement, but I don't encourage this.
Avoid setting colours in non-style sheet ways in the body of documents, with <FONT> and similar elements.
Consider this, rather dull, appearance (which incidently is close to the default settings on some browsers):

This is a header

This is normal text, the quick brown fox jumps over the lazy dog.
This is a new paragraph. Here follows two links, one visited and one unvisited link.
The author/user (no, it really doesn't matter which for this discussion, as the conflict can happen in either case) now wants to liven it up a bit, by making headers deep blue, and puts this into a style sheet:
H4 { color: Navy; }
with this being the expected result:

This is a header

This is normal text, the quick brown fox jumps over the lazy dog.
This is a new paragraph. Here follows two links, one visited and one unvisited link.
But suppose there's an author/user who prefers dark backgrounds, and has written a style sheet thus:
BODY { color: White; background: Navy; }
A:link { color: Yellow; background: Navy; }
A:visited { color: #FF7; background: Navy; }
A:active { color: Aqua; background: Navy; }

As you see, there's no H4 instruction, so if used together with the style sheet which has one, then that instruction will be used, and the document will be rendered thus:

This is a header

This is normal text, the quick brown fox jumps over the lazy dog.
This is a new paragraph. Here follows two links, one visited and one unvisited link.
Much the same thing will happen if you write style sheet instructions which rely on the browser's default settings to produce the desired effect.
This problem is not dependent on order of precendence, and thus cannot be countered by increasing the elements' importance, nor can it be countered by relying on inheritance, since if one party specifies properties for example for SMALL A:link EM, then it doesn't matter what the other party has specified for either SMALL, A:link or EM nor for SMALL A:link or SMALL EM and so on for that matter.
Had the first person taken care to specify a background also, like this:
H4 { color: Navy; background: Silver}
then the rendering would have become like this:

This is a header

This is normal text, the quick brown fox jumps over the lazy dog.
This is a new paragraph. Here follows two links, one visited and one unvisited link.
which perhaps isn't very good looking, but it is perfectly readable, which is the most important thing of all.
As an author, you know exactly which elements are present in a document, and if you give them all properties, this will not happen, as a user, you cannot know which elements documents will contain and it's practically impossible to specify them all, so you must be prepared for some behaviour like this.

What can go wrong with fonts

Font faces

Any use of fonts entails a risk, because you cannot know if the user can read a certain font.
One reason for that is that the same font name may mean different things on different systems, and thus give very unexpected renderings, another is that different fonts can have different smallest size where they are readable (and for the user to choose the smallest readable size for the font she is using makes sense as it puts the window space to best use), so a font which in itself is good may not display well at the settings in use.
To decrease the risk, I think it's better to use short font lists, perhaps only a single font. This makes also makes sense if you want the font to match the font on any graphical elements and reduces the number of possible combinations in case you suggest different fonts for different elements.
I used to not recommend the use of serif, sans-serif, monospace or other generic font families in style sheets. The reason for that was that while it is possible in some browsers for the user to select the font to be shown for these generic families, it is not always and then neither the author nor the user, only the browser maker, determines which font is to be displayed. And as the browser maker has no way of knowing the content of the document nor the user's preferences and browsing situation, I've seen cases (but not recently) where this has resulted in an unreadable font. In such a case, the user set default font is probably a better choice.
But now it's come to my attention that there are systems which, if they don't have the specified font installed will substitute it with the closest alphabetically. Such a system will in all likelyhood display a better font if one includes the generic font families.
When suggesting one font for the element BODY, you had better suggest a font for the elements which should be rendered in a fixed spacing font, like TT and PRE, so they aren't rendered in a proportional font.

Font sizes

Don't use font sizes smaller than 100% or 1.0Em, as that can lead to the text becoming too small to be read, sometimes even if it's "just" 90%, if the user has set the default font size in the smaller range of readable, in order to get more information to fit on the screen, because those values will be interpreted literally by the browser, even if the text size is obviously too small to be legible. See: Toward a standard font size interval system for an explanation.
Using the HTML SMALL instead reduces the risk, as at least some browsers have a routine to protect against SMALL getting unreadable small. Some browsers seem to have a similar mechanism in place for the CSS font-size values xx-small, x-small and small so using them is also a better solution than percetages smaller than 100%.

Choosing a DOCTYPE

It is perfectly possible to add styles to HTML 2.0 and HTML 3.2 documents. The limitation in using these doctypes is you cannot use CLASS or SPAN in your documents. Seen one way, this may be an advantage, as these elements have the potential to build in style sheet dependence in documents.
But generally, I recommend you use HTML 4.01. Then you can use CLASS, and put style on parts of the document based on that.
The DOCTYPEs you can choose between in HTML 4.01 are the "loose" one (which is backwards compatible and can be used for old documents already written):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
or the "strict":
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
In these cases, you link to your external style sheets like this:
<LINK REL=STYLESHEET HREF="my_style_sheet.css">


Validating your documents and style sheets

I suggest you use the W3C HTML Validation Service for your documents, and the CSS2 Validation Service for your style sheets.
Doing so ensures that you haven't made a tiny mistake which your browser overlooks.

Stylistic and ergonomic considerations

I recommend that you never use more than two fonts, plus a fixed pitch font, per document. It's probably also a mostly good idea to limit the number of different colours and see to that they don't clash with each other.
The way you can write style sheets makes it easy to keep track of how many fonts and colours you've used, because you do not have to specify all properties for an element at the same place. My recommendation is that you instead group the elements by properties. This also makes it far easier to maintain a style sheet, as if you should wish to change a font or colour, you can do that in a single place. Very handy in case you want to change plain white to off-white beige, navy to a deeper blue or discover that a font name you've given refers to wildly different fonts on different systems.
To furthermore group the declarations by type, and separate the font declarations from the colour declarations, makes it easier to give them different levels of importance. Only the user can know which fonts are available on the system and which font sizes makes for comfortable reading, so for the user it makes sense to at least mark font size as important; Colour blind users need to mark their colour selections as important.
The downside to grouping by properties is of course that if you have a large and complex style sheet, it's not easy to see at a glance all properties for an element, which means you must take care whenever adding an element, especially to give it both a colour and background.

Some sample style sheets and examples

Basic style sheets - templates

Let's start with a simple style sheet, one which will only set the basic colours:

BODY      { color: Black; background: White; } 
A:link    { color: Teal;  background: White; } 
A:visited { color: Blue;  background: White; } 
A:active  { color: Red;   background: White; } 

This is a header

This is normal text, the quick brown fox jumps over the lazy dog.
This is a new paragraph. Here follows two links, one visited and one unvisited
In case you also wish to suggest some fonts, you can do like this:

BODY      { color: Black; background: White;
           font-family: Garamond, serif; } 
H4        { font-family: Arial, sans-serif; }
PRE, TT   { font-family: Courier, monospace; }
A:link    { color: Teal; background: White; }
A:visited { color: Blue; background: White; } 
A:active  { color: Red; background: White; } 

This is a header

This is normal text, the quick brown fox jumps over the lazy dog.
This is a new paragraph. Here follows two links, one visited and one unvisited link.
This text is rendered in a fixed pitch font.
Perhaps you want centered headings and first line indentation of paragraphs, and wider margins in some paragraphs:
BODY { color: Black; background: White; }
A:link { color: Teal; background: White; }
A:visited { color: Blue; background: White; }
A:active { color: Red; background: White; }
H4 { text-align: center; }
P { text-indent: 15%; }
P.margins { margin-left: 20%; margin-right: 20%; }


results in approximately this appearance:

This is a header

This is normal text, the quick brown fox jumps over the lazy dog. The first line is supposed to be indented. The quick brown fox jumps over the lazy dog.
This paragraph has extra wide margins. That's been specified with <P CLASS=margins> in conjunction with the style sheet code above. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
The first line in this paragraphed is also indented. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
Perhaps you want to make some text really stand out:
BODY { color: Black; background: White; }
A:link { color: Teal; background: White; }
A:visited { color: Blue; background: White; }
A:active { color: Red; background: White; }
STRONG { color: Navy; background: Yellow; }

results in approximately this appearance:

This is a header

This is normal text, the quick brown fox jumps over the lazy dog.
This is a new paragraph, with some words with strong emphasis. Here follows two links, one visited and one unvisited

Specific solutions

Borderless images

As a general case, I would not recommend borderless images, but sometimes it looks better and does no harm (in that the image may clearly be a link or there is a text link too).
Do it either like:
<A HREF="http://www.w3.org/Style/CSS/Buttons"><IMG
STYLE="border: 0Px" SRC="cssos.gif"
ALT="Parts of this site are made with Cascading Style Sheets."></A>

or give the image a CLASS attribute:
<A HREF="http://www.w3.org/Style/CSS/Buttons"><IMG
CLASS=icon
SRC="cssos.gif" ALT="Parts of this site are made with Cascading Style Sheets."></A>

and define it as borderless in the HEAD of the document:
<STYLE TYPE=text/css><!--
IMG.icon {border: 0Px;}
--></STYLE>

Different coloured links

If you want to distinguish external and internal links, in your style sheet first define the normal colours, and then the colours for the class "ext":
BODY { color: #333; background: #FCFCFC;}
A:link { color: blue; background: #FCFCFC;}
A:visited { color: navy; background: #FCFCFC;}
A:active { color: White; background: #A21; }

A.ext:link { color: green; background: #FCFCFC;}
A.ext:visited { color: olive; background: #FCFCFC;}
A.ext:active { color: White; background: Black; }

Normal links you write as normal links, an external link you give the class "ext" like this:
<A CLASS=ext HREF="some_url">link text</A>
Or, if you want to give whole sections of a document differently coloured links, first define the regular colours, then put this in the style sheet:
DIV.ext A:link { color: green; background: #FCFCFC;}
DIV.ext A:visited { color: olive; background: #FCFCFC;}
DIV.ext A:active { color: White; background: Black; }


Then, before the section in your document where you want all links to have a different scheme, put in: <DIV CLASS=ext> and after the section: </DIV> .
I think this shows the general principles, for details, see the references at the top of the document.

Scaling images relative to text

Sometimes you may want images, like icons with text, to have a certain size relative to the text in the document. Then you can use the Em unit, where 1Em is roughly the height of a character, like this:

<IMG STYLE="height: 2Em;"
ALT="Whatever" SRC="picture.gif">

"Preventing too long lines"

Sometimes, an author feels that unless something is done, the lines will become too long for comfortable reading. Normally, I'd say this is better left alone, as users can be expected to configure their browsers.
If you think you have good reasons to do it, you should do it in as harmless way as possible. This means don't put in line breaks where you think they should be in the text, as this will lead to the lines being different length for anyone with a wider window in relation to the font size than you have; Don't put the text in a table which has a width set in pixels, as this will lead to some text falling outside the window if it's narrower and the lines being ridiculously short for those with a high screen resolution.
Instead, you should set the line length in relation to the font size, using the Em unit.
This example of how it can be used, which for the time being is the method I recommend, (use whatever value you think fitting), which where I've tested it, it doesn't let the text flow past the window edges (which in a way is illogical, so I wouldn't trust it too far), and on more than one browser the text doesn't get wider than 18Em:

<TABLE><TR><TD STYLE="width: 18Em;">
<P>Put your text here
</TABLE>
So far, the worst effect I've seen is that it doesn't do anything at all, apart from the usual thing with tables: Slow down document loading, so even if you use it, I really don't think you should except in special circumstances.

Alternatives

The more logical solution would be to set the width on individual paragraphs (<P STYLE="width: 18Em;">, which works fine in at least one browser, but not in one of the most common) or to use DIV instead of TABLE (as the content isn't really tabular):

<DIV STYLE="width: 18Em;">
<P>Put your text here
</DIV>
The drawback with setting the width of the DIV is that I've observed the text flowing outside the window in one common browser, if the window is narrower than the computed width. A solution to this would be the minimum and maximum widths from CSS2 (which unfortunately aren't widely supported yet):

<DIV STYLE="width: 18Em; max-width: 100%;">
<P>Put your text here
</DIV>

Using CSS instead of text as graphics

Instead of using images of text, because one wants a certain size or background colour, which can be wasteful of space and speed, it's in many cases possible to format the text, for example a header or a photo caption, using CSS.

h1.main {color: white; background: #666; width: 100%; 
   font-size: 250%; padding: 15Px; }
p.caption {color: black; background: #EEE; width: 200Px;
   text-align: center; font-size: 12Px; padding: 3Px;}

<h1 class="main">Some text</h1>
<p class="caption">Some text</p>

For example, the above CSS and HTML can give about the following appearance:
Some text
Some text

User style sheets

Creating a style sheet for your own use can be good way of customizing how your browser displays different elements. This can be made both with general options which would be suitable in an author supplied style sheet, but also with content, like absolute font sizes, which is best left to each user to choose.

Compact display

This is a suggestion for how to get as much text as possible into the browser window. I won't claim it looks pretty, but it's rather efficient. Perhaps you'll like the look better if you increase some of the values.

H1, H2, H3, H4, H5, H6, P, UL, OL, LI, 
 TABLE, PRE {margin-top: 0Px; margin-bottom: 0Px;}
HR {margin-top: 2Px; margin-bottom: 2Px;}
H1 {font-size: 125%} H2 {font-size: 120%} H3 {font-size:
115%}
H4 {font-size: 110%} H5 {font-size: 105%} H6 {font-size:
100%}
P {text-indent: 1.5em;}
BLOCKQUOTE, UL, LI { margin-left : 0.5Em; }

Font size depending on element
Preventing some horizontal scrolling

Sometimes, tables and preformatted text is wider than the browser window, so if the text was just a bit smaller it would fit, and you wouldn't have to scroll horizontally. By specifying a smaller font size for those elements, you won't have to scroll horizontally as often.

BODY           {font-size: 14Pt ! important; }
BIG            {font-size: 16Pt ! important; }
TD             {font-size: 10Pt ! important; }
PRE, SMALL     {font-size:  9Pt ! important; }
One might think that one could leave everyting but PRE and TD alone (BIG and SMALL aren't really necessary in the above example) and give them a percentage of the base font. The problem with that is inheritance, while for example 80% is perfectly readable in most cases, it won't be if the author already has reduced the font size (perhaps for the same reason), as then it'd be 80% of that value.

Want all links underlined, but nothing else?

Since with CSS it's possible to have more than two link colours in the same document, it can be practical to have a way of distinguishing links from other text, for example underlining.
This is how you disable a document's removal of underlines on links:
A:link, A:visited, A:hover { text-decoration: underline ! important }

And this how you remove underlines from ordinary underlined text (but not where the author has specifically suggested underlined text with CSS, if you want that, add more elements than just U and the !important rule):

U       {text-decoration: none ; }

Don't like italic text?

On some displays, italic text isn't as readable as ordinary text, so you might want to have it as seldom as possible. This changes a few commoneelements (including italic itself) which usually are rendered in italic to normal text:

ADDRESS, CITE, I {font-style: normal; }

Document created in 1996, content last modified or added to 2002 Feb 12 content checked and links updated 2002 Apr 17 by Urban Fredriksson

No comments:

Post a Comment