CSS Selectors guide

CSS Selectors guide

Learn about the CSS selectors that will cover 90% of use cases.

ยท

8 min read

Overview

In CSS there are various ways to select an element and apply specific styles to them, some are straightforward and some are not.

Most of the time a simple selector works, but while working on a project there may come a situation where we'll need some CSS selectors trickery.

We'll be discussing some of them here which will cover 90% of the cases and the rest you can build up yourself using the same tools.

Note: You don't have to memorize anything, the idea is to keep the possibilities in the back of your head and refer to this blog or any documentation when in need.

Prerequisite

Basic HTML and CSS
( Complete the first two courses on freeCodeCamp to get started )


๐Ÿ‘‰ Basic Selectors

1. Universal

Universal selector * is used to select any type of element.

Common use

  1. To reset browser pre-applied CSS.
  2. To select all child or sibling elements.

Example

2. Element Selector

If we want to select all element of a particular type then element selector is the way to go.

/* targets all paragraph elements */
p {                 
  font-size: 14px;
}
/* targets all span elements */
span {
   background-color: magenta;
   color: white;
}

3. Class Selector

We can target specific elements by their class names. A dot (.) prefix is used to indicate that selector is a class.

.first-section {
  color: red;
}

As in the universal selector example, we have used, the first-section class to target the div and change its content color to red.

We can join selectors to give more specificity.

/* All <p> that has .big-text class  */
p.big-text {
  font-size: 2rem;
}

/* All <span> that has .big-text class */
span.big-text {
  font-size: 1.8rem;
}

We can join two classes also to make it like an AND operator which says that only select the element that has all the classes joined

.big-text.underlined.p-4 {
    border: 1px solid magenta;
}

4. ID Selector

id selector is used by prefixing a hash (#) symbol to the id of the element.

#logo {
  width: 200px;
  height: 200px;
}

in the above example, we are targetting the element with the logo id.

Just like class, ids can also be joined together

/* select div with id container */
div#container {
  margin: 4px 6px;
}

Although ids are unique so we don't have to write a selector like the above example.

๐Ÿค” Difference between class and id selector

class can be given to multiple elements but the id is unique and two elements can't have the same ids.

๐Ÿ’กAs good practice, one should use class over id as much as possible.

๐Ÿ‘‰ Combinators

1. Descendent Combinator

A descendent combinator combines two selectors by a space " ".

The second selector gets selected if that selector has an ancestor element that matches with the first selector.

Confusing? It's not actually, let's learn with an example

Example

In the above example, all the span with .parent ancestor gets selected and the text color changes to green, but the span elements without .parent ancestor have no effect.

What if we want to only select the child of an element and not all the descendants?

2. Child Combinator

A child combinator combines two selectors by the > sign.

Okay, so now we are able to select child and descendants of a selector is there any way to select siblings of that selector?

3. Sibling Combinator

There are two ways to select sibling elements, General Sibling and Adjacent Sibling.

General Sibling

~ sign is used to combine two selectors to target general siblings. The second selector gets selected if it's a sibling of the first selector.

From the above example, we can see that only the p element which is a sibling of div with .card class gets selected not the child or any other sibling's child.

One thing to note here is that the first p element doesn't get selected even though technically it's a sibling of .card. The reason is in CSS there is no way to select a previous sibling and parent from a child selector. We can only select a child from a parent element and the next sibling of an element as we've seen in previous discussions.

Adjacent Sibling

Suppose we don't want to target all the next siblings but only the one that is adjacent to an element, then we have to use the + sign to combine two selectors.

here only the p tag adjacent to .card gets selected.

๐Ÿ‘‰ Attribute Selector

So far we have seen many useful selectors and combinators but one selector still remains which is called the attribute selector. If we want to select an element having some specific attribute then that can be done using this selector.

Syntax

Syntax for attribute selector is like element[attribute].

Examples

  1. Attribute is present on element
    a[data-position] {
    color: magenta;
    }
    
  2. Attribute's value equals to
    a[href="orange.fruit"] {
    color: orange;
    }
    
  3. String is part of the attribute value
    a[href*="apple"] {
    color: red;
    }
    
  4. Attribute's value ends with
    a[href$=".veggie"] {
    color: green;
    }
    
  5. Attribute's value starts with
    a[href^="kiwi"] {
    color: violet;
    }
    
  6. Attribute contains
    li[class~="big"] {
    font-size: 24px;
    }
    

    DEMO

๐Ÿ‘‰ Pseudo Selectors

There are two subtypes in pseudo selectors

  • Pseudo-classes
  • Pseudo-elements

1. Pseudo-classes

A pseudo-class added to a selector specifies a specific state of the selected element. There are many pseudo-class but we're going to touch only a few of them which are frequently used.

:hover

/* change the color of <a> when the user hovers over it. */
a:hover {
    color: purple;
}

:focus

/* change the color of <a> when it is in focus (focus state can be achieved by using tab key) */
a:focus {
    color: purple;
}

:visited

/* color of a link that is already visited by the user */
a:visited {
    color: red;
}

:active

/* state of <a> when it is clicked on */
a:active {
    background-color: yellow;
}

:disabled

/* when button is in disabled state */
a:disabled {
    background-color: gray;
}

:root

This pseudo-class represents the element that is the root of the document. A common use of this pseudo-class is to declare CSS variables inside it so it gets available to every other selector.

:root {
    --primary-color: #bf90f2;
    --width-max: 1000px;
}

:not()

The :not() pseudo-class is used when we want to select all elements excluding the one that goes inside the parenthesis of :not().

/* Select any element that is not an h1 */
:not(h1) {
  color: #666;
}

We can also combine this selector with other selectors

/* select all <a> elements that don't have .active class */
a:not(.active){
  color: gray;
}

:first-child, :last-child and :nth-child()

  • The :first-child selects the first element in a group of sibling elements.

  • The :last-child selects the last element in a group of sibling elements.

  • The nth-child() selects the child at the position passed inside the parenthesis.

You can play around above code to make your understanding better.

:nth-child can do more as it accepts values other than numbers as positions

There are so many other pseudo-classes that can be useful to you but I've only covered those that are used frequently. If you want to learn more you can explore MDN Pseudo-classes page.

2. Pseudo-elements

Pseudo-elements are added to a selector to target a specific part of the element, for example, we can use::first-letter to target the first letter of the first line of a block-level element.

::after

::after creates a pseudo-element as the last child of the selected element. It is mostly used to add visual and cosmetic content to an element, for example, a notification icon on a button.

::before

::before works similarly as ::after pseudo-element, the difference is that it creates a pseudo-element as the first child of the selected element.

๐Ÿ’ช As a challenge, make the above pseudo-element from last-child to first-child and change its position to top-left of the button instead top-right.

One final thing...

What if we want to apply the same styles to multiple selectors? Don't worry, we also have a solution for that.

Grouping selectors

We can group selectors with , to apply the same styles.

div, section, article {
  padding: 1.2rem;
}

โœ”๏ธ Conclusion

Note that there are tons of ways to select an element, we don't have to memorize it at all, they'll come to you once you start working on projects and give your brain some CSS practice.

If you forget something come back to this blog (bookmark it) and use it as your CSS Selector cheat sheet.

Share your thoughts in the comments!

ย