CSS Philosophy and Tutorial

Draft - still under construction

The purpose of this and the accompanying articles is not to teach the details of any specific part of the language. Such information is readily available from many sources.

You are reading this in order to learn how to think while using the language, how to write poetry and not doggerel, how to be a good programmer, coder, or author.

Web Design Philosophy

If you haven't read the introduction to web design philosophy, you should do that first. It covers a general philosophy to be applied to all languages, and you should understand it before reading this document.

CSS Philosophy

Define visual layout and appearance.

The target audience is human beings. Use CSS to control the visual appearance of the data only. Be concerned about the appearance of individual types of data, not the data itself or the physical media upon which it will be displayed.

Terminology

You are likely already familiar with these Cascading Style Sheets (CSS) terms, but this will serve as a reminder.

cascading
refers to having a well defined order of precedence for conflicting style rules in multiple style sheets.
style sheet
is a self-contained set of style rules.
ruleset
is a complete style rule, consisting of a selector and a declaration.
selector
specifies which HTML objects are to be affected by this ruleset.
declaration
is the rule to be a applied, consisting of a property and a value.
property
specifies the pre-defined name of a property of the selected object(s).
value
is the value to be assigned to that property.
Ruleset Example
selector[,selector]* { property:value; [property:value]* }
ul, ol, dl { margin-left: 4em; }
dt { margin-left -2em;
     font-weight: bold; }

   =

ul { margin-left: 4em; }
ol { margin-left: 4em; }
dl { margin-left: 4em; }
dt { margin-left -2em; }
dt { font-weight: bold; }
  			
Rules with multiple selectors or multiple declarations are treated as their cross product.

Multiple selectors with the same property, and selectors with multiple properties, are often written in a combined form.

This CSS is conceptually converted into individual rules, each with only one selector and one property.

Cascading

Style sheets can be defined in more than one place:


<-- This site. -->
<link rel="stylesheet"
    href="/style.css"
/>

<-- This folder. -->
<link rel="stylesheet"
    href="style.css"
/>

<-- This page. -->
<style>
    ...
</style>
			
Style sheets used in my web pages.

As with the set of documents you are reading now, you will often have a style sheet shared by the entire site, a smaller style sheet shared by all the pages in a document set, and a very small style sheet within each document's head section.

The principle you should follow is to devise style rules that are as generally useful as possible, and let them apply to all your web pages (e.g. almost all my pages have the same background color). Then, set rules that are also as general as possible while being specific to the current set of pages (e.g. the boxed figures have the same style for all web design tutorial pages in this collection). Finally, and only if necessary, set rules within the head of specific pages.

<span
  style="background-color:#FF00FF;">
    Fuchsia=#FF00FF
</span>
			
An appropriate use of inline style.

You should not use style="ruleset" attributes. The one exception is when the style is actually an attribute of the HTML object itself, not a formatting directive. For instance, when giving a list of color values it would not be inappropriate to set the background color explicitly within the HTML rather than making unnecessary complications with ad hoc style rules in the head section.


  img { width: 50%; }
a>img { width: 1em; }
  img { width: 30%; }
  			
The last rule should apply to all images. But the second rule, not the last, will apply to images immediately within anchors.

When multiple rules are defined for the same selector, the last one encountered by the browser is used.

When multiple rules apply to the same HTML object, the most specific one encountered by the browser is used.

Units

The HTML document stressed how important it was not to specify the sizes of anything while marking up your document. It is here in the style sheets that you can now work with sizes. But, never use absolute units.

If you specify sizes in inches or centimetres it might look fine on your display, but consider how huge three inches is on a mobile phone, and how tiny it is on a projection screen in an auditorium. You almost never want objects to have an absolute size.

Similarly, if you specify size in pixels it again might look fine on your display, but consider how large it will be on a low-resolution TV screen, and how tiny on a 4K screen. Again, you will almost never want objects to have an absolute size.

What you do care about is the relative size.


Consider an image that contains important details that you want your audience to be able to see. You can safely assume that they can read the surrounding text, regardless of how small or large it actually is. If the person looking at it has very sharp eyes, they will have small text, and so a small image will work fine for them. If the person looking at it needs large text, a large image will be needed for them. All you have to do is display the image as tall as some number of lines of text:
{ height: 6em; width: auto; }.

Similarly, consider an image used mostly to enhance the appearance of your page, or to provide an impression rather than specific detail. Do you want it to fill the full width of the page, or be half its width, or perhaps a quarter? Those are aesthetic questions that only you can answer. But you can answer them; what you want is whatever looks best in proportion to the rest of the page. On the other hand, if someone's display is very narrow (e.g. a mobile phone), you don't want the image to be so small it can't be seen. You can handle both concerns with:
{ width: 30%; min-width: 10em; }.


All sizes (including borders, margins, etc.) should always be specified in relative units, either as a percentage of the width of the enclosing container (%) or relative to the current font size (em).

No other units are needed, and all other units should be avoided. Almost all problems with poor formatting, non-portability, and lack of accessibility are caused by the use of absolute units.

Font Sizes

