Introduction
While HTML is used for creating the content of web pages, CSS is used to style web pages. One of the most compelling demonstrations of this is a website called CSS Zen Garden. You may apply different CSS styles to fixed HTML content on this site. It is impressive how the entire layout and look of the page can be transformed by changing the CSS applied to HTML content (the HTML stays the same).
Create a stylesheet and link to HTML
To add styles to our HTML pages, we need to create a .css
file and link it to our HTML files. To connect a .css
file to a .html
file we use the <link>
tag in our HTML file. The tag we’d use looks like this:
<link href="css/styles.css" rel="stylesheet">
and should be placed in within the <head>
element.
The href
attribute tells the browser where to look for the stylesheet. In this case, look inside the “css” folder for a file called styles.css
.
If you clone the repo to your computer, you will see an index.html
file in the root folder and a styles.css
file inside the “css” folder. If you open the index.html
file in your browser, you will see the background has been turned orange by a style set in the CSS.
RESOURCEWe’ve created a simple example of linking a CSS file to an HTML file in this repo on GitHub.
DOCUMENTATIONWhat is a git repository Documentation on how to clone a git repository: Cloning a repository.
The Basic Syntax
To style elements, you need to use a specific syntax.
Here is an example:
h1 {
font-size: 20px;
color: green;
}
- First, we state which element(s) we want to style using a selector. In this case, the
h1
. - Then, we use curly braces to group the styles we’re applying to that selector. In this case, we’re setting the font size to 20px and the colour green.
- After we’ve written each style rule, we close the line with a semi-colon, so the browser knows we’ve finished that rule.
Selectors
We use selectors to identify which element we want to style on the page.
Type
The type selector, also called the element selector, is simply a way to select the HTML element using its HTML tag. It’s generally best to use a type selector if you want to change something specific about that HTML element. By default, the browser applies certain styles to your HTML, which might be useful depending on your design. For example, an anchor tag (<a>
) is styled blue and underlined by default. To change this, we could select all anchor tags using the following selector.
The following styling changes the text colour and removes the underline.
a {
color: green;
text-decoration: none;
}
Class
Generally, the best way to style elements is by using a class. You can apply the same class to multiple elements across the page, which helps you reduce the amount of CSS you need to write. You can add classes to HTML elements using the class
attribute like so:
<section class="content">
<p>Lorem ipsum dolor sit amet.</p>
</section>
<section class="content highlighted">
<p>Sed quis cursus nunc, id fringilla purus.</p>
</section>
We can then style the classes we’ve added to the HTML by referencing them in our CSS file by using a dot followed by the class name:
.content {
font-family: 'Open Sans', Verdana, sans-serif;
}
.highlighted {
border: 2px dashed red;
}
In the HTML example above, we applied the .content
class to two <section>
elements and added a unique class called .highlighted
to the second <section>
. In this case, the second <section>
will get the styles from the .content
class and the .highlighted
class, meaning that this HTML element will have the “Open-sans” font and a red, dashed border around itself.
Learning how to combine class selectors is very useful, especially when working with JavaScript and CSS. You can use JavaScript to add and remove classes from an element. In the case of <section class="content highlighted">
, the classes .content
and .highlighted
are interpreted by the browser as a list of class names, hence called a class list.
In the example above, adding and removing the .highlighted
class from the <section>
element adds and removes the red border around it. The action of adding and removing something is called toggling. We say that you are toggling a class name from the class list of that element. You will learn more about manipulating HTML elements in this way once you start with JavaScript, but for now, it’s enough to remember that you can combine classes.
Naming classes in a clear manner is essential. Giving an introductory paragraph in a header, the class of intro
is much more meaningful than p1
. Remember that other developers usually need to read and understand your code, so make it as clear as possible.
INFONote: having single-purpose classes (utility classes), like adding a border to an element, is used in a design approach called utility-first. You can read more about the utility-first approach here.
DOCUMENTATIONFor further information, please check out the MDN docs: Class selectors.
ID
The id
is an HTML attribute that differs from the class
attribute because its value needs to be unique. The example below shows that the two <section>
elements share the class .content
but don’t share the same id.
<section id="first_section" class="content">
<p>Lorem ipsum dolor sit amet.</p>
</section>
<section id="second_section" class="content highlighted">
<p>Lorem ipsum dolor sit amet.</p>
</section>
The above example shows how to set an HTML element’s id
. In CSS, you select the specific id using the # symbol followed by the id value.
#first_section {
background-color: red;
}
INFONote: Generally, IDs are best used with JavaScript, where we want to be able to override styles applied by CSS easily.
Combining Selectors
You can combine selectors.
Take a look at the following HTML:
<header>
<h1>Welcome to my shop</h1>
<nav>
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="sale.html" class="sale">Shop</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
</nav>
</header>
<main>
<h2>We have many great products</h2>
<p>
Here are the main reasons to
<span class="sale">shop</span>
with us:
</p>
<ul>
<li>Trustworthy</li>
<li>Helpful</li>
<li>Good quality</li>
</ul>
<p>We hope you find what you're looking for.</p>
</main>
It’s a good idea to set a base font for the whole body element, and we accomplish this by using the type selector for the <body>
element. In the example below, you can see that we select an element or tag by simply writing the tag name without any symbols before it.
body {
font-family: 'Nunito Sans', sans-serif;
}
To set the font-family
CSS property on the headings, we could select them individually like so:
h1 {
font-family: 'Playfair Display', sans-serif;
}
h2 {
font-family: 'Playfair Display', sans-serif;
}
However, this is repetitive.
We try to follow the DRY Principle (Don’t Repeat Yourself) in CSS. Using the DRY principle is key to writing good CSS and helps us to write CSS that is as concise as possible. Therefore, instead of writing them twice, we can use a comma to apply the same styles to both the h1 and h2 elements:
h1,
h2 {
font-family: 'Playfair Display', sans-serif;
}
Let’s say we wanted to style all <li>
elements specifically in the navigation to be in a row rather than a column. We couldn’t use li {display: inline-block;}
because this would also affect the list items in the <main>
element. What we could do is use what is called a descendant combinator, which in this case would look like this: nav li {}
.
nav li {
display: inline-block;
}
Using a descendant combinator, you target every list item that is a child of a <nav>
element.
Let’s also remove the <ul>
padding that the browser automatically applies. Then we can set text color of the <a>
tags in the navigation to black and remove the default underline styling for links. We can do this all using the descendant combinator as we did above.
nav ul {
padding: 0px;
}
nav a {
color: #9d3400;
text-decoration: none;
}
Let’s say we wanted to style all elements with the class of .sale
to be red; we could simply target the class: .sale {}
.
.sale {
color: red;
}
Due to multiple elements having the .sale
class, the text colour would be red for all of these elements, including one of the <a>
elements in the navigation. Let’s say we also want to add an underline to this <a>
element. To specifically target the <a>
with the class of .sale
which is within the <nav>
, we can do the following: a.sale {}
. Here, we first use the type selector a
to target all <a>
elements. Then we can further target any <a>
element with the .sale
class by appending .sale
to the end of the a
selector.
a.sale {
text-decoration: underline;
}
A snippet from the HTML example above:
<nav>
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="sale.html" class="sale">Shop</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
</nav>
INFONote that we don’t have a space between the selectors. If there were spacing, it would select every anchor tag with a child element with the class
.sale
, which in this case wouldn’t apply to any elements.
Another combinator we can use is the adjacent sibling combinator. This combinator selects elements next to each other in the HTML. To increase the font size of each paragraph that follows an h2, we could use the following: h2 + p {}
.
h2 + p {
font-size: 18px;
}
When using the adjacent sibling combinator, you will only apply styling to elements that are siblings (ie. they share the same parent element).
Pseudo-classes
We can also apply styling by using so-called pseudo-classes, which allow us to use keywords to target elements based on their state.
Firstly, a brief explanation of what we mean by the state of an element: a good example is when a user hovers with the cursor over an element. When this happens, the element is in what we call a hover state. You can specify the styling of an element depending on its state. In the case of :hover
, we could change the background colour of a button whenever it is in a hover state.
Let’s say we wanted the navigation links to change when a user hovers over them. We could use the following code (notice the colon between a
and the keyword hover): nav a:hover {}
).
nav a:hover {
text-decoration: underline;
}
Other pseudo-classes include :active
when a user is busy interacting with the element, for example, clicking a button. Another is :first-child
, which targets the first child element inside the chosen parent.
DOCUMENTATIONFor further information, please check out the MDN docs: Psuedo-classes
Pseudo-elements
A pseudo-element allows you to style a specific part of the element you’ve selected. Let’s say you wanted to style the first letter of a paragraph. You could use the ::first-letter
pseudo-element.
p::first-letter {
font-size: 18px;
}
Other pseudo-elements that are useful to know are ::before
and ::after
, which let you style the section before or after a specific element. With CSS, you can use the content property to add content
to the HTML. In this example, we add a calendar icon before the date.
.date::before {
content: '📅';
}
We could add the icon in the HTML in front of the date, but we should ask whether the icon is important content that should be in the HTML for someone using assistive technology, or if it is purely styling. If it’s just for styling, then it’s best managed using CSS. Plus, we’d be able to quickly change all calendar icons in one place if we wanted a different icon at a later date.
Cheat sheet of Selectors and Combinators
Example | What is selected |
---|---|
section {} | section elements |
.highlighted {} | Elements with a class of highlighted |
#logo {} | Elements with an ID of logo |
section.highlighted {} | section elements with a class of highlighted |
section .highlighted {} | Elements with a class of highlighted inside of section elements |
section > .highlighted {} | Elements with a class of highlighted that are direct descendants of a section |
section + .highlighted {} | The first element with a class of highlighted after each section |
section, .highlighted {} | All section elements, and all elements with a class of highlighted |
section ~ .highlighted {} | All elements with a class of highlighted that are siblings of a section |
input[type="text"] {} | input elements that have a type of text |
Cascading, Specificity and Inheritance
- CSS stands for Cascading Style Sheets.
- Cascading is the order in which we write CSS, going from top to bottom.
Two conflicting rules are applied in the following example, but which styling should the browser apply? Since CSS runs from top to bottom, it cascades. Thus, the browser will choose the styling applied last and make the background blue.
body {
background-color: orange;
}
body {
background-color: blue;
}
Specificity
In the above example, we have two selectors with the same specificity level. They’re both targeting the <body>
. But what if we want the <main>
to be styled a different colour to the rest of the body? In this example, the <body>
will be orange, and the <main>
will be blue as the main is more specific than its parent element, the body.
body {
background-color: orange;
}
main {
background-color: blue;
}
In the order of specificity:
- A tag selector is the least specific.
- Then a class as it can be applied to multiple elements.
- Then an ID as it can only be applied to one element.
The more specific selector will be the one that gets chosen. Inline styling in the HTML is the most specific you can get, but this shouldn’t be added to the HTML and should only be added using JavaScript, which we will get to in the JavaScript course.
We can calculate the specificity of a CSS selector numerically. The values of each CSS selector are as follows:
Selector | Specificity rating |
---|---|
Inline style | 1000 |
ID | 100 |
Class, attribute, pseudo-class | 10 |
Type Selector | 1 |
DOCUMENTATIONFor further information, please check out the MDN docs: Cascade and inheritance.
Activities
WATCHThis tutorial video on CSS. (12m 20s)
Lesson Task
Brief
There are practice questions in the master branch of this repo.
Attempt the answers before checking them against the answers in the answers branch of the repo.