A CSS Primer for 2024

Let’s start with a huge caveat: CSS is a huge beast and can present many, many complicated features that are used to make the amazingly designed sites you see around the net. 

We are not planning to go that deep. This is just a primer to get you started.

What do you need?

Ok, First! Go get that html file you made on the first tutorial. We’re going to improve its looks.

You’ll need a text editor, as before. If you don’t already have a favorite one, here’s what comes with your OS: 

  • Windows, notepad.exe
  • MacOS, TextEdit
  • Linux, too many options, look for Kate or GEdit to start.

macOS and TextEdit

TextEdit really wants to save things as formatted files, like MS Word, so you have to tell it what you want to do. 

  • Open up TextEdit, make a new document.
  • Go to FORMAT -> Make Plain Text

Now, when you save your file the first time it will pop up a message about your file extension, saying:

You have used the extension “.html” at the end of the name. The standard extension is “.txt”. 

Click “Use .html”

From here it should work just fine.

STYLE me!

Open your HTML page from the previous primer in your text editor. It should look something like this (but with your favorite animals, not mine)

<!DOCTYPE html>
<html>

<head>
    <title>My Webpage</title>
</head>

<body>
<div>
    <h1>Hello World!</h1>

    <p>This is my first webpage, there are many like it but this one is mine.</p>

    <p>This is a paragraph, full of words. The paragraph will continue until the p tag closes it, like this.</p>

    <p>Here is a new paragraph. Here       Are some     Words
Even a few line breaks. Some.          Space
Here.</p>   

    <h2>Furthermore</h2>

    <p>Some pages have many headings</p>
    <p>Some headings have many subheadings</p>

    <h2>However</h2>

    <p>Not all do.</p>
</div>

<div>
    <h1>The Plan</h1>

    <ol>
        <li>Learn how to make HTML lists
        <li>Make a list of my favorite animals
        <li>Save my webpage and show it to everyone
    </ol>

    <h1>My Favorite Animals</h1>

    <ul>
        <li>Elephants
        <li>Corgis
        <li>Alpaca
    </ul>
    <p>Learn more about <a href="https://en.wikipedia.org/wiki/Elephant">Elephants on Wikipedia!</a></p>
</div>

<footer>
    <p><a href="about.html">About My Webpage</a></p>
</footer>

</body>
</html>

At the top, we are going to add a STYLE tag to the HEAD. All of the CSS we write is going to live in there. 

<head>
    <title>My Webpage</title>
    <style>
    
    </style>
</head>

CSS can be linked to the document in three ways: by the tag, by a class, or by an identifier. Let’s start with the tag. 

Tag me in!

Let’s change the font size of all the paragraphs in our webpage. First we have to tell CSS what we are modifying, in this case the P tag. Then, in parenthesis, we are going to put the changes we want. 

<style>

p {
    font-size: 18px;
}

</style>

If you hit refresh, you’ll see a change! All of the letters in paragraphs should have gotten bigger, but not the headers or the lists. 

Let’s note a few things. First there is a semi-colon at the end of the ‘font-size…’ line. This is important! The semi-colon acts like a period at the end of the sentence, and tells the browser to stop. Forgetting a semi-colon is a common problem, and should be one of the first things you should check if things aren’t going right. 

Ok, great! We changed the paragraphs! Let’s change the headings as well. Let’s make all the H tags into mono-space fonts. 

<style>

p {
    font-size: 18px;
}

h1, h2 {
    font-family: monospace;
}

</style>

For this one, you’ll notice I listed the tags together. By putting the H1 and H2 tag on the same line separated by a comma (that comma is important!), it says to apply these styles to both the H1 and H2 tags. Makes it easier if you have tags or classes that share styles.

Hit refresh! Typewriter headers are in! 

Classy changes

When you use just the tag, like we have been doing, ALL of the tagged things change. So all of the paragraphs, all of the headers, etc. But sometimes, that’s not what you want to happen. Sometimes you just want some of the things to change, some specific things. 

So let’s make a class and see what happens. 

<style>
p {
    font-size: 18px;
}

h1, h2 {
    font-family: monospace;
}

.animals {
        color: purple;
}

</style>

First thing to notice is that there is a period at the start of the word “animals.” This is important! The period is what tells CSS that this is a class. 

Now, how do we add this to our site? Let’s make one of our headers purple. Go to your favorite animal list and update the H tag like this:

