CSS Selectors: The Full Reference Guide 🚀
Tags: css, webdev, codenewbie, beginners
Published: 2021-06-23 13:35:26

Hello, everybody! 🚀

Today we'll be covering CSS selectors in depth.
___
#Table of contents
- [What is a selector in CSS?](#what-is-a-css-selector)
- [Types of selectors](#types-of-selectors)
  - [Universal selector](#universal-selector)
  - [Type selector](#type-selector)
  - [Class selector](#class-selector)
  - [ID selector](#id-selector)
  - [Attribute selector](#attribute-selector)
- [Grouping selectors](#grouping-selectors)
  - [Group selector](#group-selector)
- [Combining selectors](#combining-selectors)
  - [Descendant combinator](#descendant-combinator)
  - [Child combinator](#child-combinator)
  - [General sibling combinator](#general-sibling-combinator)
  - [Adjacent sibling combinator](#adj-sibling-combinator)
- [Pseudo-classes](#pseudo-classes)
- [Pseudo-elements](#pseudo-elements)

___

#What is a selector in CSS? <a name="what-is-a-css-selector"></a>
A CSS selector is a __pattern__ used to __choose the HTML elements__ that we want to __style__. 

Speaking more technically, CSS selectors are able to __select those HTML elements to which a style ruleset will be applied__.

#Types of selectors <a name="types-of-selectors"></a>

##1. Universal selector <a name="universal-selector"></a>

__Syntax:__ _*_ { style properties }

This selector is represented by an __asterisk__ (*) and matches __all the elements__ in the HTML document. 

```html
<ul>
  <li>Computer Science Eng.</li>
  <li>Mathematics</li>
  <li>Physics</li>
</ul>
```
```css
* {
  border: 1px solid coral;
}
```
This will apply a 1px solid coral border to all elements in the document.

__Output:__
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pljk80n8hmj0ihv68wdk.png)

The border property shows very well the behavior of this selector. As you can observe in the image above, every element is now surrounded by a border, including the `<body>` element and the `<html>` element. 
___

The universal selector is also used to __avoid confusion__ and make your code __easier to read__. 

Let's take a look at the following examples:


```css
div :first-child {
  background-color: maroon;
}
```
```css
div:first-child {
  background-color: maroon;
}
```

These two code snippets look both pretty much the same, right?

Well, we only need to notice the __blank space__ between the type selector and the pseudo-class to realize that they're not exactly the same: the first one selects the first child of every `<div>` element and the second one selects the `<div>` elements that are first children themselves of another element.

Don't panic yet, we'll be talking more in detail about __pseudo-classes__ and __how selectors work__ later on 🙂

For now, just keep in mind that in this example there are two different element selectors working together to apply a styling rule. Everything will make sense later. Promise.

In any case, to distinguish one from the other and being able to see the blank space more clearly, __we can make use of the universal selector__, as shown below:



```css
div *:first-child{
  background-color: maroon;
}
```

Speaking in terms of functionality, adding an asterisk symbol __does nothing__, but it's useful to quickly __identify the elements that are going to be targeted__ and to keep your code __neat and tidy__.

##2. Type selector <a name="type-selector"></a>

__Syntax:__ _elemType_ { style properties }

This selector matches __all elements that belong to the specified type__.

```html
<p>A paragraph</p>
<p>Another paragraph</p>
<p>One more paragraph</p>
```

```css
p {
  font-size: 1.5rem;
  color: deeppink;
}
```
This will apply a font size of 1.5rem and a deep pink color to all `<p>` elements. Easy and direct.

__Output:__
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lajufuf1sxcuqf7qh7v1.png)


##3. Class selector <a name="class-selector"></a>

__Syntax:__ _.classname_ { style properties }

This selector is represented by a __period__ (.) and matches __all elements that contain the specified class__.

```html
<div>
  <p class="deeppink">This is a deep pink paragraph</p>
  <p class="hotpink">This is a hot pink paragraph</p>
  <p class="pink">This is a regular pink paragraph</p>
  <p class="deeppink-bg">This is a paragraph with a deep pink background</p>
  <p class="hotpink-bg">This is a paragraph with a hot pink background</p>
  <p class="pink-bg">This is a paragraph with a regular pink background</p>
</div>
```

```css
.deeppink {
  color: deeppink;
}
.hotpink {
  color: hotpink;
}
.pink {
  color: pink;
}
.deeppink-bg {
  background-color: deeppink;
}
.hotpink-bg {
  background-color: hotpink;
}
.pink-bg {
  background-color: pink;
}

/* Group selector - Stay until the end to understand its
 behavior 😉 */
.deeppink-bg, .hotpink-bg, .pink-bg {
  color: white;
}

```
This will apply a different pink color variant to every `<p>` element depending on the class they contain, styling either their text or their background.

__Output:__

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jcqh7jakxg9aibe7jep4.png)

___
Another way to specify a class selector is __by appending the type of the element that contains the classname__ in front of the regular class selector.

Take a look at this example of a regular list:

```html
<ul>
  <li class="list-item">...</li>
  <li class="list-item">...</li>
  <li class="list-item">...</li>
</ul>
```
We could style every _list item_ like this:
```css
.list-item{
  padding: 5px;
}
```
Or like this:
```css
li.list-item{
  padding: 5px;
}
```

Note that in this specific case it wouldn't be necessary to use this method because all the elements that contain the _list-item_ class are `<li>` elements, so appending the element type wouldn't make any difference .

But let's have a look at this other example below:

```html
<section>
 <h1 class="big">List of animals</h1>
 <ul>
   <li><p class="big">Cat</p></li>
   <li><p class="big">Dog</p></li>
   <li><p class="big">Monkey</p></li>
   <li><p class="big">Dolphin</p></li>
   <li><p class="big">Frog</p></li>
 </ul>
</section>
```
In this example, we have different types of elements referencing the same class, so, in order to apply __different styling rules__ to each of them, __we need to specify the type of the elements__ that contain that class. Otherwise, the elements won't be targeted properly and, consequently, the styles we're trying to apply won't be displayed as expected.

So we should do something like the following to apply different rules depending on if the element is a heading or a paragraph: 

```css
h1.big {
  font-size: 3rem;
  color: coral;
}

p.big {
  font-size: 2rem;
  color: orange;
}
```
__Output:__
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/it9a9k8vsyosjziprhbv.png)


##4. ID selector <a name="id-selector"></a>

__Syntax:__ _#idname_ { style properties }

This selector is represented by a __hash__ symbol (#) and matches __the unique element that contains the specified id__.
```html
<div>
  <table id="users-table">
    <th>Users</th>
    <tr>
      <td>John Doe</td>
    </tr>
    <tr>
      <td>Jane Doe</td>
    </tr>
  </table>
  <table id="staff-table">
    <th>Staff</th>
    <tr>
      <td>Hannah Legend</td>
    </tr>
    <tr>
      <td>Daniel Oaks</td>
    </tr>
  </table>
</div>
```
```css
/* Type selector */
table {
  padding: 20px;
}
/* ID selectors */
#users-table {
  background-color: black;
  color: white;
}
#staff-table {
  border: 1px solid black;
}
```
This will apply a black background color and a white text color to the table that matches the id _users-table_, and a 1px solid black border to the table that matches the id _staff-table_. Both of them receive a padding of 20px based on their type.

__Output:__

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lxf6mgk56mc7bz7xwfc6.png)

>__Important:__ Even though HTML allows you to assign the same id value to several elements, __you shouldn't ever do it__.

>If you need to apply the same style to a bunch of different elements, __always use the class attribute__. You'll keep your code clean and will get rid of a possible confusion.

##5. Attribute selector <a name="attribute-selector"></a>

The attribute selector is more complex than the rest of the selectors and has __several syntaxes__ that can be applied to our HTML elements based on which __condition__ should be satisfied by them.

In other words, it matches __all the HTML elements which contain a specified attribute__ and whose value for that attribute __satisfies a given condition__.

###Attribute selector syntaxes

###Syntax 1
_[attr]_ { style properties }

Matches elements with the __specified attribute__.
```html
<nav>
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/blog">Blog</a></li>
    <li><a href="/contact">Contact</a></li>
    <li><a href="/about">About</a></li>
  </ul>
</nav>
```
```css
/* Type selector */
nav {
  background-color: darkslategray;
  padding: 10px;
}

/* Attribute selector */
a[href] {
  color: white;
  text-decoration: none;
}

```
This will apply a white color to every `<a>` element that contains the `href` attribute, regardless of its value, and removes the underline.

We're also styling the `<nav>` element with a background color and some padding by making use of the type selector.

__Output:__

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gv6kb7j9gqb0bshhrft3.png)


###Syntax 2
_[attr=value]_ { style properties }

Matches elements whose __value for _attr_ is exactly__  ___value___.
```html
<form>
  <label for="username">Username</label>
  <input id="username" type="text" placeholder="Username" />
  <label for="password">Password</label>
  <input id="password" type="password" placeholder="Password" />
</form>
```
```css
input[type="text"] {
  color: chocolate;
}
```
This will apply a chocolate text color to every `<input>` element that has the `type` attribute with an exact value of _text_.

__Output:__

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/98clr2noel3w93i126t4.png)

___

We could as well use this syntax to __emulate the ID selector__ (remember the example in section 4):

```css
[id="users-table"] {
  background-color: black;
  color: white;
}

[id="staff-table"] {
  border: 1px solid black;
}
```
>__Explanation:__ By using this attribute selector syntax, we are targeting elements that contain an _id_ attribute whose value is exactly _users-table_ or _staff-table_. We're using this one syntax because an element can only have one _idname_, so the value needs to be exact (=).

###Syntax 3
_[attr~=value]_ { style properties }

Matches elements whose __value for _attr_ is a list of words separated by blanks and one of them is exactly__ ___value___.
```html
<p lang="en-gb en-us en-ca en-au en-nz">Welcome!</p>
<p lang="fr-fr fr-ca fr-be">Bienvenue!</p>
```
```css
p[lang~="en-us"] {
  color: navy;
}
p[lang~="fr-fr"] {
  color: red;
}
```
This will apply a navy color to every `<p>` element whose value for `lang` is a list that contains the exact string _en-us_. Same for all `<p>` elements whose value for `lang` contains _fr-fr_, applying a red color in this case.

__Output:__

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0qn0t4xfsmcp08kgjcwq.png)
___
As well as the previous syntax, through which we could emulate the ID selector behavior, we can also use this one attribute syntax to __emulate the behavior of the class selector__:

```css
[class~="list-item"]{
  padding: 5px;
}
```

>__Explanation:__ By using this attribute selector syntax, we are targeting elements that have a _class_ attribute whose value is a list that contains the string _list-item_.

>We're using this specific syntax because an element can contain several classes and we're aiming at just one of them (~=). But even though the element had just one class, __the value for the class attribute always acts like a list of values__.

###Syntax 4

_[attr|=value]_ { style properties }

Matches elements whose __value for _attr_ is exactly__ ___value___ __or starts with__ ___value___ __followed by a hyphen__.
```html
<p lang="en-us">Hello</p>
<p lang="en-gb">Hello</p>
```
```css
p[lang|="en"] {
  background-color: cornflowerblue;
  color: antiquewhite;
}
```
This will apply a cornflower blue background color and an antique white text color to every `<p>` element that has a `lang` attribute whose value is exactly _en_ or starts with _en-_.

__Output:__

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4hs7uwkhop6l34ae1ibe.png)

###Syntax 5
_[attr^=value]_ { style properties }

Matches elements whose __value for _attr_ starts with__ ___value___.
```html
<a href="#list1">Go to list 1</a>
<a href="#list2">Go to list 2</a>
<section>
  <h1>Lists</h1>
  <div id="list1">
    <h1>List 1</h1>
    <ul>
      <li>Milk</li>
      <li>Butter</li>
      <li>Eggs</li>
      <li>Sugar</li>
    </ul>
  </div>
  <div id="list2">
    <h1>List 2</h1>
    <ul>
      <li>Oranges</li>
      <li>Lemons</li>
      <li>Strawberries</li>
      <li>Apples</li>
    </ul>
  </div>
</section>
```
```css
a[href^="#"] {
  color: crimson;
  font-size: 2rem;
}
```
This will apply a crimson color and a font size of 2rem to every `<a>` element that has a `href` attribute whose value starts with _#_.
__Output:__
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ej7ue7fvtvm7ml5cojma.png)

###Syntax 6
_[attr$=value]_ { style properties }

Matches elements whose __value for _attr_ ends with__ ___value___.
```html
<a href="css-selectors-guide.pdf">CSS Selectors Guide</a>
```
```css
a[href$=".pdf"] {
  color: slateblue;
}
```
This will apply a slate blue color to every `<a>` element that has a `href` attribute whose value ends with _.pdf_.
__Output:__

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vemqc0qkwnfbeacap4xr.png)


###Syntax 7
_[attr*=value]_ { style properties }

Matches elements whose __value for _attr_ contains at least one occurrence of__ ___value___.
```html
<div class="small-box">
  <p>This is a small box</p>
</div>
<div class="big-box">
  <p>This is a big box</p>
</div>

```
```css
div[class*="box"] {
  background-color: burlywood;
}
```
This will apply a burlywood background color to every `<div>` element that contains a `class` attribute whose value has at least one occurrence of the string _box_.

__Output:__

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v9ocd7x3jzxr5hc15chv.png)

#Grouping selectors <a name="grouping-selectors"></a>

Grouping selectors in CSS is basically used to __put together__ those elements of different type or with different id/classes that we want to apply the __same style properties__ to.

Additionally, by using this technique, we'll get rid of redundancy and our code will be __clean__, __concise__ and __organized__.

##Group selector <a name="group-selector"></a>
__Syntax:__ _elem1, ..., elemN_ { style properties }

This selector is represented by a __comma__ (,) and matches __all the elements stated in the list__ and applies the same ruleset to all of them.
```html
<h1>Computer Science Engineering</h1>
<h2>List of courses</h2>
<ul>
  <li>Algebra</li>
  <li>Calculus</li>
  <li>Physics</li>
  <li>Discrete Mathematics</li>
  <li>Introduction to Programming</li>
</ul>

```
```css
h1, h2, li {
  color: darkred;
}
```
This will apply a dark red color to every `<h1>`, `<h2>` and `<li>` element.

__Output:__
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3hvbszl13m7vfy7f1uvm.png)

#Combining selectors <a name="combining-selectors"></a>

CSS selectors can also be combined. By combining selectors, then we can define __CSS combinators__.

CSS combinators are used to __establish a relationship between different selectors__ and are very useful to make your element selection __more targeted__.

##1. Descendant combinator <a name="descendant-combinator"></a>
__Syntax:__ _elem1 elem2_ { style properties }

This combinator is represented by a __single space__ ( ) and matches __all _elem2_ that are descendants of__ ___elem1___.

Consider the following navigation:
```html
<nav>
  <ul>
    <li><a>Home</a></li>
    <li>
      <a>People</a>
      <ul>
        <li><a>Students</a></li>
        <li>
          <a>Faculty members</a>
          <ul>
            <a>Discrete Mathematics</a>
            <a>Programming</a>
            <a>Physics</a>
            <a>Algorithms</a>
          </ul>
        </li>
        <li><a>Staff members</a></li>
      </ul>
    </li>
    <li><a>About</a></li>
    <li><a>Contact</a></li>
  </ul>
</nav>
```
```css
nav a {
  border: 1px solid crimson;
  color: darkslateblue;
  font-size: 1.5rem;
  font-weight: bold;
}
```
This will apply a 1px solid crimson border, a dark slate blue color, a font size of 1.5rem and a bold font weight to every `<a>` element that is descendant of a `<nav>` element, __regardless of how nested they are__.

__Output:__

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2p6xm0nqrlni7anhvark.png)

##2. Child combinator <a name="child-combinator"></a>
__Syntax:__ _elem1 > elem2_ { style properties }

This combinator is represented by a __prompt__ (>) and matches __all _elem2_ that are direct children of__ ___elem1___.
```html
<div class="box">
  <p>This is a direct child of .box</p>
  <div>
    <p>This is not a direct child of .box</p>
  </div>
  <p>This is another direct child of .box</p>
</div>
```
```css
.box > p {
  color: darkgoldenrod;
}
```
This will apply a dark golden color to every `<p>` element that is a direct child of any element that has the class _box_, so, in this HTML example, the first and last `<p>` elements will be selected, but not the one in the middle.

__Output:__

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hpmqn5iqgv3iob6w0bds.png)





##3. General sibling combinator <a name="general-sibling-combinator"></a>
__Syntax:__ _elem1 ~ elem2_ { style properties }

This combinator is represented by a __tilde__ (~) and matches __all _elem2_ that are siblings to__ ___elem1___ __and come after it__.



```html
<img src="blue-mug.jpeg" alt="a regular blue coffee mug" />
<p>Blue mug</p>
<p>Price: $15</p>
```

```css
img ~ p {
  color: darkblue;
}
```

This will apply a dark blue color to every `<p>` element which is a sibling of any `<img>` element and comes after it. In this example, both `<p>` elements will be selected.

__Output:__
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fzd07tw58z4i6dwq725o.png)



##4. Adjacent sibling combinator <a name="adj-sibling-combinator"></a>

__Syntax:__ _elem1 + elem2_ { style properties }

This combinator is represented by a __plus__ symbol (+) and matches __all _elem2_ that are siblings to__ ___elem1___ __and appear immediately after it__.



```html
<img src="blue-mug.jpeg" alt="a regular blue coffee mug" />
<p>Blue mug</p>
<p>Price: $15</p>
```


```css
img + p {
  color: darkblue;
}
```
In this case, only the first `<p>` element will be selected, since the second one doesn't appear immediately after the `<img>` element.

__Output:__
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6he4xnv2xj565trggu7p.png)




