teaching machines

CS 268: Lecture 3 – Hello, CSS

February 11, 2020 by . Filed under lectures, spring-2020, webdev.

Dear students:

If the purpose of modern HTML is to give structure but not presentation to our information, how do we specify its presentation? We will answer that question today. We’ll look at some of the common visual properties that we can adjust and describe how we can apply them to certain substructures. By the end, we’ll be able to apply styling to produce a page that looks like this:

But first, let’s complete a little refresher exercise.


With exactly one neighbor, claim your task on Crowdsource. Then complete the task below. When you are done, submit your solution on Crowdsource.

  1. Write an HTML page that shows a top 10 list of some category of things. Place the winner last.
  2. Write an HTML page that shows a list of album covers for a musician of your choosing.
  3. Write an HTML page that shows a list of quotations.


HTML imposes a structure on our information. Each tag is like a sticker on a moving box, describing what’s inside. But those labels don’t say how the box should be unpacked and displayed on our shelves, mantle pieces, and refrigerator doors. For that, we must apply styling.


The standard language of stylesheets is called Cascading Stylesheets (CSS), which were invented by Håkon Wium Lie in the 1990s. Lie was a colleague of Tim Berners-Lee at CERN when various styling standards were being debated.

Many of the existing standards drew style rules from a single stylesheet, but Lie proposed a new standard that allowed multiple stylesheets from multiple origins to be blended together. The origins included the browser, the author of a page, and the user visiting the page. Each origin had a degree of importance. Rules from the least important source cascaded down to a more important source. The more important source could either override the styles or let them cascade further. Thus CSS was born.

In 2005, Lie openly challenged Microsoft to make Internet Explorer standards-compliant and initiated development of a test site called Acid2 that would show how poorly the newly released Internet Explorer 7 conformed to web standards. Not until Internet Explorer 8 did Microsoft pass the test. Acid2 and its brethren have since become a benchmark for all web browsers.

Lie went on to join Opera as its chief technology officer. Opera doesn’t have and has never had a huge market share, but Lie preferred to go work for a company that was more concerned about web standards and software quality, saying:

I joined Opera when I saw that Opera was able to implement as much of CSS in three months as Netscape and Microsoft could in three years.


[Opera] didn’t have enough people to make it bloated.

Lie was also a founding member of the Norwegian Pirate Party. The Pirate Party, which is more prevalent in Europe than the United States, was initially founded to battle restrictive copyright laws. He summarizes his position as follows:

My political manifesto can be summed up as: Global information, local production! That is, one should freely exchange bits of information at a global level, but atoms (including food, furniture, and people) are much harder to transport and there are natural restrictions. Rather than packaging and transporting stuff, spare parts can be printed locally and fish should be programmed to swim to their destination. You should know the name of the person who made your shoes.

Some of that seems to have gotten lost in translation. See Why Opera isn’t planning to go open source and Lie’s website for more history.


There are three places that we can declare the style of our HTML elements.

  1. In an element’s style attribute:
    <element style="...">
    But this just bakes the presentation into the information structure like in the earlier days of HTML, cluttering the HTML and making the styling impossible to reuse. Avoid the style attribute if possible. (I sometimes use style in programmatically-generated HTML to avoid the headache of providing a separate stylesheet.)
  2. In an inline stylesheet declared in head, like this:
    Though the HTML and presentation are separate with this approach, they are still tightly coupled by being in the same file. You can’t apply the styles to another HTML page.
  3. In an external stylesheet linked in head. The link tag is what we use to declare links to external resources, including favicons and stylesheets. Use it as follows:
      <link rel="stylesheet" href="path/to/stylesheet.css">
    This is the child of Goldilocks and Baby Bear. The stylesheet is logically separated and can be included in many HTML pages. Favor this approach.

We now turn to what goes in these stylesheets.


Let’s start with these two common color properties:

color: green;           /* foreground color */
background-color: red;  /* background color */

But we don’t assign these colors to the whole document at once. We assign it only to pieces of the document using a selector. For example, we can set the color of p elements with this selector and rules:

