# CSS Selectors
By default, the browser gives them a style that looks like the web would have looked in the late 1980s — a simple white background with black text in a default font. At the time this simple styling was fine for scientific research and basic websites, but as the Web became more popular, the Web’s authors wanted to tweak the look and feel of their sites.
Over a few years between 1989 and 1996, to change the style, authors used plenty of “hacks” — non-standard ways to get around the limitations of the code they could play with. HTML started getting more complicated as more hacks were added, to the point where HTML started to look unusable to normal people.
Back at CERN, one of Tim Berners-Lee’s colleagues, a Norwegian called Håkon Wiem Lie, had an idea based on other word processing programs. The idea that if you were using a header or a paragraph in several places across a website, you probably want them to look consistent. The idea that you could make the colors and typography consistent until you wanted to overwrite something later on. Håkon had come up with the idea of Cascading Style Sheets (or CSS for short).
The cascading part of CSS is the idea that you begin to style your site on a general basis, then get more particular as you get into the nitty-gritty. For instance, you might want to make the typeface Arial across the whole site, except for headers where you prefer Georgia.
So it’s always good to keep this in mind. Start off thinking about styling in the most generic way possible. What is the most used color? What is the most used typeface?
We'll look at the cascade more in the next lecture, for now, let's look at some selectors.
# Basic Selectors
# Element Selectors
The most basic selector is an element selector. We've mostly been using these for our examples. They select any HTML Element specified.
p {
color: #222233;
}
2
3
This selector would select every instance of the <p>
tag on our site. If we wanted to overwrite this style, we would need to be more specific (next lecture).
# Class Selectors
We've mentioned classes before, but let's look a bit closer. In the HTML, we can add a class like so...
<p class="introduction">Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. </p>
2
3
To style this in CSS, we would use a .
before the class name.
.introduction {
font-size: 18px;
font-weight: bold;
}
2
3
4
You can also combine an element and a class selector, like...
p.introduction {
/* ... */
}
2
3
The first selector says "these rules apply to every element with the class 'introduction'". The second selector says, "these rules apply to every <p>
element with the class 'introduction'". The second one is more specific, which we'll talk about in a bit.
Class selectors make up a large chunk of the selectors you'll write. Effective class naming and usage is key to working with CSS and staying sane. We'll have an entire lecture on this subject later.
# ID Selectors
You can also give elements "IDs" with the id
attribute. In theory, every ID should be unique.
<p id="introduction-but-more-specific" class="introduction"></p>
You use these in CSS with a #
like...
#introduction-but-more-specific {
color: purple;
}
2
3
We'll talk more about it in a bit, but IDs are very specific. So specific, that you need to be careful when using them. They should only be used when you absolutely only want to write styles for one thing that you'll never re-use again.
# Combinators
# Descendant Selectors
Given the following HTML...
<p class="introduction">Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor <a href="#">incididunt ut labore</a> et
dolore magna aliqua.</p>
2
3
...We can use the following CSS selector to select only links inside elements with the "introduction" class.
.introduction a {
color: tomato;
}
2
3
Simply using a space between the selectors implies an ancestor/descendant relationship. With a descendent selector, it isn't just children that will be styled, but all links that are inside something with the "introduction" class, no matter how deep it's nested.
You can also have more than one descendant in a list.
.introduction ul li {
margin-left: 1em;
}
2
3
In this case, li's that are inside ul's that are inside elements with the class "introduction" will be styled.
Keep in mind though, the longer you make these chains, the more specific they get and hence become difficult to overwrite later on.
# Child Selector
Since using the descendant selector (a space) targets all the descendants, the need arises to target just the immediate children of an element. We use the greater than symbol for this (>
).
.introduction > a {
color: tomato;
}
2
3
In this case, only <a>
tags that are the immediate children of elements with the class "introduction" will be targeted.
# Sibling Selectors
# Adjacent Sibling
The plus (+
) sign indicates an adjacent sibling. Given the following CSS...
h2 + p {
font-size: 1.5em;
}
2
3
...would apply the rule-set to any <p>
element that appears directly after an <h2>
. These only work forwards though, you couldn't target <h2>
s that occurred before a <p>
.
# General Sibling
The ~
character lets us target general siblings.
h2 ~ p {
font-size: 1.5em;
}
2
3
That selector would target any <p>
elements that were siblings of an <h2>
. It still only works forwards though. For example...
<p>text ...</p>
<h2>Heading</h2>
<p>text ...</p>
<p>text ...</p>
2
3
4
... only the last two paragraphs would be targeted.
# Attribute Selectors
You won't use these much as a beginner, but Attribute Selectors are worth mentioning because they're really powerful.
We'll just look at one really simple example, you can dig in deeper if you'd like by reviewing the MDN Documentation
a[href="https://example.org"] {
color: green;
}
2
3
The syntax here is selector[attribute="value"]
. The above CSS would select any link on your page with the exact href
value of "https://example.org".
You can also check for the simple existence of an attribute like...
a[class] {
color: purple;
}
2
3
This would select any <a>
tag that had a class set. Even if the class attribute was empty. There are more practical examples, but, they would involve HTML we've not covered yet.
# Pseudo classes
# Link States
Anchor links get to use some special selectors called "Pseudo Classes." Because your browser keeps track of your history, every URL has a state, it's either not visited, visited, or active (being pressed). You can style these states like so...
a {
color: blue;
}
a:active {
color: lightblue;
}
a:visited {
color: gray;
}
2
3
4
5
6
7
8
9
# Hover
There's also a really cool pseudo selector that works on links called "hover". This allows us to change styles as users hover the mouse cursor over our links.
a:hover {
color: red;
}
2
3
But, hover actually works on just about any element, allowing us to do things like...
div:hover {
background-color: yellow;
}
2
3
One of the main pitfalls of hover is that it's works differently on touchscreens. There's no such thing as hover on a touch screen device, so it should never be used to hide and show content.
# Focus
The focus pseudo class is mostly for form elements and buttons. If you click into a text field, that field has focus.
input:focus {
border-color: blue;
}
2
3
# Child Selection
Given the following HTML...
<div class="content">
<p>Lorem....</p>
<p>Lorem...</p>
<p>Lorem...</p>
<ul>
<li>list item</li>
<li>list item</li>
<li>list item</li>
</ul>
</div>
2
3
4
5
6
7
8
9
10
...there are several pseudo selectors that allow us to pick elements based on their order.
first-child
lets us pick the first element when it's the first child of its parent.
.content p:first-child {
font-size: 1.5em;
}
2
3
This only works if the paragraph element is the first element directly inside that container. To select the first paragraph, even if there was something else before it, we can use first-of-type
or last-of-type
.
There's also last-child
, which works similarly...
.content p {
border-bottom: 1px solid gray;
}
.content p:last-child {
border-bottom: none;
}
2
3
4
5
6
Both of these can be really useful for building things like borders and margins you want in-between items, but not on the first or last item.
A more complicated one is nth-child
. It allows us to pass formulas in to select different repeating patterns of elements. We can also pass in the keywords "odd" or "even"
ul li:nth-child(odd) {
background-color: #eee;
}
2
3
The best way to get a feel for what you can do with nth-child
is to check out a few links from CSS Tricks...
There is also only-child
which will only select an item if it is the only child of its parent.
li:only-child {
margin-top: 1em;
margin-bottom: 1em;
}
2
3
4
That CSS would only work on an <ul>
or an <ol>
if they only had one <li>
inside.