# > . , * + ~ : { } ( ) [ ]
CSS selectors
A visual reference guide
Originally released in 1994, Cascading Style Sheets (CSS) have become a feature-rich language capable of laying out a webpage, creating complex animations, and much more. These patterns allow web designers to dictate how styles apply to specific HTML elements.
There are many different types of CSS selectors, each with their own unique syntax. Together they tell the browser which elements to apply CSS property values to.
CSS is not a conventional programming language. Its more like a to-do list for the browser: You are saying to the browser, here is a list of things I want you to find. Once the browser finds those things, the CSS instructs the browser to go through the subset list and make changes to those things.
Pick me
Selectors can be broadly divided into six categories:
- Universal selector (*)
- Individual selector (tag name)
- Class (.) and Id (#) selector
- Group selector (,)
- Combined selector (⎵ > + ~)
- Pseudo selector (: or ::)
Universal selector: * { }
Selects everything. Useful for resetting styles to flatten browser inconsistencies and provide a stable foundation to build on. Typically starts a stylesheet before custom styles are added.
Individual type selector: a { }
Select elements by type (tag name). In this example, we select all a
elements.
ID selector: #a { }
IDs shouldn't be used in selectors because these rules are too tightly coupled with the HTML and have no possibility of reuse. It's preferred instead to use classes in selectors and then apply a class to an element in the page.
Class selector: .a { }
Here is a great primer on using class names to add context to your HTML and create more reusable code.
Comma combinator selector: a, c { }
You can condense different CSS selectors with identical declarations into one rule using a comma separated list.
Combine universal selector: a * { }
CSS is read right to left.
The selector a * { }
can be as read "all elements that are descendants of a
element".
Child selector: a > b { }
The child selector matches only those elements matched by the second selector that are the direct children of elements matched by the first 🤯
Remember that CSS is read right to left, so here we match all b
elements that follow an a
element.
Descendant selector: a b { }
This means “any b
element that is a descendant of an a
element.”
Combine descendant & ID selector: #a b { }
Combine the class selector: b.x { }
This means “any b
element that has a class ofx
.”
Adjacent sibling selector: a + b { }
Matches the second element only if it immediately follows the first element, and both are children of the same parent element.
General sibling selector: a ~ b { }
Selects all elements that are siblings of a specified element. Again, both must be children of the same parent element.
Who's there?
Along with traditional CSS selectors, we also have pseudo-classes and pseudo-elements. Pseudo-classes allow us to define styles based on an element's state or its relation to other elements. Think of things like hovering over a button or selecting the first item in a list. Pesudo-classes start with a colon (:) character .
First child pseudo selector: b:first-child { }
or
first-child
* In the second diagram, the first-child is a
element, not b
element, so there is nothing to be selected.
Only child pseudo selector:
b:only-child { } or a :only-child { }
Last child pseudo selector: b:last-child { }
or
* In the second diagram, the last-child is c
element, not b
element, so there is nothing to be selected.
Nth child pseudo selector:
b:nth-child(2) { }
1
2
3
or
1
2
3
or
1
2
3
* In the third diagram, the nth-child(2) is a
element, not b
element, so there is nothing to be selected.
a :nth-child(2) { }
Select the nth-child(2) that is a descendent of an a
element.
First of type selector: b:first-of-type { }
Nth last child selector:
a :nth-last-child(2) { } or c:nth-last-child(2) { }
4
3
2
1
a:nth-last-child(2) { } or b:nth-last-child(2) { } or d:nth-last-child(2) { }
4
3
2
1
* In this diagram, nth-last-child(2) is c
element, not b
element. So there is nothing to be selected.
Nth of type selector:
a:nth-of-type(2) { }
1
0
2
0
3
0
4
a:nth-of-type(even) { }
1
0
2
0
3
0
4
a:nth-of-type(odd) { }
1
0
2
0
3
0
4
a:nth-of-type(2n+1) { }
1
0
2
0
3
0
4
2n+1
* n is an every positive integer or zero value.
Only of type selector: b:only-of-type { }
Last of type selector:
b:last-of-type { }
a :last-of-type { }
or
.x:last-of-type { }
or
* Those items won’t be selected as no .x is presented
Empty selector: a:empty { }
🤘
* empty indicates no children elements or text.
Negation pseudo-class selector:
a:not(.x) { }
a:not(:last-of-type) { }
Attribute selector:
The [attribute] selector is used to select elements with a specified attribute.
[for] { }
This means "Select all elements that have the [for] attribute.
a[for] { }
This means "Select all a
elements that have the [for] attribute.
Attribute value selector: a[for=“x”] { }
This means "Select all elements that have a [for] attribute equal to "x".
Attribute starts selector: [for^=“x”] { }
Now we're getting funky. The [attribute^=value] selector matches every element whose attribute value begins with a specified value.
Attribute ends selector: [for$=“x”] { }
Same thing as above, but this time we match elements that end with a specified value.
Attribute wildcard selector: [for*=“x”] { }
Used to select elements whose attribute value contains the specified substring. This example shows how to use a wildcard to select all elements with a class that contains x. This could be at the start, the end or in the middle of the class.