Sometimes the difference between absolute and relative is subtle. You can set the font-size attribute to values such as small, smaller, x-small, or xx-small, as well as medium and the corresponding large sizes. Only smaller and larger are relative sizes. The rest are all absolute sizes, and shouldn't be used.

<p style="font-size: 150%">
  Blah blah
  <span style="font-size: large">
    word
  </span>
  blah blah.
</p>
			

Blah blah word blah blah.

The large word is actually relatively smaller.

If you use large for some word within a paragraph for instance, the word will appear larger than the surrounding text. But if at some time in the future a change to a style sheet causes the containing paragraph to have a much larger font, the word you have marked could end up being smaller than the surrounding text, because large is an absolute size that might actually be smaller than the paragraph's.

Or some readers might have set their browser's preferred font size to something quite large or quite small. If so, your large or small might appear as smaller or larger than the surrounding text, the exact opposite of what you were trying to achieve.

It would have been much better if you had set an explicit relative value, say font-size: 120%;. That makes it very obvious that you want it to be 20% larger than the surrounding text, and it totally eliminates any possibility of having things break later on. It also guarantees a similar appearance across browsers.

Page Width

Web pages that specify their widths can be very annoying and frustrating.

On wide screen devices, large amounts of real estate are wasted at either side of the page. You have to room to see it all, but web designers went out of their way to explicitly force you to see only a narrow column of text.

Similarly, on narrow windows, the fixed-width document forces you to horizontally scroll the text back and forth in order to read it, again because of explicit style settings made by some brilliant web designer.


There are of course legitimate reasons for limiting a page's width, but explicitly setting a fixed width is not the right solution.

Small text on a very wide window will produce excessively long lines, which are difficult to read, especially when trying to find to the beginning of the next line.

/* All three forms are required. */
-webkit-column-width: 30em;
-moz-column-width: 30em;
column-width: 30em;
			
column-width is not yet a fully implemented property of the CSS standard.

There are at least two good solutions to that problem. The simplest is to restrict the maximum line length (to some number of em, not of inches or pixels):
body { max-width: 60em; }.
Another is to tell the browser that it can display the page in multiple columns whenever the window is sufficiently large:
article { column-width: 30em; }.

In either case, you are setting a reasonable limit on the width of a line of text, and the web browser software is making everything look as good as possible on each person's particular viewing device. This is how HTML, CSS, and browsers are intended to work together.

Reset

html {
  box-sizing: border-box;
  text-align: left; vertical-align: baseline;
  border-style: solid;
  font-family: sans-serif;
  color: #000; background-color: #FFF;
  border-color: #000; border-collapse: collapse;
  column-rule-style: solid;
  column-rule-color: #000;
  column-rule-width: 0;
}

*, *:before, *:after {
  box-sizing: inherit;
  text-align: inherit; vertical-align: inherit;
  border-style: inherit;
  font-family: inherit;
  color: inherit; background-color: inherit;
  border-color: inherit; border-collapse: inherit;
  column-rule-style: inherit;
  column-rule-color: inherit;
  column-rule-width: inherit;
}

  /* Undo damage */
*, *:before, *:after { /* don't inherit */
  padding: 0; margin: 0; border-width: 0;
}
img { vertical-align: baseline; margin-bottom: -.3em; }
pre, code { font-family: monospace; }
highlight { background-color: yellow; }
			
Resetting most common properties.

It's less common now, but browsers often assigned their own default values for many properties. That meant that the same HTML and CSS code would produce a different appearance from one browser to the next. Even if every browser behaved identically though, having to remember (or continually look up) those default values can be bothersome.

One thing many people recommend is to start with a clean sheet by resetting everything to trivial values. These are much easier to remember, and are often what you want to use anyway.

This example illustrates how it works.

Typically, these reset rules would go into your site's top level style sheet, or even into a separate reset.css file of their own.

On the Web, you can find much more complete reset sheets than this example.

Layout

<table>
<tr> <td>19</td><td>3</td><td>6</td><td>8</td><td>11</td><td>14</td><td>17</td><td>19</td><td>3</td><td>6</td> </tr>
<tr> <td>C</td><td>D</td><td>E</td><td>F</td><td>G</td><td>A</td><td>B</td><td>C</td><td>D</td><td>E</td> </tr>
</table>
			

A simple table:

193681114171936
CDEFGABCDE

The same table with <table class="music">:

193681114171936
CDEFGABCDE
An example of possibly abusing style.

I once used CSS to format an HTML table to look like a piano keyboard. (This was to illustrate the correlation between the keyboard and the metatonic cycle of the Hebrew biblical calendar. At the top edge of the keyboard, starting at C, counting white keys and the cracks between keys produces number labels for the white keys: 3, 6, 8, 11, 14, 17, and 19, the year numbers of the leap years within each 19-year cycle.)

If someone's browser's styling had been turned off, the table would have lost its meaning, so using CSS to generate that information went against the general principles of my currently espoused philosophy, though that principle applies much more strongly to JavaScript than to CSS. I'm including it here as an illustration of what can be done using only style rules.

If you enjoy creating visual information using CSS though, see my document on transforms and animation.

???

...

Summary

...