Tutorial: An Introduction to the Awesome World of CSS

Lara Aigmüller

(updated on )

When somebody would ask me what my favorite web technology is, I would probably answer: CSS, which is short for Cascading Style Sheets. The CSS syntax is easy to understand and learn, but the inner workings of CSS can become complex quickly. It became a powerful language over the last couple of years and there are so many awesome features already available in modern browsers, I didn’t have the time to try and use them all.

Today we’re going to start small: we’ll have a look at how CSS works, what it can do and how it interacts with HTML. Let’s go!

What is CSS?

CSS is short for “Cascading Style Sheets”. We’ll get a feeling about what “cascading” means in this context during the next few tutorials.

In the last three articles about HTML basics we learned that HTML is the heart of every web page. It defines the content structure and contains links to all resources needed to display the page, like for example images. CSS is HTML’s best friend. It’s used to give your web page a unique look, to add colors and fonts, layouts and spacing, visual effects and animations, and much more…

HTML tells your browser that one part is a headline and another part is a navigation and there’s a list of links to interesting articles. CSS tells your browser that the headline is larger than the body text, that the navigation is a horizontal bar on top of your page with a light blue background, and that the list of links can always be found on the right side of your main content.

As always in this tutorial series, we continue working on the code example we built together last time. If you are new here, I’ll recommend working through the first three articles of my HTML tutorial series to have a working HTML code example ready.

If you want to skip working through the previous parts, have a look at the code from last time in the GitHub repository I prepared.

CSS in HTML

Let’s start with the index.html file of our small web page: open it in a text editor and a browser of your choice (I use Visual Studio Code and Firefox).

On the homepage of our personal website, we have a navigation on top, a page title (<h1>) and two content sections within our <main> part of the page with some text about ourselves, an image and a list of interesting projects. The page has a white background, black text and the default font family uses a serif typeface.

There’s actually styling already! 🎨

We want to override the defaults defined by the browser. To do so, we have to switch back to the code and search for the <head> section in the HTML file. It’s above the <body>. As described in the very first article of this series this is the place where all the metadata is placed, everything that’s not visible to the user who visits your site. This is the place where we will put our styles.

Add the following code snippet to your HTML file’s <head> section, below the <title>:

<style>
  body {
    color: tomato;
  }
</style>

Go back to the browser and reload the index.html file. Now the whole text should be rendered in a nice color looking like a mix of orange and red. 🍅

CSS rules

The thing we added to our head section in the HTML file, enclosed by <style> tags to tell the browser that it will find CSS code in the following lines, is called a CSS rule.

The first part of the rule is called CSS selector—that’s body in our example. It selects the element within our HTML file we want to style. We select the whole body here, but we could also change body to h1 and have a look what happens then. Update your CSS code to the following and reload the page again in your browser. Now, the page title looks like a tomato, but the rest of the page’s text is black again.

h1 {
  color: tomato;
}

The selector is followed by an opening brace (or curly bracket). The closing brace comes at the end of the rule.

In between is a so-called CSS declaration—a key value pair defining which CSS property should get assigned which value. We assign the color name tomato to the CSS property color, which is used to define the font color of a certain element. Each declaration is concluded by a semicolon.

A CSS selector followed by a block surrounded by braces containing one or more CSS declarations is called a CSS rule.

Within a CSS rule block, we can add more than one declaration; there’s a lot more we can change than just the text color… 😊 Let’s add a background color and change the text color of the whole page back to something more neutral, for example:

body {
  color: dimgray;
  background-color: ghostwhite;
}

To keep your CSS rules readable, put every declaration in its own line and never forget the semicolon after each declaration! 👩‍🏫

Grouping selectors

Let’s say we want our body text on the page to be dimgray but the headlines should be more colorful. We can extend the CSS code like this:

body {
  color: dimgray;
  background-color: ghostwhite;
}

h1,
h2,
h3 {
  color: indigo;
}

CSS selectors can be grouped by separating them with commas. This way you don’t have to add a lot more rule blocks and repeat the color declaration for each headline type individually, but rather combine styles that should be applied to all headlines.

Inheritance and overrides

Before, we only set the color for the body and all text on the page was dimgray. This is because the color property is inherited by all child elements of the body element. On our page we use headlines (h1, h2, h3), paragraphs (p), a list (ul, li)… When selecting the body the color style gets applied to all its children.

By adding another rule and selecting the headlines, we override the inherited color property, because we’re getting more specific here. All other child elements of the body keep their dimgray color.

Styling text

On our website we want to use a sans-serif typeface instead of the default serif one. To change this, we use the font-family CSS property. Update the CSS code like this:

