HTML Guide

Lesson 5: CSS

Don't you think that test page is kinda dull, though? It has no colors or anything. How did I make all that cool stuff on my site, anyway? How did I change the font? How did I make that menu work?

Behold the power of CSS. CSS stands for Cascading Style Sheets, and it is basically a set of commands associated with your page that describe how it should look in the user's browser. Remember when I told you to imagine the head element is the bar at the top where it says "HTML guide - CSS", etc.? Well, stylesheets don't like to be seen. Even though they affect things on the page greatly, they're not actually on it - they control it from a distance, or rather from the head.

So basically, put this line somewhere in your head element - I like to put it just below the title:

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

Now you have a <link> element, which refers to the document stylesheet.css, which is a stylesheet of the type text/css. Pretty simple. Technically, you could also make a stylesheet like this:

<style type="text/css">
CSS here
</style>

However, I recommend the other method as it will allow you to change the styling on many pages at once by editing one file, and the stylesheet will be cached in the visitor's browser, which means that the page will load a little quicker once they've visited one page.

Now, open a new Notepad/whatever window, and make a new file there. This one will not be HTML. It will be your page's stylesheet, which is like the great behind-the-scenes magician that turns the dull example page colorful and pretty.

I must introduce CSS a bit first. Why have I completely left out everything related to the looks and presentation of your page up until now? This is because of a concept called "separation of presentation and structure", which basically means that everything in your HTML should be markup, not presentation. This will not only make it a great deal easier to read your code when editing the page, but also enable you to completely alter the whole presentation on your page only by changing the stylesheet applied to it. Look at this page in, say, Axe-Murderer style or Spectrum style, and then again in Voice of the Forest style, and perhaps in something like Bouncy Mew style as well. The page looks completely different, doesn't it? It's all done with pure CSS (and admittedly with a little snippet of Javascript for Internet Explorer 6 to make everything work); the actual HTML of the page, if you view the page source, is almost exactly the same whichever style you're using. This is what you can achieve with separation of presentation and structure. (You may also notice, if you have learned HTML before from older and less W3C-valid sites, the complete absence of elements that define their presentation in my HTML, containing no font tags, etc.). Basically, everything about the presentation of your page should be contained in a stylesheet for easier editing of your layout. All modern browsers support them, and I see no reason why anybody would browse around with stylesheets turned off and still expect to see marvelous presentation, so you'll be fine with leaving the HTML completely without it. Leave that to the CSS, and let the HTML be the structuring language it's meant to be.

The first thing you need to know is that you need to throw away all notions you might have of CSS being something like HTML. You can't compare the two; they're two completely different things that work best when combined, like paint and canvas. CSS has no tags or attributes. The basic syntax of CSS is as follows:

selector {
   property1:value1;
   property2:value2;
   property3:value3;
   [...]
}

For example, let's assume we're going to style all links (which, as you'll hopefully remember, are created with an a element in HTML) so that they will be red without underlines. Then we're going to do it like this:

a {
   color:red;
   text-decoration:none;
}

You need to learn the CSS properties separately, and that is what this page is devoted to. I'll only introduce you to what you'll most commonly be using - when you want to go into more complex techniques, you're on your own. (However, you can contact me to request something specific to be included, as long as it's not something obscure that other people are highly unlikely to use.)

But first you need to learn how you apply style to things. Of course it's simple when it comes to styling stuff like p or li elements in general; you just put p or li as the selector as I did in the example above with the a. Additionally, if you want to select only those elements of a certain type that are children of another element (child elements are elements contained within another element), you put both element names with a space in between them, e.g. li a for links within list items. To select ALL elements, use *; you can also use this to select all child elements of another element, e.g. li * to select all children of list items but not the list items themselves. Additionally, some styling such as font properties is inherited to all child elements - applying some font styling to the body will therefore cause all elements on the page to have that font unless you override it or the element has predefined font properties.

