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
.
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:
- Inline selectors are worth 1000 points
- ID selectors are worth 100 points
- Class selectors are worth 10 points
- Element selectors are worth 1 point
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:
background
,background-position
,background-image
,background-color
,background-repeat
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.
- For general questions, try this template:
How do I [insert use case] in CSS
- If you want a tutorial, try:
[insert use case] tutorial CSS
- For rule-specific questions, try:
[rule name] example CSS
Examples:
How do I align text to the right in CSS
Text shadow tutorial CSS
text-align example CSS
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
- Gem is a ruby package manager.
- Bundle allows us to install packages based on a list found in a file called
Gemfile
- Middleman is a lightweight server that runs locally.
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:
- Create a new file in /source/includes
- Make sure the filename starts with an underscore, ie
_section
- Tell the site to render the new section by adding it to the
includes
list inindex.html.md
.
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:
- Visit your fork on Github - https://github.com/YOUR_USERNAME/js-fundamentals
- Click the Pull Requests tab
- Click the New Pull Request button
- It should automatically compare your fork with the master repository
- Submit your pull request!
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.