NAV Navbar
Logo
css

CSS Fundamentals

At RED, we ask you to learn CSS very fast. It is impossible to get all of the ideas, patterns, and syntax right away. This resource is here to help.

Prerequisites

It is strongly recommended that you read the HTML Fundamentals Wiki before continuing.

Why CSS?

CSS (Cascading Style Sheets) is what we use to control the appearance of our web pages. It has two main usages. The first is to control typography (font, size, text style, color, etc.), and the second is to alter the layout and position of elements within an HTML document. It can also control the background (color or image) of any element.

The CSS language is designed to help developers write generalized rules that apply to multiple elements in a page. The idea is that styles for any given element should be consistent across a site, so we should only have to define that style in one place. CSS is what allows it to be applied everywhere.

Using this Resource

Major topics are immediately visible in the navigation bar on the left. Sub-topics are exposed when you click a navigation item and when you scroll down the page. Code examples associated with the descriptions in the center column can be found in the right column.

CSS Rule-sets

/* Example 1 */
p {
  color: red;
}

/* Example 2 */
header {
  position: fixed;
  height: 50px;
  background-color: grey;
}

A CSS rule-set consists of a selector and a declaration block.

In Example 1 on the right, the selector is p, and the rule-set is everything including and between the curly braces. In this case, we are styling the text to be red.

In Example 2, the selector is header. As you can probably guess, we are styling the header’s position, height, and background color.

Selectors

Selectors are how we define which elements on our site we want to style.

We primarily use three types of selectors: element, class and id.

Element Selectors

/* Will select all p elements on a page */
p {
  color: red;
}

/* Will select all header elements on a page */
header {
  position: fixed;
  height: 50px;
  background-color: gray;
}

Element selectors are the easiest to understand, as they use the same element names that we use in HTML.

What’s important to understand is that when we use element selectors we are choosing to apply a style to all of those elements. This is great for general styles, like text size and color. But what if we want to style just some of a given element? We use Classes.

Classes

<p class="description">This is a description</p>
.description {
  font-size: 80%;
  color: lightgray;
}

We use classes to group elements. For example, most sites have regular paragraph tags, but also have a class of paragraph called description. Descriptions are often a bit smaller, and perhaps a lighter shade of grey than regular text.

To select classes using CSS, prepend the class name with a period.

For example, <p class="description"> is selected using .description.

IDs

<h1 id="main-description">This is a description</p>
#main-description {
  font-size: 110%;
  color: black;
}

IDs operate very similarlry to classes. The difference is that an element of any ID should only appear once on a page.

In the example to the right, we use the id main-description. If we need to use the main-description id on another element on the page, we should change main-description from an ID to a class. In general, prefer using classes over IDs.

To select ids using CSS, prepend the id with a hash.

For example, <h1 id="main-description"> is selected using #main-description.

Inline Selectors

<p style="color: red">This text will be red</p>

Inline selectors are selectors that manually applied to an element. They exist in the HTML itself.

CSS was essentially invented to avoid inline styles, so they should be avoided whenever possible. There are a few exceptions (programattically generated background images, some jQuery functionality), but 99% of the time, you should be using CSS instead.

Naming Classes and IDs

/* Bad */
.Description {}
.DESCRIPTION {}

/* Good */  
.description {}

/* Bad */
.main_nav {}
.MAIN_NAV {}
.MainNav {}
.mainnav {}

/* Good */
.main-nav {}

/* Bad */
.des {}
.dscript {}

/* Good */
.description {}

Classes and IDs should be named using kebab case (lowercase with words separated by hyphens - looks-like-a-kebab).

They should be used to describe the element you’re assigning a class or ID to. For example, side-navigation is descriptive, while column-2 is not.

They should avoid silly abbreviations, like des for description, of clm for column. Some abbreviations are permitted, but only if they’re ubiquitous, like nav for navigation.

How CSS Works

                    HTML Document Tree

                           html
                            |
             -----------------------------------
             |                                  |
           head                                body
             |                                  |
  ---------------------------           ---------------------
  |       |         |       |           |        |           |