p {
  color: rgb(0, 255, 0);
  background-color: #FF0000;

Any text that’s not in a p tag won’t be colored by these rules. If we want to apply the rules to more of the text, we can target at element higher in the information tree, like body.

body {
  color: rgb(0, 255, 0);
  background-color: #FF0000;

The rules for body will cascade down the tree. We can override them with the p selector.


We can also change the type itself with these various font- properties:

/* See https://developer.mozilla.org/en-US/docs/Web/CSS/font-family. */
font-family: 'Palatino' | serif | sans-serif | monospace | fantasy | cursive | system-ui;
font-size: 12pt | 150%;
font-weight: normal | bold | 100 | 200 | ... | 900 | ...;
font-variant: normal | small-caps;
font-style: normal | italic;

The font-family can take on the name of a specific or generic font family. Listing a generic family tells the browser to pick a font availble on the system that represents the specified class. Listing a specific family requires that the font be available. Thanks to Lie, it is possible to include the font and have the browser automatically download it. For instance, say we want to use the Roboto font. We include this link tag in head:

<link href="https://fonts.googleapis.com/css?family=Roboto&display=swap" rel="stylesheet">

And we specify this style rule:

p {
  font-family: 'Roboto', sans-serif;

If we use a comma-separated list of families, we’ll fall back to the next family in the list if an earlier family isn’t available—perhaps because a font provider’s site is down or because there’s no internet connection on the client.

Text Decoration

There are three properties that we can set to decorate text with lines.

text-decoration-line: overline | underline | line-through;
text-decoration-color: red;
text-decoration-style: solid | double | dotted | dashed | wavy;

I mention these not because we use them often, but because this collection of three properties can be condensed into a single property of this form:

text-decoration: line-through wavy white;

CSS has many such shorthand properties. The order of the values is generally not important. The parser can figure out what is meant as long as the values for each property are unique. When two or more properties share values, then an order is imposed. See MDN for more details.


Some elements, like img, can have their dimensions set with the width and height properties, like so:

height: 1024px;
width: 50%;

Various units are supported.

Most inline elements don’t support this property. For instance, you can’t set with the width and height of an a element. Images are inline elements by default (in the browsers I’ve checked), but they are given special treatment. We can set their dimensions like so:

img {
  width: 200px;
  height: 100px;

But please don’t specify both width and height unless your image is nothing but a solid color. If you set both, you risk violating the image’s aspect ratio and thereby distorting its content.

To say that you want an image filling 50% of the horizontal span, you’d say this:

img {
  width: 50%;

Likewise, here’s how we’d say that you want the image to fill 50% of the vertical span:

img {
  height: 50%;

But this doesn’t always work. The % unit refers to the parent element’s dimensions. If the image is inside an element whose height is unspecified, the height value will revert to auto.

If you want it to fill 50% of the viewport, you can use 50vh instead of 50%.


To surround our content with lines, we can use the various border- properties.

border-width: thin | medium | thick | <LENGTH>;
border-style: solid | dotted | dashed | double | groove | inset | outset;
border-color: black;

There’s also this shorthand property:

border: 1px solid black;


Generally, any sequence of spaces, tabs, and linebreaks in the content is collapsed into a single space character. The browser may wrap the content at this consolidated space. For prose, this is reasonable behavior. For poetry and code, this is not reasonable. Whitespace is significant.

One might be tempted to include <br> to insert significant linebreaks. But <br> is really a presentational element that has somehow evaded the firing line. There’s also the HTML entity &nbsp;, but this too can be avoided by using styles.

To alter how whitespace is interpreted, we use the white-space property, which has these values:

white-space: normal | pre | nowrap | pre-line | pre-wrap;

The behaviors of these values vary across two dimensions: whitespace preservation and wrapping. Let’s decompose this behavior space into a 2D table and plot the values:

wraps doesn’t wrap
collapses whitespace normal nowrap
preserves all whitespace pre-wrap pre
preserves only linebreaks pre-line

IDs and Classes

When we use element names in our selectors, the style rules get applied to all instances of that element. Sometimes we only want to apply a set of styles to one or a subset of instances.

To target a single element, we can give it an id attribute, like so:

<p id="closing">...</p>

We can then apply rules to this ID in our stylesheet like so:

#closing {
  font-style: italic;

IDs are supposed to be unique across a page.

If we have a subset of elements that we wish to style, we can use the class attribute, like so:

<p class="struck">...</p>

We can then apply rules to all instances of this class in our stylesheet like so:

.struck {
  text-decoration: line-through;

Div and Span

Sometimes we found ourselves needing an element not for giving structure but for the sole purpose of applying styles to it. In modern HTML, we have div and span for this purpose. div is by default a block element, and span an inline element. Beyond that, they are semantically neutral.

For example, we can strike out a single phrase from a paragraph by embedding it in a span with the struck class:

I <span class="struck">love</span> like you.


Now let’s put all these ideas together as we reverse engineer and recreate this page:

We’ll build off of this raw text:

Back to C
December 17, 2019

It is the first day of winter break. My mother encouraged me to keep my brain from wasting away and handed me this book on the C programming language that she used in college:


I read the book cover to cover. All one needed back in the day was to install a compiler. Mom had it easy. She'd freak out if I showed her <code>node_modules</code>. Perhaps someday computing will be simple again. But I think there's a law somewhere that says technological complexity will only increase.

Once I finished, I wrote my first C program. Here it is:

#include <stdio.h>

int main(int argc, char **argv) {
  printf("Hello, world!\n");

I will never write another. Here's to a lifetime of learning!


Here’s your TODO list for next time:

See you next time.


P.S. It’s time for a haiku!

To make users smile
You need both structure and style
Not in the same file