Introduction to CSS
Introduction to CSS
Today we'll look at what CSS is, how it operates, where to put it, how to write CSS rules, and how to validate our CSS.
Table of Contents
What is CSS?
Today we learn a new language! CSS, or "Cascading Stylesheets" is a computer language that has been a part of the web since 1996. Currently, we use "CSS3", but since new features keep getting added incrementally, there likely won't be something we call "CSS4".
Just like HTML and the Web Accessibility Guidelines, CSS is governed by W3C.
(For better, or for worse) CSS controls how web documents (a.k.a. web pages, a.k.a. HTML) look, from colours and fonts to layouts and animation.
Why CSS?
As discussed, having our styling kept separate from our content (HTML) and our functionality (JavaScript), allows for the "separation of concerns".
These different languages do different tasks, which makes things more resilient (one thing can break without taking everything down with it), more maintainable (you can update the look without having to rewrite the content, for example), and easier to understand.
CSS as a language is tremendously flexible (and can be a lot of fun!) But that flexibility means we have to code responsibly, or things can get messy and quick.
Today we're going to go into what makes CSS messy, but before we dive into the nitty-gritty, let me do some quick live-coding to show you, in a nutshell, how CSS normally works.
How to write CSS
Structure of a CSS ruleset
CSS rulesets (commonly just called 'rules') start with a selector. The selector determines what HTML elements the rules should apply to.
Following the selector, there are braces (a.k.a. curly brackets) that wrap the rules.
Inside the braces are the declarations. Declarations are the rules that are going to apply to the selected elements.
These declarations are made up of properties and values. The property is the quality that you want to change. The value is what you want to change the property to be.
After each declaration within the ruleset, you write a semicolon.
At the end of your ruleset is a closing brace.
(selector) | open brace | (property) | colon | (value) | semicolon | closing brace |
---|---|---|---|---|---|---|
h1 | { | color | : | blue | ; | } |
h1 {
color: blue;
font-size: 2rem;
}
Selectors
Unless I tell you otherwise, use single classes as your selectors. I'll explain more later. What you're learning in this section will help you work with other people's code, but when you are writing your own code, use classes as your selectors.
Selector | Description | Example | Selected element |
---|---|---|---|
. | Selects elements with matching class attribute | .my-class {color: blue;} | <p class="my-class"></p> |
Element name | Selects a matching elements | p {color: blue;} | <p></p> |
# | Selects elements with matching id attribute | #myId {color: blue;} | <p id="myId"></p> |
* | Selects all elements | * {color: blue;} | <p></p> and literally every other element on your page. |
[attr=value] | Selects all elements with matching attribute | [href="#home"] {color: blue;} | <a href="#home"></a> |
Selector | Description | Example | Selected element |
---|---|---|---|
, | Adds multiple selectors to the same ruleset | .my-class, .my-other-class {color: blue;} | <p class="my-class"></p><h1 class="my-other-class"></h1> |
Combined selectors | Selects one element based on multiple selectors | div.my-class.my-other-class{color: blue;} | <div class="my-class my-other-class"></div> |
[space] | Selects descendant elements | div .my-class{color: blue;} | <div><p><span class="my-class"></span></p></div> |
> | Selects direct child elements | #myId > span {color: blue;} | <p id="myId"><span></span></p> |
~ | Selects all sibling elements | p ~ .my-class {color: blue;} | <p></p><div></div><span class="my-class"></span> |
+ | Selects immediate sibling | h1 + p {color: blue;} | <h1></h1><p></p> |
See the Pen CSS selectors demo by Simon Borer (@simonborer) on CodePen.
Where to write CSS
There are 3 places you can write CSS:
- In an external stylesheet document
- In the
<head>
of your HTML document, wrapped in a<style>
element - In the style attribute of an element, i.e.
<span style="color:red;">My red text</span>
External stylesheets
Most of the CSS you write will go in an external stylesheet - a document with a .css
file extension. This gets loaded into your document via a <link>
element in the <head>
of your HTML document, much the same way we load images via an <img>
element. But we'll worry about that next week.
This week, we can just work in the 'CSS' pane of Codepen.
Style tags
It's fine to write CSS in a style tag in the head of your document. However, if you're hoping to share this CSS across multiple pages (and you're not templating the head across documents), or if you write more than a few dozen lines of CSS, this can get really messy and unmaintainable.
Style attributes
The least popular way to write CSS is in the style attribute. It's inefficient, messy and hard to maintain. People will make fun of you if you do this without a good reason. And they're right to do it.
Inheritance, specificity, and the 'Cascade'
The messy part of CSS is determining what rules take precendence based on priority.
The priority is set based on 3 factors: inheritance, specificity, & the 'Cascade'.
Inheritance
Some properties1 are inherited from parent elements.
<p style="color:green">
All this <strong>text</strong>
will <em>be green</em>
<p>
Inheritance is the lowest priority. Any selector beats inheritance.
Specificity
Specificity gets very complicated Opens in a new window very quickly.
Here's the short version:
An id selector (#myId
) beats a class selector (.my-class
), and a class selector beats an element selector (h1
, for example).
Three levels of specificity (.three-levels .two-levels .one-level {}
) beats two levels of specificity (.two-levels .one-level {}
) which beats one level of specificity (.one-level {}
)2.
Combined selectors (h1#myId
) beat single selectors (#myId
).
All of this specificity gets beaten by an inline style3.
The only thing with a higher priority than an inline style is !important
.
.so-important {
color: purple !important;
}
The only thing that can override !important
is another !important
.
How the 'Cascade' works
If you have more than one declaration targetting the same selector with the same level of specificity, the cascade determines precedence.
The 'Cascade' refers to prioritization based on the type and load-order of stylesheets (and CSS written in <style>
tags).
Default browser styles (also called 'User-agent styles') get loaded first.
Next, styles defined by the web page's author ('author styles') are loaded in the order they appear in the document.
Why some people hate CSS
I mean, you get it at this point, right? It can be really hard to figure out what takes precedence, and therefore how to make that thing blue, or whatever.
That's why I'm going to strongly, strongly encourage you to use classes with little to no layers of specificity for all your styles. It is very, very easy to make your code into a confusing mess, also known as specificity wars Opens in a new window.
If you want to have lots of classes that do very specific things (i.e. one for font-size, one for border), that's actually very popular these days Opens in a new window, and is certainly better than the alternative.
Personally, I like having a system for naming Opens in a new window my component classes. But that's just me.
Some basic CSS units, values & properties
Okay, now that you've been thoroughly intimidated by the 'Cascading' part, it's time to actually get stylish!
Here's a list from our friends at MDN Opens in a new window. Check it out in order to determine what values a property can have, and what elements it can be applied to.
Colours in CSS
Where a property can take a colour as a value, those values are usually written as hexadecimal values (the # symbol, followed by a six-digit alphanumeric code). You can also use named colors, and RGBA units if you want to take advantage of an opacity value.
Unit | Description |
---|---|
px | Number of pixels (1/96th of an inch). The only common way of hard-coding an absolute value in CSS. |
rem | Font size of the root element. |
em | Font size of the parent element. |
vw | 1% of the viewport's width. |
vh | 1% of the viewport's height. |
% | Well, this is context-dependent and gets messy. For example, if you set a width to a percentage, then it would be that percentage of the parent's width. |
Property | Description |
---|---|
background | Defines the background color or image. |
border | Defines the width, style and colour of the element's border. |
border-radius | Defines the degree to which an element's corners are rounded. |
color | Changes the color of text. |
font-family | Changes the text's font. |
font-size | Changes the text's size. |
font-weight | Changes the text's weight. |
margin | Changes the space around the outside of an element. |
padding | Changes the padded space inside of an element. |
text-align | Changes the justification of text. |
text-decoration | Changes the decoration of text. |
height | Changes the height of an element. |
width | Changes the width of an element. |
How to validate CSS
Just like HTML, we have the option to spot-check things in Codepen, and do a proper validation through the W3C Opens in a new window.
Here's today's lab work:
- Sign into your CodePen Opens in a new window account.
- In CodePen, create a new "Pen".
- Create a short write-up about what you learned today about how CSS determines what rules apply to what elements. Your write-up should be styled with at least one instance of each of the following:
- a class selector
- an id selector
- a sibling selector
- a child selector
- centred text
- a hex code
- a font-size
- one style that gets overridden by another
- When you're done, submit the link to it via Blackboard, just like we did the first week.
Footnotes
font-size
, line-height
, and text-align
, including list properties like list-style
.+
, >
, ~
, and [space]
don't affect specificity.