body {
  color: dimgray;
  background-color: ghostwhite;
  font-family: "Helvetica", "Arial", sans-serif;
}

h1,
h2,
h3 {
  color: indigo;
}

Reload the page in your browser and you’ll see that the font style has been updated from a serif to a sans-serif typeface. The font-family property takes one or more values separated by commas. If the first font (Helvetica in our case) is not installed on the user’s device, the browser looks for the next one (Arial). In case none of the defined fonts is available, it falls back to the system’s default sans-serif font.

Text related properties

There are a lot of CSS properties available that can be used to change the appearance of the text on your page. Properties I use a lot are:

  • font-size
  • font-weight
  • text-decoration
  • line-height
  • text-align

It takes some research and practice learning and keeping in mind which values the individual properties can take. We’ll have a look at some of them in the following code example:

body {
  color: #303030;
  background-color: #fafafa;
  font-family: "Helvetica", "Arial", sans-serif;
}

h1,
h2,
h3 {
  color: indigo;
  font-weight: 700;
  text-align: center;
}

p {
  font-size: 18px;
  line-height: 1.5;
}

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

You already know what color, background-color and font-family do. Using text-align you can—obviously—change the text alignment. On our website, we want headlines to be centered. The font-weight property defines the used font style; 700 is an equivalent to bold.

It's good to adjust the default line-height for body text on your website. There are a lot of design guidelines available about which value to choose based on the given font size and the given layout. For now, we use 1.5, which is a good starting point.

Take a few minutes and play around with the new CSS properties. Change the values, reload the page in your browser, and get a feeling on how elements change and behave on your index page.

Colors in CSS

We started by using predefined keywords as color values, but more often you’ll find hexadecimal values within CSS code. Instead of color: red; you can write color: #ff0000. Another way of telling the browser to display something red is to write color: rgb(255, 0, 0); or color: hsl(0, 100%, 50%);. Which syntax to choose depends on the code style of your project and whether you want to change (e.g. animate) the color dynamically.

Find more about the color syntax and things that can have color in CSS in the official MDN documentation.

Units in CSS

In the above example, we used the pixel unit (px) to define the font size. In CSS code, you’ll find other units as well, not only for defining font sizes but to define the size of an element or space between elements. Here are the most commonly used units:

  • px: an absolute unit
  • em: a relative unit; equal to the element’s (or its parent’s) font size (I told you, that CSS gets complex quickly)
  • rem: relative to the root element’s (the html tag) font size; if not changed, this defaults to 16px in all common browsers
  • %: relative to the current font size or the parent element’s size

There’s much more, but listing all possible unit values here will get rather boring soon, so let’s continue with something more fun! 🥳

Share CSS code across HTML pages

Make sure you have the recent version of our CSS snippet ready. Until now, we only worked in the index file of our small website. As soon as you use the navigation and switch to the “about me” or the “contact” page, all our wonderful styles are gone.

We could copy the <style> tag and its content from the index file and paste it into the head sections of the other HTML files. However, as soon as you start copy-pasting code during web development, alarm bells should start ringing. 🔔 Duplicated code most commonly leads to bugs after some time. You make updates in one file but forget about the others… The solution is to share the CSS code across all HTML files.

To do so, we create a file called styles.css, put all CSS rules (without the <style> tags) into this file and save it next to our HTML files. In the index.html file, we replace the opening and closing <style> tags in the head with <link rel="stylesheet" href="style.css" />. This is similar to links (anchor tags a) within the HTML body, but when placed in the head of an HTML file we call them link. Put this line in the other HTML files as well.

Now we have a place where we can put all our styles shared across all HTML files!

The full code of this article can be found on GitHub. Go to repository.

Designing in the browser

I never write CSS code without the help of my browser’s developer tools. They are super useful when it comes to try out things and find bugs. Often when I’m on another website and want to know how something is done, the first thing I do is open the developer tools and inspect the element.

Open your website’s index page in the browser and open the dev tools as well. Make sure the "Inspector" tab (in Firefox; in Chrome it’s called "Elements") is selected.

Pick, for example, the h1 headline of our page and explore what you can find about it in the developer tools.

The index page in the browser with dev tools opened. The page’s h1 headline is selected and styles are shown in Firefox developer tools.

You see all the styles you've written yourself (color, text alignment,…) and also the browser’s default styles, the user agent stylesheet—these are the styles applied by default, which you can override with your own CSS. You can see that the applied font family is "Helvetica" (and not "Arial") and that this property is inherited from the body.

In the developer tools, you can disable or change values and see the changes directly in the browser. You can also add new properties. Take some time and try some things, for example:

  • Change the color of headlines
  • Change the text alignment
  • Change the (font) size of elements
  • Disable styles you defined in your stylesheet file