<h1 class="animals">My Favorite Animals</h1>

And refresh. Purple! Some thing to point out here is that the class “animal” does NOT have a period in front of it here. Period in the CSS, no period in the HTML. 

Or, say you want a different color! There are lots of named ones you can choose from. Check out the list of named colors here.

(you can use hex code to be very specific about color, but we are keeping this simple for this tutorial)

The reason we named it animal is for us, the person. The classname can help tell you what it is for, or what it does, making it easier to use in larger websites. 

Now that you have classes, you can designate some styling to some paragraphs, different styling to others. You can add multiple classes on one tag, so you can have many ways to organize your styles.

ID Selector

The ID attribute of a CSS tag. 

The ID is unique on the page, so you can only use it once. If you take a book as an example, you may have many headings on a page, but only one Chapter heading per chapter. And only one Title per book! 

So let’s give our page a title ID tag. 

<h1 id="title">Hello World!</h1>

And then we style that, by using the # in front of the selector, like this: 

<style>
p {
    font-size: 18px;
}

h1, h2 {
    font-family: monospace;
}

.animals {
    color: purple;
}

#title {
    color: red;
}

</style>

When you hit refresh, your title is now red! 

ID selectors are unique on a page for a reason. They can be used for on page navigation, they can be linked in with Javascript to update or transform based on user input. While it may not seem useful at the moment, it will become so once your page become more complicated. 

SPACES Again!

Class and ID names in CSS cannot have spaces in them. If you do something like this, for example:

<h1 class="purple header">My Favorite Animals</h1>

You do not have one class named purple header, but instead, two classes, one purple, the other header

Some people will use what is called camel case, which is where you simply capitalize the first letter of each word, so in this case it would be purpleHeader

Others use underscores or hyphens, purple_header or purple-header. Still some do nothing at all, just simply purpleheader

These names are for you, so make them so you understand them.

Hierarchy

These three things, the tag, the class and the ID have a hierarchy amongst themselves. The ID will be on top, followed by the class and then the tag. Let’s see what that means. 

Let’s add an H1 style for color to our code: 

<style>
p {
    font-size: 18px;
}

h1, h2 {
    font-family: monospace;
}

h1 {
    color: green;
}

.animals {
    color: purple;
}

#title {
    color: red;
}

</style>

Now if you hit refresh, after you save, only one of your H1 tags should be green, the one that says “The Plan”. The first one, “Hello World” stays red, as it has an ID, and the last one, “My Favorite Animals” stays purple, as it has a class. 

But what happens if we add the class of animals to the H1 tag that has an ID? Let’s see:

<h1 id="title" class="animals">Hello World!</h1>

Now save, refresh and… nothing. No change. Because the ID, which says to make the color red is higher priority than the class that says it is purple. 

Sharp Dressed HTML

Ok, let’s start cleaning up our page for real. Here are the things we are going to do. 

  1. Change the font size
  2. Change the line spacing of the paragraphs
  3. Make some snazzy font choices

We are going to use the BODY tag for these styles so that everything in the body will be affected by them. Think of this as setting the default styles for the page. So first, let’s delete everything in our style tags and start over like this:

<style>
body {
    line-height: 1.5;
    font-size: 18px;
    font-family: Baskerville, Georgia, serif;
}
</style>

Hit refresh and boom! Isn’t that much nicer? 

Let’s see what each does. 

  • line-height is the space between lines, similar to how you space lines in Word.
  • font-size is how large your font is. Unlike Word, where text sits comfortable at 12pt, web on the text needs to be larger, 16 or 18 is your comfort zone most of the time. The px stands for ‘pixels’ and is one of the ways to do font sizes.
  • font-family is what font you want. Now you can put any font here, but it will only work if that font is installed on the viewer’s device. So the line lets you do fall backs.
  • Baskerville, Georgia, serif; What this says is first try the font Baskerville, if that isn’t installed on the viewer’s device, then try Georga, if that isn’t installed… etc, until the end where it simply says serif, meaning ‘use whatever the default serif font the browser wants.’

Fonts and font stacks can get complicated quickly. You can link to fonts and get fancier ones even if they aren’t installed on the viewer’s computer. You need to pick fonts that pair well together, that match your design, that are easy to read at various sizes. Whew. 

For now, we are just going to stick with some simple choices. 

Ok, let’s do the same to our headings. We want to do all of them the same, so we are going to group them together, and let’s add back in our animals class from before, like this:

<style>
body {
    line-height: 1.5;
    font-size: 18px;
    font-family: sans-serif;
}

h1, h2 {
    font-family: Arial, Helvetica, sans-serif;
}

.animals {
    color: purple;
}
</style>

Hit refresh and we are starting to look respectable! 

Not Least, but Last

The footer of your site usually has some styling to set it apart. So let’s do that for our footer, adding in a light grey color and smaller fonts

<style>
body {
    line-height: 1.5;
    font-size: 18px;
    font-family: sans-serif;
}

h1, h2 {
    font-family: Arial, Helvetica, sans-serif;
}

.animals {
    color: purple;
}

footer {
    font-size:14px;
    background-color: lightgray;
}
</style>

Reflowable Rearrangable

HTML is reflowable. That means if you resized your browser window, that the words will shift around to adjust for the new size of the window. This means as you are designing your page, you should keep that in mind. Some people are going to see your page on their 27 inch monitor. Some are going to see it on their phone. 

Let’s add some to our HTML to get a good look at what we mean. Here are the opening paragraphs to Alice in Wonderland, let’s add them in after our list of animals, but before the FOOTER tag:

<div>

<h1>Alice in Wonderland</h1>

<p>Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, "and what is the use of a book," thought Alice, "without pictures or conversations?"</p>

<p>So she was considering in her own mind, (as well as she could, for the hot day made her feel very sleepy and stupid,) whether the pleasure of making a daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly a white rabbit with pink eyes ran close by her.</p>

<p>There was nothing so very remarkable in that; nor did Alice think it so very much out of the way to hear the Rabbit say to itself, "Oh dear! Oh dear! I shall be too late!" (when she thought it over afterwards, it occurred to her that she ought to have wondered at this, but at the time it all seemed quite natural;) but when the Rabbit actually took a watch out of its waistcoat-pocket, and looked at it, and then hurried on, Alice started to her feet, for it flashed across her mind that she had never before seen a rabbit with either a waistcoat-pocket, or a watch to take out of it, and, burning with curiosity, she ran across the field after it, and was just in time to see it pop down a large rabbit-hole under the hedge.</p>

<p>In another moment down went Alice after it, never once considering how in the world she was to get out again.</p>

<p><a href="https://en.wikisource.org/wiki/Alice%27s_Adventures_in_Wonderland_(1866)">Read Alice in Wonderland</a></p>

</div> 

Now, if you refresh your webpage you’ll see these first paragraphs near the bottom. What you should take notice of is that they stretch all the way to the end of the browser window before going to the next line. 

If you resize your window, you’ll see that they reshape themselves based on how wide the window is. This is good to some degree because that means the text you have will conform to the window it is viewed in. 

It is not good in a way because reading a line that goes from one side of your monitor to the other is not easy. Go give it a try. 

Books don’t do this, they have a set line length (caused by the page size and margins), and that length is picked to be easy to read. We are going to do the same with our page and some CSS.

So we are going to add a maximum width to the BODY tag. What this will do is prevent the text from stretching out forever, instead make a reasonable line length that is easier to read. 

It is a maximum, rather than fixed width, so that if someone looks at it on their phone, it will shrink down in size. 

body {
    line-height: 1.5;
    font-size: 18px;
    font-family: baskerville, Georgia, serif;
    max-width:650px;
}

Now, if you refresh your page, it will be much easier to read the opening to Alice in Wonderland. AND, if you resize your window, you’ll see that it will still resize if you make it smaller than it is, but when you make it larger, that maximum width value stops the lines from growing. 

Shortcuts

I want to talk about CSS shorthand propeties.

Let’s take a look at two bits of CSS code. 

First: 

line-height: 1.6;
font-size: 18px;
font-family: baskerville, Georgia, serif;

And Second: 

font: 18px/1.6 baskerville, Georgia, serif;

These two bits do the exact same thing. The border attribute has a similar shortcut as well with its components. 

The shorten version may save space, may make your file smaller, but the best practice for you when you are writing code, especially code for yourself, is to write it so you understand it. 

So if the line by line first version works best for you, then keep it. Don’t feel like you need to forsake readability at this stage. 

Portabile Styles!