title  link(x2)  script  meta(x3)     header    div       footer
                                        |        |           |
                                       h1    ---------       p
                                             |        |
                                             h2       p

In our HTML Wiki we talk about how CSS understands an HTML Document as a tree.

This is a really important concept, as it helps us visualize how CSS applies rules to HTML elements.

Forget the Head

HTML Document Tree (without head)

             html
              |
             body
              |
     ---------------------
     |        |           |
   header    div       footer
     |        |           |
    h1    ---------       p
          |        |
          h2       p

The head tag doesn’t actually render any HTML Elements, so we can ignore it when thinking about the Document Tree in the context of CSS.

Apply a Selector

div {
  color: blue;
}
The div elements and its descendants
will have the 'color: blue' rule applied

               html
                |
               body
                |
       ---------------------
       |        |           |
     header  → div ←      footer
       |        |           |
      h1    ---------       p
            |        |
          → h2 ←   → p ←

Let’s say we want to select all div elements in our page and apply a font color to them.

CSS finds any div elements in the tree, and applies the style to them and all of their descendants.

In the example on the right, all text within the div will be red, but so will the text in the h2 and p elements that descend from the div.

View in Codepen

Cascading

html {
  font-size: 16px;
}
The html element and its descendants
will the 'font-size: 16px' rule applied

            html
             ↓
            body
             ↓
    ← ← ← ← ← → → → → → →
    ↓        ↓           ↓
  header    div       footer
    ↓        ↓           ↓
   h1   ← ← ← → → →      p
        ↓         ↓
        h2        p

As we saw in the previous example, if we apply a CSS rule to and element, it will be applied to all of its descendants. So, if we apply a rule to html, the rule will be applied to the entire document.

If we think of the tree as a waterfall with water flowing from the root (the html element) down every branch until it finds the bottom, we can say that the CSS rules for html cascade down the waterfall to every descendant of html.

Sub-Trees

div {
  color: blue;
}
Div Sub-Tree

    div
     ↓
 ← ← ← → → →
 ↓         ↓
 h2        p

When we use a selector, we effectively break the document tree into sub trees. So, as in the previous example, when we select a div, we apply rules to it and its descendants.

CSS works exactly as it did will the html element, except now the waterfall starts at the root of the sub tree (div) and cascades down from there.

Combining Selectors

<body>
  <div class="intro uppercase">
    <p>Intro Text</p>
  </div>

  <p>This is the main paragraphy in the document</p>
</body>
/*
  Multiple selectors on a single element
*/

/* Select an element and a class */
div.intro {}

/* Select an element with both classes */
.intro.uppercase {}

/*
  Selectors that use hierarchy
*/

/* Select paragraphs descending from elements with a class of intro */
.intro p {
  color: red;
}

Sometimes you need to select an element in a certain context. To do this, we can combine selectors. If the example on the right, if we wanted to select the p tags within the intro div, we simple combine the two selectors: .intro p.

When we combine selectors, we can do it in a couple ways.

First, we can apply several selectors on a simple element. For example, for a div with a class of intro we can select div.intro. If we have a div with two classes, intro and uppercase, we can use both in a selector: .intro.uppercase. Notice that there is no space between the selectors.

We can also take advantage of hierarchy when we use selectors. To do so, use a space between selectors. For example, .intro p means any paragraphs that are descendants of any elements with the intro class. This is extremely powerful. The space is what we use to signify descendance. Note that descendants don’t need to be direct descendants (children), they can be grand-children, great-grand-children, etc. If we picture our HTML as a tree this is easy to understand. We apply the first selector to part of the tree, and any subsequent selectors are found within that element’s sub-tree.

Specificity

Because CSS rules apply to their selected element and all descendants, it is inevitable that elements will have multiple CSS rules assigned to them. So what happens if those rules conflict? How does the browser know which rule to apply?

The answer is specificity.

Specificity calculation is actually very simple math based on the selectors you write. Here’s how it works:

This is easier to digest when viewed in a table:

