CSS selectors

# > . , * + ~ : { } ( ) [ ]

Cascading Style Sheets (CSS) is the language for visual style and design on the web. CSS has a long history on the web dating back to 1994. In the time since, CSS has become a feature-rich language capable of laying out a webpage, creating complex animations, and much more.

CSS is not a conventional programming language. While it does have some features found in other programming languages, such as variables and math, CSS is dependent on HTML to work. CSS’s purpose is to provide visual modifications to HTML. The CSS language is 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.

Universal Selector: * { }

a
b
c
d

Selects everything. I use this to reset default CSS styles before adding my own.

Combine Universal Selector: a * { }

a
b
c
a
b
a
b

CSS is read right to left.
The selector a * { } can be as read "all elements that are descendants of a element".

Type Selector: a { }

a
b
c

Select elements by type. In this example, we select all a elements.

Child Selector: a > b { }

a
b
c
a
b
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 { }

a
b
c
a
b
a
b

This means “any b element that is a descendant of an a element.”

ID Selector: #a { }

#a
#b
#c

* 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 much preferred to use classes in selectors and then apply a class to an element in the page.

Combine Descendant & ID Selector: #a b { }

#a
b
c
a
b
a
b

Class Selector: .a { }

.a
.b
.c

Here is a great primer on using class names to add context to your HTML and create more reusable code.

Combine the Class Selector: b.x { }

a.x
b.x
c.x

This means “any b element that has a class ofx.”

Comma Combinator Selector: a, c { }

a
b
c
d

You can condense different CSS selectors with identical declarations into one rule using a comma separated list.

Adjacent Sibling Selector: a + b { }

a
b
b
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 { }

a
b
b
c
b

Selects all elements that are siblings of a specified element. Again, both must be children of the same parent element.

First Child Pseudo Selector: b:first-child { }

b
b
b

or

a
b
b

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 { }

a
b
a
a
b
a
a
b
c

Last Child Pseudo Selector: b:last-child { }

b
b
b

or

b
b
c

* 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

b
b
b

or

1

2

3

a
b
b

or

1

2

3

b
a
b

* 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) { }

a
a
b
c

Select the nth-child(2) that is a descendent of an a element.

First of Type Selector: b:first-of-type { }

a
b
a
b

Nth Last Child Selector:

a :nth-last-child(2) { } or c:nth-last-child(2) { }

a
a
b
c
d

4

3

2

1

a:nth-last-child(2) { } or b:nth-last-child(2) { } or d:nth-last-child(2) { }

a
a
b
c
d

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

2

3

4

a
b
a
b
a
b
a

a:nth-of-type(even) { }

1

2

3

4

a
b
a
b
a
b
a

a:nth-of-type(odd) { }

1

2

3

4

a
b
a
b
a
b
a

a:nth-of-type(2n+1) { }

1

2

3

4

a
b
a
b
a
b
a

2n+1

* n is an every positive integer or zero value.

Only of Type Selector: b:only-of-type { }

a
b
a
b
b
a
a
b
c

Last of Type Selector:

b:last-of-type { }

a
b
b

a :last-of-type { }

a
b
b
b

or

a
b
b
c
c
d

.x:last-of-type { }

a
b
c
b.x
c.x
b.x
c.x

or

a
b.x
c.x
b.x
c.x
b
c

* Those items won’t be selected as no .x is presented

Empty Selector: a:empty { }

a
a
a
b
b

🤘

* empty indicates no children elements or text.

Negation Pseudo-class Selector:

a:not(.x) { }

a
b
a.x
b.x

a:not(:last-of-type) { }

a
b
a
a

Attribute Selector:

The [attribute] selector is used to select elements with a specified attribute.

[for] { }

a
a[x]
a[y]
a[z]

This means "Select all elements that have the [for] attribute.

a[for] { }

a
a[x]
b[y]
c[z]

This means "Select all a elements that have the [for] attribute.

Attribute Value Selector: a[for=“x”] { }

a
a[x]
a[y]
a[z]

This means "Select all elements that have a [for] attribute equal to "x".

Attribute Starts Selector: [for^=“x”] { }

[x]
[xy]
[yz]
[zx]

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”] { }

[x]
[xy]
[yz]
[zx]

Same thing as above, but this time we match elements that end with a specified value.

Attribute Wildcard Selector: [for*=“x”] { }

[x]
[xy]
[yz]
[zx]

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.