Having these styles in the HEAD of your HTML page is fine if you are only going to have one page on your site… but let’s face it, most webpages are more than that. If you copy/pasted the code on the top of all your HTML pages it would work… and it would be a mess to try to change if you decided that purple wasn’t really your color anymore. 

So, let’s move those styles out into their own file. Make a new file in your notepad.exe called style.cssand save it to the same folder your mypage.html is in. 

Copy all the styles you made, but NOT the STYLE tags, and paste them in this file, so it looks like this: 

body {
    line-height: 1.5;
    font-size: 18px;
    font-family: Baskerville, Georgia, serif;
    max-width:650px;
}

h1, h2 {
    font-family: Arial, Helvetica, sans-serif;
}

.animals {
    color: purple;
}

footer {
    font-size:14px;
    background-color: lightgray;
}

Comments in CSS are bracketed by /* and */ markers, so let’s just add a comment to the top like this. Like HTML comments, line breaks are ok! 

/* This is a style sheet for my website! */

/* 

This is a multi-line comment, everyting inside of the markers is ignored. 

Often you'll see comments like this at the top with information on the author of the website, its URL, and license. 

*/

/* overall website typogrpahy */
body {
    line-height: 1.5;
    font-size: 18px;
    font-family: Baskerville, Georgia, serif;
    max-width:650px;
}

/* sans-serif fonts for the Headers */
h1, h2 {
    font-family: Arial, Helvetica, sans-serif;
}

/* I like purple, ok? */
.animals {
    color: purple;
}

/* Footer styles */
footer {
    font-size:14px;
    background-color: lightgray;
}

Hit save. 

I add comments into my code everywhere, like ‘notes to Jake’ about what something is or does so that in the future I can more easily remember what it was past Jake was doing. 

Because let me tell you, that guy sometimes doesn’t know what he’s doing. 

Link it to me!

But, we aren’t done yet. We have to tell the HTML page where those styles are. We are gong to do that with a LINK tag in the header. So, first delete the STYLE tags and everything inside of them all together. 

Then we will add a LINK, which similar to the A tag, will have an HREF property. it will also have a REL property, for relationship, this tells the browser what kind of file this is and how it relates to the HTML page. 

So your HEAD tag should now look like this:

<head>
    <title>My Webpage</title>
    <link rel="stylesheet" href="style.css">
</head>

And just like the previous discussion about A tags, this is a relative link, so your style.css file needs to be in the same folder as your mypage.html file. 

So now we’ve connected the two together, if you refresh your mypage.html nothing should change! 

And that’s a good thing. It means your styles, which are now in their own css file are being loaded just fine.

Share and Share Alike!

Remember we made that about page in the first tutorial? Let’s open it, add the style link to the top, same as we just did. 

<head>
    <title>About My Webpage</title>
    <link rel="stylesheet" href="style.css">
</head>

And, if you open this in your browser, boom, same style as mypage.html

Now, if you change the style.css file, both mypage.html AND about.html will update with the new changes. You can use the classes you’ve written, such as .animals to style your about.html as well. 

Most sites use a separate CSS file like this for their styling, allowing for easy change and updates to the whole site. Some will use multiple CSS files, so they are only loaded on the pages that need them. 

Bonus Round! DARK MODE

Exciting music plays

This is going to be a very, very simple dark mode bit of code, but it will help show the overall idea for dark mode. 

Dark mode is an inverse color scheme, so instead of a light background and dark text, we have a dark background and light text. 

Now you can just simply style your page to be dark, lots of sites do that. But this code will change from light to dark when the viewers device changes. So if your computer is set to dark mode, the page will be dark. If it is light, then light. If it switches based on the time of the day, like mine does, then the page will change as your computer does. 

So, here is what we are going to do. We are going to make a section that calls out new colors for background and text of everything in the body tag, using a media query. 

The media query is a powerful tool that can be used to change the style of your page based on the size of the screen it is on, the orientation (landscape v portrait), the color settings and more. This is just one slice, and a simplistic one, of what this tool can do. 

At the bottom of your style.css file, add this: 

/* styles for Dark Mode */
@media screen and (prefers-color-scheme: dark) {

}

See the two curly brackets? They are important! Everything we want to add needs to go between them. 

Ok, so prefers-color-scheme: dark is the call, if your computer is set to dark mode, it should trigger this. 