But what if you just have some normal text that you want to apply some styling to, like making it red? What if you want some list items to be different from others?

Inline Styles

The most rudimentary way to specify CSS styling for an individual element is to do it inline. This is basically adding the style attribute to the element and placing CSS inside. For example:

<p style="color:red; font-style:italic;">This paragraph will be red and italic.</p>

However, this has several drawbacks, for example that you can't do anything with the paragraph's child elements this way, besides that it is a basic violation of the principle of separation of presentation and structure, so I don't recommend this unless you absolutely have to.

IDs and Classes

You can give any element an id or class attribute. The main difference between them is that an ID is always unique to only one element, while the same class can be used for as many elements as you like.

The ID selector is #id. Basically, if the ID was, say, "bulbasaur", you'd use #bulbasaur - however, using Pokémon names as IDs is not recommended as it's much easier to edit your stylesheet if the IDs and classes actually indicate what exactly you're styling. Therefore you could use for example "menu" or "content". The class selector is .class (e.g. .bulbasaur), and the same applies to it as to IDs when it comes to naming conventions.

If you want to only select, say, lis with the class red, as opposed to ps with the class red, you can use li.red. Make absolutely sure there is no space between li and .red or it will think you're selecting all elements with the class red that are also children of li elements!

Pseudo-Classes

Pseudo-classes are not as similar to classes as the name seems to imply. Rather than being user-defined, they are pre-defined additions to selectors which basically cause the rule to only apply to the element under certain conditions. As it happens, pseudo-classes are pretty much useless on anything except links due to insufficient browser support (which, as so often in the world of web design, means "Internet Explorer 6 does not support them"). The pseudo-classes you use on links employ conditions which you should already be familiar with in your web browsing experience.

