CSS Selectors you should know

Adeola BaderoAdeola Badero
7 min read

Introduction: With various ways to target HTML elements and various states to style for, styling can get really daunting. This article simplifies and deepens your understanding of styling to make you love CSS more.

PREREQUISITES

  • A basic understanding of HTML and referencing elements in CSS with classes and id(s).

What are CSS selectors and why are they important?

CSS Selectors refer to specific patterns of element(s) that help developers target specific elements from the HTML document for styling or dictating its behavior using JavaScript. They are really important and powerful because web pages neither look amazing nor function well without them. When used properly, they can be used to style multiple elements across the web page without needing to style every element, i.e., just one block of styling can style a wide range of elements once certain rules controlling the property and layout are defined. Without further ado let’s go into the basics.

CSS Selector Basics: Selectors and Combinators

Let's start this section by learning more about CSS Selectors. As we have earlier discussed, Selectors are used to define the pattern of elements when we are about to apply certain CSS rules while Combinators specify the relationship between selectors. Together, they are used to accurately select and style the element of choice based on their type, attributes, state and relationship with other elements.

Selectors

  1. Basic Selectors: These types of selectors are further split into three main types. Let’s go over each one.

    1. Type Selectors: Select all elements with a given node name. For example, p will select all <p> elements and span will match any <span> element. There’s also a special type of type selector which is often used which is the universal selector denoted by the asterisk symbol *. It is used to select all elements.

    2. Class Selector: Selects all elements that have the given class attribute. It is denoted by a '.' prefixing the class name, i.e., .icon matches any element having class = “icon”.

    3. ID Selector: Selects an element based on its id value. It is denoted by a hash sign # prefixing the id value, i.e., #time matches any element with id=time.

  2. Attribute selectors: These selectors select all the elements that (depending on the format of the selector), either have the given attribute or the given attribute set to a certain value. A very good use case is that of the 'type' attribute. The [type] attribute selector would match all elements that have the ‘type’ attribute whether it is set to a value or not while the [type = “checkbox”] would match all elements with the type = “checkbox” set such as <input type = “checkbox”>.

  3. Pseudo-class selectors: These are simple selectors prefixed with a colon :, that allows selection of elements based on state information not contained in the document tree. Simply put, pseudo-classes can be used to style an element based on its state. Some commonly used pseudo-class selectors include: :hover, :focus and :target.

  4. Pseudo-element selectors: They are denoted by a double colon (::) and are used to target elements that don't exist as part of the HTML structure but are generated by CSS for styling purposes. For example, the compound selector p::first-letter is often used to style the drop-cap (i.e., a case where the first letter is bigger than the rest of the paragraph) of an initial letter.

Combinators

They are very useful in specifying the relationship between selectors. There are four main combinators which will be well-discussed below.

  1. Descendant combinators (“ ”): This is denoted by a space and it is used to select all nodes that are descendants of a specified element. For example, div p would match all p elements that are within a div regardless of their position in the DOM tree.

  2. Child combinators (>): This is denoted by the greater than sign and it is used to select elements that are direct children of the specified element. For example, div > p would match all the p elements that are direct children of the div element. It only selects elements (p) that are immediately nested within the parent element (div).

  3. Adjacent sibling combinator (+): This selects an element that is a sibling of the specified element. A sibling is an element that comes immediately after a specified element and shares the same parent. For example h3 + p selects all p tags that come immediately after h3 tags in the entire HTML document.

  4. General sibling combinator (~): Similar to the adjacent sibling combinator, this targets elements that share the same parent and come after the specified element, regardless of their immediate position. So no matter how far the specified element is, as long as it is a sibling of the first element it matches it throughout the HTML document, i.e., h3 ~ p matches all p elements that occur after h3 regardless of whether it is an immediate sibling or it is two or more siblings away.


Deep dive into CSS selectors: CSS selector structure

Now that we have learned about CSS selectors and combinators let's see the hierarchy of those CSS selectors and how they can be combined.

  • Simple selectors: This is a selector with a single selector type such as the single universal selector, type selector, pseudo-class selector and pseudo-element selector.

          .myclass{
          }
    
          [type = 'radio'] {
          }
    
          #myId{
          }
    
  • Compound selectors: This is a sequence of simple selectors without the presence of a combinator. Since whitespace represents the descendant combinator, there is no white space between them.

    ```css #myId.active{ // Rule for element with id: myID and class: active }

// Rule for input type of radio being in focus and checked at the same time. }


    There is an order of precedence in which compound selectors are written. It goes thus, the *type or universal selector* must come first, (in cases where neither is present the class or id selector comes first), followed by an *attribute selector, pseudo-class selector* and *pseudo-element selector*. An element is said to match a compound selector if it matches all the simple selectors in the compound selector.

* **Complex selectors:** This is a sequence of simple and/or compounds whereby combinators are used to specify their relationships. It represents a set of simultaneous conditions on a set particular element. This includes the white space too since it is the descendant selector.

    ```xml
        <div class = "vacation-card">
          <h3>Welcome to the bahamas</h3>
           <p> Get the best value for your money.</p>
          <img src = 'upload.png'/>
          <p> Explore this beautiful city with our tour guide. </p>
        </div>

        <style>
        .vacation-card h3 ~ p {
          /* Styles written here apply to all <p> elements that come after the <h3> element */
        }

        .vacation-card > h3 + p {
          /*Styles written here apply to the <p> element that comes immediately after the <h3> element, i.e., a direct sibling*/
        }
        </style>

In the code block above, multiple selectors were used – along with combinators such as ~, +, > and (space) which makes it a complex selection. Also, notice that although the descendant combinator ( ) and the child combinator (>) work alike in this example, they are not the same given the explanation made earlier in this article.

  • Selector list: This is a comma-separated list of selectors. It is used to apply CSS rules to multiple elements through multiple selectors. An element is said to match a selector list if it matches at least one of the selectors in the comma-separated list. There are two types and they both work the same way; they are specified in the code block below.

          /*Single line selector list*/
          h1, h2, h3, h4{
            /*CSS rules put here affect each selector in the list*/
          }
    
          /*Multi-line selector list*/
          main,
          blockquote,
          button.active{
            /*CSS rules put here affect each selector in the list*/
          }
    

Conclusion

Thanks for reaching the end of this article, you now understand how to make more precise targeting of HTML elements which would help you greatly in your development career. It would also be a great asset when you transition to CSS preprocessors like SASS and LESS and if you already use preprocessors, that's even better, you just learned how to target DOM elements more precisely and without having to use classes and id(s) all the time.

References

(n.d.). CSS Selectors. Mozilla Development Network. https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_selectors

6
Subscribe to my newsletter

Read articles from Adeola Badero directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Adeola Badero
Adeola Badero

I am a frontend developer, UI designer and technical writer who is really passionate about career growth, creativity and finding solutions to challenges.