Knowing how to use CSS selectors effectively is useful for Frontend developers. I created a cheatsheet of commonly-used selectors.
Although other CSS selector cheatsheets exist (see resources), I find them either lacking grouping/organization, missing examples, or have too much information.
That's why I group this cheatsheet into 8 different types. At the start of each group you'll find HTML snippet. Use that HTML snippet with that group (and play around with it!). The list is not comprehensive and I intend it to be. The list below should cover most development needs.
# Table of Contents - [Navigations](#navigations) * [Basic Selectors](#basic) * [Descendant Selectors](#descendant) * [Multiple Selector](#multiple) * [Combination Selector](#combination) * [Sibling Selectors](#sibling) * [Pseudo Selectors](#pseudo) * [Pseudo Selectors (links and inputs)](#pseudo2) * [Attribute Selectors](#attribute) - [Resources](#resources)# Basic selectorsThey select element/id/class. They are also used most often and easiest to remember.
<div id="app">
<div class="container">
<p class="hello">Hello</p>
<p class="hola">Hola</p>
</div>
<div class="other">
I am left behind...
</div>
</div>
Element
. It selects any given element.p { color: blue; }
div { color: magenta; }
.class
. It selects all element containing given class name. .hello {
color: red;
}
#id
. It selects the element containing given HTML ID.#app {
color: red;
}
*
. It selects all elements. * {
color: yellow;
}
# Descendant selectorsThese are selectors for choosing descendants of any element.
<div class="container">
<div class="paragraph-container">
<p id="hola-id" class="hola-class">Hola world</p>
<p class="hello-class">Hello world</p>
<p class="hello-class again-class">Hello again world</p>
</div>
</div>
A B
. Selects any elements B that are descendants of A. The descendant can be nested really deep..container .hello-class {
color: red;
}
We can combine this with *
to get:
.paragraph-container * {
color: blue;
}
This selects everything inside .paragraph-container
A > B
. Unlike any descendant selector, this one only selects direct descendant/ child..paragraph-container > .hello-class {
color: blue;
}
While below won't work because .hello-class
in this scenario is not direct descendant:
.container > .hello-class {
color: blue;
}
# Multiple Selector<div class="container">
<div class="paragraph-container">
<p id="hola-id" class="hola-class">Hola world</p>
<p class="hello-class">Hello world</p>
<p class="hello-class again-class">Hello again world</p>
</div>
<p class="outside-class">I'm outside</p>
</div>
Multiple selectors allow us to select multiple unrelated elements together.
A, B, C, ...
. To select multiple elements/classes/ids, connect them with ,
:.outside-class, .again-class, .hola-class {
color: purple;
}
Combination selector allows you to choose very specific element using multiple references. A popular use-case is button highlight effect when hovered/ clicked by giving them an .active
class.
<div class="container">
<div class="paragraph-container">
<p id="hola-id" class="hola-class">Hola world</p>
<p class="hello-class">Hello world</p>
<p class="hello-class active">Hello again world</p>
</div>
<p class="outside-class">I'm outside</p>
</div>
AB
. This selects element containing BOTH A and B. The syntax looks like descendant selector, except this does not have space. p.active {
color: yellow;
}
We can combine anything, not just element and class:
p#hola-id {
color: blue;
}
.hello-class.active {
color: red;
}
# Sibling selectors These selectors target their siblings.<div class="container">
<div class="paragraph-container">
<p id="hola-id" class="hola-class">Hola world</p>
<p class="hello-class">Hello world</p>
<p class="hello-class again-class">Hello again world</p>
</div>
<p class="outside-class">I'm outside</p>
</div>
A + B
. Targets one sibling element placed immediately after that element. sibling1 + sibling2
#hola-id + .hello-class {
color: blue;
}
Note that CSS below won't work because .again-class
, although it is #hola-id
's sibling, is 2 elements away.
#hola-id + .again-class {
color: blue;
}
A ~ B
. Like adjacent sibling selector, but selects ANY sibling selector(s) after. The syntax ~
personally reminds me of shrugging 🤷♂️🤷♀️ - hence ~
is more relaxed than +
.#hola-id ~ .hello-class {
color: purple;
}
Note it doesn't work backwards (B ~ A
is not the same as A ~ B
):
.again-class ~ #hola-id {
color: red
}
<div class="container">
<div class="paragraph-container">
<p id="hola-id" class="hola-class">Hola world</p>
<p class="hello-class">Hello world</p>
<p class="hello-class again-class">Hello again world</p>
</div>
<p class="outside-class">I'm outside</p>
<ul id="list-id" class="list-class">
<li class="list-item-class">First</li>
<li class="list-item-class">Second</li>
<li class="list-item-class">Third</li>
<li class="list-item-class">Fourth</li>
<li class="list-item-class">Fifth</li>
</ul>
<div class="single-paragraph-container">
<p>I'm the only child of this span</p>
</div>
</div>
A:first-child
. It selects each target that is the first child of its parent. The definition is a bit confusing at first. The way I think of it, the target (A
) must itself be a first child of a parent. note the phrase: the first child of its parent.
li:first-child {
color: blue;
}
The above one works because li
has a parent: ul
. li
is also ul
's first child.
What would happen if you target ul
?
ul:first-child {
color: red;
}
Nothing happens. This is because although ul
has a parent (div
with class container
), ul
is not a first child (it is a 3rd child).
The code below will work because .paragraph-container
is .container
's first child.
.paragraph-container:first-child {
color: red;
}
A:last-child
. Works like first-child, except instead of first, our target must be a last child.li:last-child {
color: purple;
}
A:only-child
. Selects all A
that is the only child of its parent. Similar to first and last child selectors. Except the target must not have any siblings.p:only-child {
color: red;
}
Note although we have several p
elements, only the last one applies because the other p
elements are not its parent's only child. They have siblings.
A:nth-child(n)
. It selects each target that is the nth child of its parent.li:nth-child(2) {
color: red;
}
Let's try with p
now:
p:nth-child(2) {
color: red;
}
Can you see why two p
elements changed colors?
A:nth-last-child(n)
. It is similar to the nth child selector, except it counts from last.li:nth-last-child(2) {
color: red;
}
A:not(B)
. Selects all A
element that is not B
.p:not(.outside-class) {
color: blue;
}
A:first-of-type
. It selects the first element of its type among its sibling elements. This one sounds similar to :first-child
when I first hear about it. To feel how it is different, let's play around:
li:first-of-type {
color: blue;
}
Ok, that's not a good example because it shows same result as li:first-child
😅. Let's do another example:
p:first-of-type {
color: red;
}
This one is better. Compare that with p:first-child
. You'll notice that the middle p
turns red using first-of-type
and it doesn't using first-child
. This is because the middle p
is the first p
element type among its siblings 💡.
A:last-of-type
. Just like the above, but opposite.li:last-of-type {
color: blue;
}
A:nth-of-type(n)
. Just like the two above, but this selects nth element of that time.li:nth-of-type(2) {
color: blue;
}
Let's try different element:
p:nth-of-type(2) {
color: blue;
}
If we changed it to p:nth-of-type(1)
, it behaves just like first-of-type
. Also if we changed it to p:nth-of-type(4)
, nothing changes color - this is because there is no 4th p
element among siblings.
A:only-of-type
. Selects the element with ONLY that type (no siblings)p:only-of-type {
color: purple;
}
Notice two p
elements change color. This is because there are two p
elements that have no sibling with the same type.
Below are a list of more pseudo selectors. These are commonly associated with links (a
) (although they may work with non-link elements).
<div id="app">
<a class="cheesyLink" href="#">I like cheese</a>
<a class="sweetLink" href="#">I like donut</a>
<div class="burger">I like cheezburger</div>
<div class="container">
<form onsubmit="event.preventDefault()">
<input class="myinput"type="text" />
<input class="mysubmit" type="submit" />
</form>
</div>
</div>
A:hover
. Selects hovered element. Commonly used to highlight links.a:hover {
color: red;
}
It doesn't have to be a
tag though. This selector works with anything.
.burger:hover {
color: red;
}
A:focus
. Selects a focused element. Usually works with input
.input:focus {
background: red;
}
A:active
. Selects an element that is in active state.Note as you click it, the background changes.
.cheesyLink:active {
background: red;
}
A:link
. It selects all links that have not been clicked yeta:link {
background: blue;
}
# Attribute selectorsAttribute selector is useful for selecting HTML attributes.
<div for="chocolate">Chocolate</div>
<div for="peanut">Peanut</div>
<div for="butter">Butter</div>
<div>Jelly</div>
A[B]
. Selects all elements A
with attribute B
.div[for] {
color: red;
}
A[B="C"]
. Selects all element A
with attribute B
with value C
div[for="chocolate"]{
color: blue;
}
A[B^="C"]
. Selects all element A
with attribute B
with C
starting value. Note that ^
is Regex for starting string.div[for^="cho"] {
color: magenta;
}
A[B$="C"]
. Selects all element A
with attribute B
with C
ending value. Note that $
is Regex for ending string.div[for$="er"] {
color: yellow;
}
A[B*="C"]
. Selects all element A
with attribute B
containing C
value. Note that *
is usually a wildcard in regex and globs.div[for*="ut"]{
color: cyan;
}
So there you have it folks! If you need more references, feel free to check out the resources below. If you think a different way I can make this cheatsheet more practical, feel free to comment below.
# Resources: