CSS Selectors

Reading Time: 5 minutes

CSS selectors are very used to apply specific rules to a bunch of elements, either to a set of two or more elements or to a unique element, thus it is very important you know how and where to use them.

What's a CSS Selector?

W3 Definition

“Selectors are used to selecting elements in an HTML or XML document, in order to attach (style) properties to them.”


The most used CSS selectors are by class and by id, nevertheless, there are many selectors which you can use easily and fairly to add styles into a set of elements.

In this blog, I will be talking about different selectors beyond class and id.

Let’s take a look at all the different kinds of available selectors along with a brief description of each one of them.

The Selectors

div p → Descendant Selector

It selects an element inside another element.
This selects all the p elements inside of div.

div p {

  bacground-color: #fff;

  display: flex;

  text-aling: center;


#user.admin / ul.class → Descendant Combinator

You can combine any selector with the descendent selector.

#user.admin selects all elements with id="user" that also have class="admin".

ul.list selects all ul elements that have class="list".

#user.admin, ul.list {

  border: none;

  text-align: left;

  width: 100%;


* → The Universal Selector

You can select all the elements with the universal selector.
div * selects any element inside all div elements.

ul.something * selects every element inside all ul class="something" elements.

div * {

  color: #F8386D;

  line-height: 26px;


div + p → Adjacent Sibling Selector

It selects an element that directly follows another element.

This selects the p elements that directly follow div tag. Elements that follow another one are called siblings.

span + .intro selects every element with class="intro" that directly follows a span.

span + .intro {

  color: rgb(182,216,218);

  background: #D37C71;


div ~ p → General Sibling Selector

You can select all siblings of an element that follow it. This is like the Adjacent Selector (div + p), but this one gets all of the following elements instead of one.

div ~ p {

  display: flex;

  align-items: center;


div > h1 → Child Selector

It selects direct children of an element.

You can select elements that are direct children of other elements.
div > h1 selects all h1 that are direct children div.

div > h1 {

  font-size: 16px;

  width: 100%;

:first-child / :last-child → First, last Child Pseudo-selector

You can use these selectors to select an element that is the first child / last child element inside another element.

ul li:first-child selects all first child p elements that are in a div.

ul li:last-child selects the last li elements inside of any ul.

ul li:first-child {

  padding: 5em;

  margin: 0 1px 0 -4px;

ul li:last-child {

  font-size: 16px;

  text-decoration: none;


:only-child→ Only Child Pseudo-selector

It selects any element that is the only element inside of another one.

ul li:only-child selects the only li element that is in a ul.

ul li:only-child {

  color: #1264a3;

  padding: 0 12px 0 15px;


:nth-child(A) → Nth Child Pseudo-selector

It selects the nth (Ex: 1st, 3rd, 12th, etc.) child element in another element.

div p:nth-child(8) selects every p element that is the 8th child of a div element.

div p:nth-child(8) {

  color: #FA6887;

  height: 26px;

  width: 100%;


:nth-last-child(A) → Nth Last Child Selector

It selects the children from the bottom of the parent.

ul li:nth-last-child(2) selects all second-to-last child elements.

ul li:nth-last-child(2) {

  display: flex;

  font-size: 16px;

  justify-content: center;


:first-of-type → First of Type Selector

It selects the first element of that type within another element.

span:first-of-type selects the first span in any element.

span:first-of-type {

  display: block;

  font-size: 18px;

  margin-top: 3rem;


:nth-of-type(1) → Nth of Type Selector

It selects a specific element based on its type and order in another element, either 'even' or 'odd' instances of that element.

.example:nth-of-type(odd) selects all odd instances of the class=”example”.

div:nth-of-type(2) selects the second instance of a div.

.example:nth-of-type(odd) {

  line-height: 1.5;

  padding: 10px 0;

  text-align: center;


:nth-of-type(An+B) → Nth-of-type Selector with Formula

The nth-of-type formula selects every nth element, starting the count at a specific instance of that element.

span:nth-of-type(6n+2) selects every 6th instance of a span, starting from (and including) the second instance.

span:nth-of-type(6n+2) {

  color: #08c;

  height: 26px;


:only-of-type → Only of Type Selector

It selects the only element of its type within another element.

p span:only-of-type selects a span within any p if it is the only span in there.

p span:only-of-type {

  font-size: 16px;

  font-weight: 400;

  line-height: 26px;


:last-of-type → Last of Type Selector

It selects each last element of that type within another element.

p span:last-of-type selects the last span in every p.

p span:last-of-type {

  font-size: 85%;

  padding: 16px;


:empty → Empty Selector

It selects elements that don't have any other elements inside of them.

div:empty selects all empty div elements.

div:empty {

  display: flex;

  justify-content: flex-end;


:not(X) → Negation Pseudo-class

You can use this to select all elements that do not match selector "X".

div:not(:first-child) selects every div that is not a first child.

:not(.big, .medium) selects all elements that do not have class="big" or class="medium".

:not(.big, .medium) {

  position: relative;

  left: 30px;


A[attribute] → Attribute Selector

It combines the attribute selector with another selector by adding it to the end.

input[disabled] selects all input elements with the disabled attribute.

input[disabled] {

  position: absolute;

  z-index: -1;


[attribute="value"] → Attribute Value Selector

input[type="checkbox"] selects all checkbox input elements.

input[type="checkbox"] {

  font-size: 16px;

  margin-top: 3rem;


[attribute^="value"] → Attribute Starts With Selector

.user[category^="Eng"] selects elements with class="user" and either category="Eng" or category="Engineer".

.user[category^="Eng"] {

  background: #fff;

  font-size: 3em;


[attribute$="value"] → Attribute Ends With Selector

img[src$=".jpg"] selects all images which end with .jpg.

img[src$=".jpg"] {

  display: flex;

  align-items: center;


[attribute*="value"] → Attribute Wildcard Selector

img[src*="/party/"] selects all image elements that show images from the "party" folder.

[class*="sales"] selects all elements with "sales" in their class, such as class="DM-sales" or class="Post-sales".

img[src*="/party/"] {

  display: flex;

  align-items: center;


Selectors hierarchy

With these CSS selectors, now you can give styles with other different selectors to class or id, but, how do we know which of them has a major hierarchy when we apply styles? Below, you will find the list containing priority ordering from highest to lowest, on the side, I put their  calculating CSS specificity.

  1. Inline styles (1,0,0,0 points).

  2. IDs: identifier for element (0,1,0,0 points).

  3. Attributes, classes and pseudo-classes → .class, [attributes] and div:hover, div:active (0,0,1,0 points).

  4. HTML elements and Pseudo-elements → div, p, p:after, p:before (0,0,0,1 point).


  • The universal selector (*) has no specificity hierarchy.

  • Pseudo-elements (e.g. :first-line) get 0,0,0,1 unlike their pseudo-class brethren which gets 0,0,1,0.

  • The pseudo-class:not() adds no specificity by itself, only what’s inside its parentheses.

In the next chart, I show you some examples of the hierarchy of selectors, (some of them have more hierarchy than others), and their value according to their calculating CSS specificity mentioned above.

Selector Specificity value
li { } 1 (one element – 0,0,0,1)
body#home div#featured p.text { } 213 (two id selectors, class selector, 3 HTML selectors – 0,2,1,3)
li:first-line { } 2 (one element, one pseudo-element – 0,0,0,2)
ul li { } 2 (two elements – 0,0,0,2)
ul ol+li { } 3 (three elements – 0,0,0,3)
h1 + *[rel=up] { } 11 (one attribute, one element – 0,0,1,1)
ul ol li.first { } 13 (one class, three elements – 0,0,1,3)
li.last.featured { } 21 (two classes, one element – 0,0,2,1)
style="" 1000 (one inline styling – 1,0,0,0)
div p.big-text { } 12 (two HTML selectors and a class selector – 0,0,1,2)
#author-name { } 100 (one id selector – 0,1,0,0)
body #blog-list .post p { } 112 (id selector, class selector, 2 HTML selectors – 0,1,1,2)
navbar ul.menu li#first a:not(:visited) { } 133 (id selector, 2 class selectors, 1 pseudo-class, 3 HTML selectors – 0,1,3,3)
#footer *:not(nav) li { } 102 (one id, two elements – 0,1,0,2)

Wrapping Up

As you can see in the examples, there are many selectors which you can use to give appropriate styles to a bunch of elements without using class or id. Also, we talk about selectors hierarchy which many times overrides our styles and adds undesired styles to our elements, thus, it’s necessary to know which of them has a major hierarchy to can give the appropriate styles.

If you want to practice more with CSS selectors, I recommend that you follow the GitHub course.

Thank you for reading, and keep learning!

You May Also Like