Selector Inline ID Class Element Score
p 0 0 0 1 1
.intro 0 0 1 0 10
#wrapper 0 1 0 0 100
#wrapper article.featured p 0 1 1 2 112
#wrapper nav li.active i 0 1 1 3 113
#wrapper nav ul li.active i 0 1 1 4 114

As you may have guessed, the selector with the higher score will be applied, and any less specific rules will be ignored.

This is called clobbering. The strongest survive!

How specific should you be?

/*
  Keep it simple!
*/

/* This is crazy */
#wrapper nav ul li.active i {}

/* This is probably a better version */
nav .active i {}

/*
  Avoid using html or body selectors, they're probably not needed
*/

/* Bad */
body p {}

/* Good */
p {}

/*
  It helps to define general classes and apply them
  in multiple places in the html
*/
.uppercase { text-transform: uppercase; }

Less is more.

The purpose of CSS is to be able to write generalized rules that apply to an entire site. If you’re writing a selector to only apply to one element, ask yourself why that element is different than every other element, and whether it needs to be.

As we mentioned before, Inline and ID selectors should be avoided. If you only use class and element selectors, your specificity score should never be above 15.

There will be exceptions to this, particularly if you’re using outside libraries and need to clobber their CSS, but it’s a good generalized rule.

Learn More!

MDN (Mozilla Developer Network) has the best online resource for CSS.

It is well-maintained and very descriptive, but sometimes can be a bit overkill for beginners. In the sections below we’ve outlined some of the more common elements you’ll use while writing CSS. The documentation for each one can be found on MDN.

Typography

CSS allows us incredible contol over the text on our pages.

Common Rules:

font, font-family, font-size, font-weight, text-decoration, text-align, line-height

Additional Resources:

Box Model

When the browser renders our HTML, it essentially renders nested boxes onto the screen. The Box Model is the set of rules used to determine the size and orientation of those boxes.

Common Rules:

width, height, margin, margin-[left/right/top/bottom], padding, padding-[left/right/top/bottom], border, border-[left/right/top/bottom]

Additional Resources:

Positioning

The Box Model defines the majority of layout in an HTML document, but sometimes we need items to behave in very specific ways. We can change whether an item is inline or block, for example, or whether is should be rendered outside of the flow of the rest of the elements on the page!

Common Rules:

display, position, float, clear, flex

Additional Resources:

Backgrounds

CSS allows us to alter the background of any element, we can use colours, images, gradients, even video for backgrounds.

Common Rules:

Additional Resources:

How to Google CSS

There are dozens of tutorials for every CSS use case, so you just need to figure out how to find them.

Examples:

Contributing

This is a living document. It is up to all of us to make sure the information it contains is relevant and useful!

We encourage you to contribute, whether you’re fixing a typo or adding a new section.

Fork the repository

Forking is essentially making a copy of a repository. You can then make changes to it for your own purposes.

The source code for this website can be found on Github.

When you visit a repository page on Github, the fork button can be found in the top-right corner. Click it and choose your account as the place to “fork to”.

Clone your fork of the repo

cd an/appropriate/directory
git clone git@github.com:YOUR_USERNAME/html-fundamentals.git
cd js-fundamentals

Cloning is the term we use for copying code from Github to our local filesystem.

The clone command automatically creates a new folder with the repository name; in this case, js-fundamentals.

Install dependencies and serve

# Install:
gem install bundler
bundle install

# Serve
bundle exec middleman server

Once your server is running, you can visit a local version of the site at localhost:4567!

Contribute!

This site is written entirely in Markdown. Each section has its own file in /source/includes. You can update any existing files.

If you’d like to add a new section:

Make a pull request

git add --all
git commit -m "Made a contribution!"
git push origin master

Once you’ve finished your work, commit your changes and push them to your local repository.

Next:

Merge conflicts

You may end up with merge conflicts with the base fork. To resolve, you’ll first have to add the base fork to your local git.

git remote add upstream https://github.com/redacademy/js-fundamentals.git

Then you can get the most recent code from the base for and merge it into your local code.

git fetch upstream
git merge upstream/master

Then you can resolve your conflicts and push back to your fork. Pull requests update automatically when new commits are pushed.

css