#Pseudo-classes <a name="pseudo-classes"></a>
A CSS pseudo-class is a keyword that is added to a selector and __defines a special state__ of the selected elements.

__Syntax:__ _elem:pseudo-class_ { style properties }

This selector is represented by a __colon__ (:).

```html
<h1>Shopping list</h1>
<ul>
  <li>Milk</li>
  <li>Butter</li>
  <li>Eggs</li>
  <li>Sugar</li>
</ul>
```
```css
li:hover {
  background-color: black;
  color: white;
}
```

In this example, we're applying a black background color and a white text color to every `<li>` element when the cursor hovers over it.

Take a look at what happens when we hover over the _Butter_ element:

__Output:__
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kadphf9gvfhu0hab6vlc.png)





Some of the __most common CSS pseudo-classes__ are:

`:active`, `:hover`, `:focus`, `:disabled`, `:checked`, `:first-child`, `:nth-child`, `:first-of-type`.


#Pseudo-elements <a name="pseudo-elements"></a>
A CSS pseudo-element is a keyword that is added to a selector to __style a specific part__ of the selected elements.

__Syntax:__ _elem:pseudo-element_ { style properties }

This selector is represented by a __double colon__ (::).
```html
<p>CODE</p>
```
```css
p::before{
  content: "_";
}
```

In this example, we're appending an underscore symbol in front of every `<p>` element.

__Output:__
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7p6dm0v4obsehzpedvf8.png)

Some of the __most common CSS pseudo-elements__ are:

`::after` (can also be written as `:after`), `::before` (can also be written as `:before`), `::marker`, `::placeholder`, `::first-letter`.

___

And that's pretty much it 🙂

I hope this reference guide has been helpful for you.

You can also check out the following related posts about CSS selectors on [@underscorecode](https://instagram.com/underscorecode) Instagram account:

{% instagram CP8znDHsMmV %}{% instagram CQErX0PMe1I %}{% instagram CQWagoQsEdV %}
_____

🎉 Don't forget to follow @underscorecode on [Instagram](https://instagram.com/underscorecode) and [Twitter](https://twitter.com/underscorecode) for more daily webdev content 🖥🖤