:link
Applies if it is a link (as opposed, I suppose, to a page anchor that people can link to - which can, in addition to the ID way I explained, be done with a elements with no href but a name attribute - although I haven't tested this theory to any degree).
:visited
Applies if it is a visited link, i.e. one that leads to a page in the user's browsing history, but otherwise not.
:hover
Arguably the most useful one; this is the link when the mouse is hovering over it, good for indicating to the user that they're definitely highlighting the right link. Generally, you want links to stand out more when they are hovered over, usually by putting an underline on them if there wasn't one already or by lightening their color.
:active
The link after it has been clicked.

Pseudo-classes are simply tacked onto the element selector, e.g. a:link, a:visited, a:hover and a:active. Note that if one pseudo-class begins to apply, any others it had before apply as well. You can use child selectors with pseudo-classes; a:hover span will for example select any span within a link that is being hovered over, which is at the core of the CSS used for the Featured Section here at The Cave of Dragonflies.

Multiple Selectors

Sometimes you'll want to apply the same CSS rules to more than one set of elements, and that is where you can, instead of copying and pasting, use multiple selectors before the same block of CSS rules. The selectors are then separated by commas. Note that each selector is considered separately; #content a:link, a:visited will not select links and visited links inside #content, but all links within #content and all visited links (even those outside of #content). To achieve the former, you would need to use #content a:link, #content a:visited. This can get annoying with complicated selectors, but there is no better way to do it.

The Generic Elements

Sometimes you want an element just for styling purposes but which has no semantic meaning and should not have any default styling setting it apart from anything else. Therefore, we have the generic inline element span and the generic block-level element div. These do absolutely nothing unless you add some styling to them, except that wrapping a div around some text will cause a line break before and after it, faithful to the definition of a block-level element. You use them just like you would use any other inline or block-level element. If you want to make red text, you can for example use something like this:

<p>This is normal text, but <span class="red">this is red text</span>.</p>

And then in the stylesheet, you would use this:

.red {
color:red;
}

(Admittedly, as I said before, it is a general principle that your class and ID names should describe the meaning of the element rather than the actual styling you plan to apply to it; in this case, if the red is thought of as a way to highlight this particular bit of text, you should name the class .highlight or something in that direction rather than .red, since you might later create another stylesheet and decide there that you'd rather make highlighted text, say, yellow.)

Specificity

This is one of the more complicated and confusing aspects of CSS, but thankfully it is one that you should not have to worry about most of the time. This concerns which CSS rules take precedence over others if the same element is selected by multiple selectors that apply conflicting CSS rules.

To quote the CSS specification:

A selector's specificity is calculated as follows:

  • count 1 if the declaration is from is a 'style' attribute rather than a rule with a selector, 0 otherwise (= a) (In HTML, values of an element's "style" attribute are style sheet rules. These rules have no selectors, so a=1, b=0, c=0, and d=0.)
  • count the number of ID attributes in the selector (= b)
  • count the number of other attributes and pseudo-classes in the selector (= c)
  • count the number of element names and pseudo-elements in the selector (= d)

The specificity is based only on the form of the selector. In particular, a selector of the form "[id=p33]" is counted as an attribute selector (a=0, b=0, c=1, d=0), even if the id attribute is defined as an "ID" in the source document's DTD.

Concatenating the four numbers a-b-c-d (in a number system with a large base) gives the specificity.

[Don't mind the unfamiliar "attribute selectors" and "pseudo-elements"; I left them out for not having enough browser support to be of much use.]

If two rules are equally specific, the latter rule takes precedence.

It is confusing to think too much about specificity. Usually it will do just to keep it at the back of your mind, and when a CSS rule doesn't appear to be taking effect, see what happens if you add the ID of a containing element to the front of the selector or something like that.

Now I'm just going to run through the basic properties you're going to need and use frequently in styling.

Styling Text

If you apply these properties to an element, all text within said element will be affected. If the element contains no text, nothing will happen.

color
Makes all text inside the element a specified color. Value can be a color name - for some colors - or a hexadecimal color code (covered later).
font-family
Changes the font of the text. Value can be a font name (such as verdana or arial; if the font name is many words, such as "times new roman", it should be enclosed in quotation marks) or a generic font family - serif, sans-serif, monospace, cursive or fantasy. The test page will give you an example of what they all look like; they are basically classes of fonts that share similar traits, which will ensure that if your reader for example doesn't have the right cursive font installed, they will see another cursive font rather than just their default font, etc. You should specify the ideal font first, and then one or more alternatives for computers that don't have that font installed, separated by commas. It will basically go from the first font in the list and then onwards until it finds a font it has; therefore, the last font you specify should always be a generic font family.
font-size
Specifies the font size of the element. Value can be an actual font size followed by a unit or a relative font size:
  • 10px - ten pixels (you are generally advised not to specify font sizes in pixels, since this could make fonts appear too big or too small on other resolutions)
  • 10pt - ten points
  • 2em - twice the inherited or default font size
  • 200% - 200% of the font size that it would be if no size was specified
  • medium - the default font size
  • small/large - small/large
  • x-small/x-large - extra-small/large
  • xx-small/xx-large - extra-extra-small/large
  • larger/smaller - larger/smaller than the inherited or default font size
text-transform
Values can be uppercase, lowercase or capitalize. Uppercase puts the letters all in upper case, lowercase puts them all in lower case, and capitalize capitalizes the first letter of each word.
text-align
Aligns the text inside the element - the value can be left, right, center or justify. Should be self-explanatory.
text-indent
The indentation of the text, specified in a length of px or em.
font-variant
Can be normal or small-caps. Self-explanatory.
font-style
Use italic to make the text italic; use normal to make it normal.
font-weight
Use bold to make it bold and normal to make it normal.
text-decoration
Values can be underline, overline, line-through or none; if you want for example both an underline and an overline, put them both with a space in between. It should be noted that underlines should mostly be reserved for links; when users see underlines, they expect them to be links and might attempt to click on them, so for clarity of presentation, use them sparingly.
letter-spacing
The spacing between the letters; can be specified as normal or a length given in px or em. normal will make the browser decide it for itself (meaning it can increment it to allow for justified text alignment, for example); setting it to 0, on the other hand, will force the spacing between the letters to be as ordinarily defined by the font itself. The value can be negative.
word-spacing
Exactly the same as letter-spacing, except it refers to the spacing between words, not between individual letters.

Backgrounds

These can be used to apply a background to any element.

background-color
Applies a solid background color. Value can be a color name - for some colors - a hexadecimal color code (covered later) or transparent.
background-image
Gives the element a background image. Value should be url('image.ext'), where image.ext should be the path to the background image; for example, if I wanted an image called background.gif inside a folder called images on some element, I'd use background-image:url('images/background.gif'). Note that in an external stylesheet, the image path should be relative to the folder the stylesheet is in.
background-attachment
Value can be scroll or fixed. The default is scroll, but if it is fixed, the background image will stay in place if the text is scrolled down. Because Internet Explorer 6 renders this fixed effect incorrectly on everything but the body, I recommend not using it on anything else unless you know what you're doing.
background-repeat
Determines whether the background image should repeat. Value can be repeat, which is the default and makes it repeat until it covers the whole background of the element; no-repeat, which causes it only to appear once at the specified background-position; repeat-x, which will cause it to repeat horizontally but not vertically; and repeat-y, which will make it repeat vertically but not horizontally.
background-position
Positions the background image - mainly useful when the background-repeat is set to repeat-x, repeat-y or no-repeat. Value should be two keys for the vertical and horizontal positioning, which can be percentages, absolute values or keywords - top, bottom, left, right and center. The defined point in the element the background image is applied to is then lined up with a corresponding point in the image - meaning that if you put center center, the image's center point will be put right where the element's center point is, making it look properly centered.
background
A property that basically combines those - you could for example use background:url('dpsprites/001bulbasaur.png') #FFFFFF fixed top left no-repeat;.

Positioning, Dimensions, Padding, Borders and Overflow

position
Determines how the position of the element should be calculated. The default value is static, which makes the element stay where it should be in the normal document flow. Then there is relative, which allows you to shift the element up/right/down/left from where it would otherwise be, and absolute, which will position it in relation to a positioned element that it is contained by - if you want to absolutely position an element but don't want to move the containing element anywhere, just give the containing element relative as its position. fixed also exists, but as Internet Explorer 6 does not support it, I will not detail its usage here.
left, right, top and bottom
Value can be given in px, em or %. If the element has position:relative, it will shift the element by that distance away from the direction denoted by the property used; if it has position:absolute, it will be positioned this distance away from the respective edge of the container that it is being positioned relative to.
width
Specifies the width of the element. The default value is auto, which will for a block-level element basically make it take up all the available horizontal space, or for an inline element make it take up exactly the space that it needs and no more. It can also be a value specified in px, em or % (of the containing element). Internet Explorer has an annoying thing for expanding elements past their specified width if their content is too large to fit into them, but this is incorrect behaviour. See overflow for the solution.
height
Specifies the height of the element, and the default value is auto like for width; however, here auto means taking up no more space than necessary in both inline and block-level elements. Like width, it can also be specified in px, em or % (relative to the containing element), and Internet Explorer also loves to ignore your specified height if the content is too big for it.
margin
Split into margin-top, margin-right, margin-bottom and margin-left, but you may just want to specify it all in one by giving the margin property four values specifying, in order, the top, right, bottom and left margin, with spaces in between. You can also give it two values, for which the former will apply to the top and bottom and the latter to the left and right, three values, for which the second value applies to both the left and right margins, or one value, for which all four margins will be the same size. margin basically puts margins on the sides of an element, pushing it away from the other elements on the page. The value can be given in px, em or % (which then refers to percentages of the containing element), or alternatively as auto, which will make the browser calculate a margin according to the width of the element and the opposite margin if any. This is useful mainly because it means that if you have an element and specify a width on it, you can center it by putting the left and right margins to auto - a trick which, unfortunately, apparently does not work in Internet Explorer 5.x. (This can be easily solved by also giving the containing element text-align:center and then negating it on the child, since as it happens Internet Explorer 5.x also incorrectly made the text-align property apply to the position of child elements as well.)
padding
Like margin, padding is technically shorthand for the top, right, bottom and left paddings. It is used almost exactly like margin, with one important exception: paddings are actually "inside" the element. That is, if you have margins on an element which, say, has a red background color, the red color will only reach as far as the contents of the element, and the margins will be transparent. However, if you have paddings on the element, it will leave a red space as wide as the padding you specify on the sides of the element. Unlike margins, paddings also can not be specified in percentages or as auto. One important thing to note about padding is that in the most infamous Internet Explorer bug of all time, it used to use a different box model than the W3C standard. That is, while the paddings are supposed to go outside the specified width or height, Internet Explorer would put the padding inside the dimensions, so that if you for example had an element with a width and height of 100px and gave it 10px paddings on all sides, the content would have only an 80x80 area in the middle of the element in Internet Explorer while it was supposed to have the full 100x100 area with the 10px paddings added outside that. While it can be argued that Internet Explorer's box model makes more sense than the W3C one, going against the web standards in this way caused headaches for web developers for years. In Internet Explorer 6 and 7, the standard box model is used if you have a strict doctype (which you do, if you followed all my instructions). Keep this in mind when making your layouts.
border
Rather self-explanatorily, this adds a border to the element, which is placed between the padding and margin (if any). This is shorthand for border-width, border-style and border-color, and like with the other shorthand properties, you just specify them in that order with a space between them. For example, a black, solid 1px border would be specified as border:1px solid black (or border:1px solid #000000). The width and color are self-explanatory; the style can be none, dotted, dashed, solid, double, groove, ridge, inset or outset. To specify only one of the four borders, use border-top, border-right, border-bottom or border-left. (The border-width property is technically shorthand as well; you can specify four individual values for the four borders, using it like how you would specify padding or margin.) The borders were also a problem in the Internet Explorer box model, as like with the paddings, Internet Explorer's rendering engine rendered the borders inside the specified width of the element.
overflow
Specifies what should be done with the element if the content in it exceeds the specified width or height. The default value is visible, which in standards-compliant browsers means that the content will simply flow out of the element. Internet Explorer, on the other hand, will, as noted above, expand the element and if this value is used and possibly break layouts in the process. overflow:hidden will solve this problem; with this property, the element will mercilessly cut off any of its contents that happen to be too large for it right where the element ends, and this will indeed work in Internet Explorer, solving the expansion problem. It can also take the values scroll and auto; scroll will put scrollbars on the element, while auto will put scrollbars on it if and only if the element's contents are indeed too large for it.

Floating

float
float is a property originally designed for easier implementation of images into text. Instead of having images take up a lot of vertical space, how about allowing the text to flow around the image? What the float property does is to take an element and make it "float" to the left or right side of its containing element - depending on whether the value of float is set to left or right - while allowing any text that would have been placed at its new location to wrap neatly around it. This may be a little hard to explain just like this, so see the example page. Floating is also often used in layouts. More on that later.
clear
The clear property basically makes it so that this element will not be wrapped around a float, but be pushed below it (along with all subsequent elements). The value can be left, right or both, depending on which side's floats should be cleared. Also see the example page for a demonstration of how this works.

List Styling

(The following, rather obviously, only apply to ordered or unordered lists)

list-style-type
Defines how the list items should be marked. Values include, for unordered lists, disc, circle and square, and for ordered lists, decimal for ordinary numerals, decimal-leading-zero for ordinary numerals with leading zeroes that make each number equally many digits, lower-roman for lowercase Roman numerals, upper-roman for uppercase Roman numerals, lower-alpha for lowercase Latin characters, and upper-alpha for uppercase Latin characters. It can also be none, which will cause there to be no markers at all.
list-style-image
If defined, it overrides the list-style-type by causing the bullets in the list to consist of an image instead; the image is written like a background image, i.e. list-style-image:url('image.ext').
list-style-position
Defines whether the list marker should be positioned inside or outside the list item itself (i.e. whether a border around the list item would include or exclude the marker; if it's inside, it will act pretty much like if you had just put the image inside the list item manually).

Display and Visibility

display
Controls how the element should be displayed. The primarily useful possible values are inline, block and none; elements have different default values for this depending on whether they are inline elements or block-level elements (there are also a couple of other types, but the distinction is not that important). This allows you to make an inline element act as a block-level element or vice versa, but it also allows you to remove an element from the page altogether with display:none. More on practical uses of this later.
visibility
Value can be visible or hidden. visible is the default; hidden will hide the element from view while still keeping it there, in the sense that it takes up space on the page.

Phew, that's enough CSS for now, isn't it? Lastly, we'll just have a quickie on...

Hexadecimal Color Codes

While some colors can be specified in CSS as words, you sometimes want absolute control over the colors displayed on the viewer's screen. This is of course possible, and it is done using the hexadecimal color code system, or hex codes for short.

In paint programs, you may have seen weird values going from 0 to 255 labelled with R, G and B. Well, those stand for red, green and blue, and they are the primary colors of light - which means you can make any color by combining them in different amounts. What the numbers do is add more of the respective primary color into the blended result - and remember that we're talking about light, so more of the color is more light. Thus, 0 for all three colors yields black, and 255 for all colors yields white. And colored lights do not blend in the same way as paint, so while you will have learned that blue and yellow make green, this is not true here - as you may have noticed, yellow is not even a primary color. How do you get yellow, then? By mixing red and green! It sounds odd at first, but you will get hang of it. And thus, orange is gotten by having more red than green in that mix, and so on.

The way the hexadecimal system works is that the three numbers for red, green and blue are written in hexadecimal - base sixteen rather than base ten as our ordinary numbers. This means that instead of having ten numbers (0, 1, 2, 3, 4, 5, 6, 7, 8 and 9), we have sixteen, with the ordinary decimal digits and then the last six being arbitrarily titled A, B, C, D, E and F. Otherwise it works exactly like the decimal system - you count 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, 10, 11, and so on. 10 in hexadecimal thus actually "means" 16, 11 means 17, and so on. The numbers go on like that until FF, which is 255 - the highest number that can be written with only two digits in hexadecimal. This is also the highest number that the primary color values can go up to.

So once we have the hexadecimal equivalent of each primary color number, we simply add a zero in front of any single-digit numbers and then stick them together and put a # in front. 255 R, 255 G, 255 B becomes #FFFFFF. 32 R, 80 G, 0 B becomes #205000.

To get hang of the hex codes, it is best to just experiment, and for that purpose I have prepared a little script. Enter a hexadecimal color value in the input field and press the button to make the background color of the box below change to your specified color.


 

It may seem awkward at first, but I assure you that as you get used to using hex codes, you will find that they seem to flow from your fingers without effort, producing just about the color you want in just a few tries. I never use the color keywords, just because I feel more comfortable with typing out the hex codes.

Lastly, I would like to point out, just for when you've been making a graphic for your website and then want the background color on the page to be the same or something, or if you like to use a paint program's color selection menu rather than manually guess at the hex codes for the color you want, that in most paint programs, the hexadecimal color code for the selected color is displayed somewhere in the color selection menu, or at least the plain RGB values which you can then convert to hexadecimal.

Now, in conclusion, to see what we've learned in this section (quite a lot, isn't it?) in action, take a look at the new, spiffified example page, which also contains additional explanations and tutoring - it is highly recommended you take a good look.

Previous lesson - Next lesson

Page last modified April 11 2023 at 23:29 UTC