The index page in the browser with dev tools opened. The page’s h1 headline is selected and styles are shown in Firefox developer tools. Styles have been updated directly in dev tools.

Note that changes you made using developer tools are not automatically saved to your CSS file. If you’ve made changes you want to keep, go back to your stylesheet file and add them there as well!

Use the browser’s developer tools to debug your own CSS code but also to explore CSS code of sites you like, for example this website and the scale blog. 😉

The cascade

Understanding the cascade may take some time and experience. Let’s start with a few basics about it. You’ve already learned that styles can be declared in different places in your project; e.g. directly in the HTML file or in an external file that is linked to the HTML file. Both have the same effect basically, but think about what happens when you have similar CSS rules in both places…

In your external stylesheet file it says:

body {
  color: midnightblue;
}

… and in your index HTML file you find the following rule:

<style>
  body {
    color: darkblue;
  }
</style>

The browser now needs to decide which color value should be applied to the body. The most specific rule usually wins. In this case it means: the closer the CSS rule is to the HTML code it gets applied to, the more specific it is. The body color in the above example would be darkblue.

Sources of CSS code

There are a few more places where CSS code can be defined. Here’s a list ordered from less specific to most specific:

  • User agent style sheet (the browser’s default)
  • Browser settings (defined by the user)
  • External style sheet
  • Page specific styles
  • Inline styles

It gets even more complicated when taking the !important keyword into account, but I don’t want to tell you too much about it for now…

Here’s a nice summary from MDN about the CSS cascade for those who already want to learn more about it.

Specificity and source order

Next time, we are going to learn about new selector types and their possible combinations. Then, we can talk about the specificity of CSS selectors, which are also relevant for the cascading algorithm to decide whether to apply a certain styling to an element.

Source order is relevant as well. When you have two style rules that are equally specific and important the one that comes later in your CSS code gets applied.

Basic styles for a tiny website

Let’s conclude this part of this web development basics blog post series with some more CSS. Here’s my final code for my personal website. Feel free to use other fonts or colors, sizes and line-heights.

Don’t forget to put the link to your styles in the head section of your about.html and contact.html file as well!

<link rel="stylesheet" href="style.css" />
body {
  color: #303030;
  background-color: #fafafa;
  font-family: "Helvetica", "Arial", sans-serif;
}

h1,
h2,
h3 {
  color: indigo;
  font-family: "Georgia", "Times", serif;
  font-weight: 700;
}

h1 {
  text-align: center;
}

p {
  font-size: 18px;
  line-height: 1.5;
}

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

nav {
  text-transform: uppercase;
  letter-spacing: 2px;
  font-weight: 700;
}

footer {
  background-color: #3c2a4a;
  color: #ffffff;
}

footer p {
  font-size: 14px;
  text-align: center;
}

There’s not a lot you haven’t already seen during this part of the tutorial. Just two things that might need some explanation:

When text is transformed to uppercase, like I did it for the navigation (nav), it’s a good idea to also increase letter spacing a bit. Here’s a blog post about Guidelines for Letterspacing Type in case you’re interested in typography.

The last rule only applies to p (paragraph) elements that are children of the footer element. We’ll hear more about combining selectors next time. This way, I can override the styles I defined for p elements a few lines before. Note that the font-size gets overwritten and is 14px instead of 18px in the footer. The other two CSS declarations are combined, which means that the line-height for paragraphs in the footer is 1.5 as well and additionally text alignment is changed to center.

Here’s a screenshot of the "about me" page with CSS included.

My website’s about me page including the CSS code from this part of the tutorial.

Key takeaways

Phew… I would say, we've learned many new things today. Let’s summarize:

  • CSS is short for Cascading Style Sheets.
  • CSS is used to add styles, i.e. colors, fonts, spacings, layouts, and more to web pages.
  • There are different ways to include styles in an HTML file. I prefer creating an external stylesheet and link to it from all my web pages, so I can reuse basic styles and don’t have to duplicate anything.
  • CSS files consist of CSS rules. A rule is a selector, followed by one or more CSS directives (key-value pairs) enclosed by curly braces.
  • We played around with some CSS properties to change font families, colors, sizes, and more.
  • CSS can be viewed, debugged and temporarily edited via the browser’s developer tools.
  • Once your CSS file grows, it happens a lot that more than one CSS rule applies to a certain element of your web page. Therefore, we need a way to find out which rule "wins" and overrides another one. This is called "the cascade", and it’s very useful to understand its inner workings to be able to prevent bugs and writing unused code.

Next time we’ll learn more about CSS selectors, possible combinations and their specificity.

Any thoughts or comments?

Say hello on Mastodon or contact us via email or contact form!