Inside of those curly brackets, let’s change our webpage: 

/* styles for Dark Mode */
@media screen and (prefers-color-scheme: dark) {
    body { 
        color: white;
        background-color: black;
    }
}

This says, change the background of the body (so, everything our our basic site) to black, and change the text to white. 

If you save that, you may or may not see a change, depending on what your computer is set to. But if you are in dark mode, it will invert, black background, white text. 

Now that purple we chose for a light background is way too dark for our dark background. We need to change it as well. To keep with our color scheme, let’s change it to a not-so-dark purple, like this:

/* styles for Dark Mode */
@media screen and (prefers-color-scheme: dark) {
    body { 
        color: white;
        background-color: black;
    }
    
    .animals {
        color: mediumpurple;
    }
}

To note, we only need to put the attributes we want to change in this media query. So if animals had additional attributes, like font size or line height, we don’t have to put them here since we only want to change the color. 

Like our footer! Which is lightgray at the moment, and doesn’t fit our dark theme. Let’s make it a darker gray, called ‘dimgray’:

/* styles for Dark Mode */
@media screen and (prefers-color-scheme: dark) {
    body { 
        color: white;
        background-color: black;
    }
    
    .animals {
        color: mediumpurple;
    }
    
    footer {
        background-color: dimgray;
    }
}

We are going to tweak one last thing. You see that color: white; part doesn’t affect links. You’ll see your links are still dark blue or purple depending on if you’ve clicked on them. And they are hard to see. So, let’s add in some colors that you can see with a dark background: 

/* styles for Dark Mode */
@media screen and (prefers-color-scheme: dark) {
    body { 
        color: white;
        background-color: black;
    }
    
    .animals {
        color: mediumpurple;
    }
    
    footer {
        background-color: dimgray;
    }

    a {
        color: orange;
    }

    a:visited {
        color: yellow;
    }
}

The A tag changes any unvisited links. So we have to add in a pseudo-class, A:VISITED for the color of lines you’ve clicked. 

Save, refresh, and now your links stand out against the dark background! 

Don’t want those colors? Don’t forget the fill list of colors at MDN.

A Start

This was, even more so than the HTML primer, just a start. There are many other aspects of CSS, particularly when you get to layout, that are more complicated than this. But again, just like the HTML tutorial, just because these things are basic, they are far from useless. 

You’ll use font styles on nearly any site, colors for backgrounds and boarders, and as soon as you start your layout, the media queries will come out for responsive websites. 

With the basic structures of classes and IDs you will create a layout, moving these DIV sections all over the page. You’ll create dropdown menus, and change the way the page looks based on the device it is on. 

And inevitably, you’ll forget a semi-colon and spend an hour trying to figure out what went wrong.

Sometimes, the Beginning is the best place to Continue

I’ve been taking an online course on CSS that starts from the basics.

My original ‘course’ in CSS was on the job training as we converted a site from tables to CSS divs somewhere in the summer of 2000.

A lot has changed in the world of web programming since the dot-com boom when I was doing it professionally (well, as professionally as any of us were, I suppose), and while I still make web things, from WordPress plugins and themes to even dabbling in React.js and Svelte, it’s not my profession anymore. This means that while I’m dipping my toes back in everyone in a while—scraping through Google searches to find the answers to my questions—I’m not active enough in the space to catch up by working.

That was how I learned these things, programming Perl, then PHP, adding JavaScript to have mouse-overs. Tables for layout, and I’m going to admit here, in public, that there are days I wish we went back to tables for layout. I learned CSS ‘real-time’ as we updated the site from tables, hard coded styles and background images to a more fluid CSS layout over the summer.

The thing is this: sometimes the best way to learn is to start from the beginning. Sure, I know everything in the first couple lessons, but it wasn’t long before something new came out. A new term, a new phrase, a new best practice.

I know CSS. But I learned it then and patch-worked myself through updates and improvements throughout these years. I knew CSS, and even though I still use it often, the foundation is based on the lessons learned, right and wrong, all those years ago. At some point… at this point, the best way to continue learning is to start over.

Because it is not just specs and code that has changed over the years, but vocabulary, best practices, formatting and naming conventions (not that we had naming conventions in 1999).

This makes a basic course a refresher and a new foundation to build on from here. Don’t be afraid or prideful to take a step back and go over the basics once again.