Advanced CSS Selectors – Part 1

Weโ€™ve seen 5 different ways to select page elements for styling. Over the next few tutorials we will add more than 50 advanced CSS selectors for targeting HTML elements for styling.

Contents

  1. A Quick Recap and Introduction
  2. Updated Clone Page Code
  3. Final Words
  4. References

A Quick Recap and Introduction

You have seen how to style HTML elements using the following selectors:


/*
  This styling will be applied to all elements on
  the page unless another style overrides it.
*/
* {
  box-sizing: border-box;
}

/*
  This styling will be applied to all <p> elements
  on the page unless overridden by a style applied
  via a .class, [attribute], or #ID
*/
p {
  color: black;
  background-color: white;
}

/*
  This styling will be applied to all elements
  with this class.

  It can be overridden by other classes or [attributes]
  that are applied to the element, but only if they are
  defined after this one.

  An #ID style will always override this style.
*/
.myStyle {
  color: blue;
  background: yellow;
}

/*
This styling will be applied to all elements
matching this attribute.

It can be overridden by other classes or [attributes]
that are applied to the element, but only if they are
defined after this one.

An #ID style will always override this style.
*/
[reversed] {
  color: white;
  background-color: black;
}

/*
  This styling will be applied to the element
  with this ID. Remember: each ID must be
  unique on the page and an element can have a
  maximum of 1 ID.

  This styling overrides any other styling
  applied to the element.
*/

#myID {
  font-size: 24px;
  color: black;
  background-color: orange;
}

This sort of styling is very direct: you explicitly specify the element you want styled and rely on inheritance to pass styles from parent to child elements.

This direct form of styling does have shortcomings – if we want to style part of the page differently, we have to explicitly create new styles for that (likely using classes) and apply them to the elements we want styled. This creates a multiplicity of style rules than can quickly become unwieldy.1 As well, if you apply multiple styles (via classes) then the order in which the styles were defined matters.

Letโ€™s consider the clone page created earlier: one of the things used was a card pattern for the articles on the page:

<div class="card">
  <div class="image">
    <img src="">
  </div>
  <div class="headline">

  </div>
  <div class="timestamp">๐Ÿ•” 2 Hours</div>
</div>

This worked fine, except that instead of using a generic class of .headline, specific headline classes were used depending on which column the card was located: .headline-small, .headline-large, and .headline-medium.

This makes moving cards from one column to another complicated because styling information (rather than content information) is embedded in the class. Moving a card requires the class be updated because its location changed.

CSS allows you to apply styles based on the context your content appears in. Consider:

/*
apply the following style to elements
with the class .headline that are
immediate children of elements with the
class .card that are immediate children
of elements with the class .left-column
*/
.column-left > .card > .headline {

}

/*
apply the following style to elements
with the class .headline if their parent
element has class .card and their
grandparent has class .middle-column
*/
.column-middle > .card > .headline {
  font-size: 32px;
}

/*
apply the following style to elements
with the class .headline only if it is
nested exactly as follows:
  class=โ€œright-columnโ€
      class=โ€œcardโ€
          class=โ€œheadlineโ€
*/
.column-right > .card > .headline {
  font-size: 24px;
}

If you replace the .headline-small, .headline-large, and .headline-medium. style definitions in the clone page with the above code and replace their use in the HTML with .headline, you will notice everything still works correctly.

Updated Clone Page Code

You can see how the updated clone page looks here and you can see how the original clone page looks here. You can also inspect the page source code using the view source tool you learned about here or inspect the updated source code below:

<!DOCTYPE HTML>
<html>
  <head>
    <title>Clone Page</title>
    <meta charset="utf-8"  />

    <style>

      * {
        box-sizing: border-box;
        font-family: sans-serif;
        font-size: 16px;
      }

      img {
        width: 100%;
      }

      #wrapper {
        width: 960px;
        margin: auto;
      }

      #title {
        background-color: white;
        color: black;
        padding: 8px;
      }

      #site-name {
        font-size: 32px;
        font-weight: bold;
      }

      #login {
        color: grey;
        padding-top: 8px;
        float: right;
      }

      #search {
        color: grey;
        float: right;
        padding-top: 18px;
        padding-right: 16px;
        font-size: 24px;
      }

      #navbar {
        background-color: #333333;
        color: white;
        border-bottom: 2px solid grey;
      }

      #darkbox {
        background-color: #333333;
        height: 100px;
      }

      #content {
        margin-top: -90px;
      }

      #popular {
        color: white;
        padding-left: 16px;
        font-weight: bold;
      }

      #footer {
        text-align: center;
        padding: 24px;
        background: #333333;
        color: white;
        font-size: 20px;
      }

      .nav-item {
        display: inline-block;
        padding: 24px 16px;
      }

      .column-left {
        width: 20%;
        float: left;
      }

      .column-middle {
        width: 55%;
        float: left;
        border-left: 2px solid grey;
        border-right: 2px solid grey;
      }

      .column-right {
        width: 25%;
        float: left;
      }

      .clearfix::after {
        clear: both;
        display: block;
        content: "";
      }

      .card {
        padding: 0 16px 16px 16px;
      }

      .image {

      }

      /*
      Use the more specific styling selectors
      that select HTML elements based on their
      class AND placement in the page.
      */
      .column-left > .card > .headline {

      }

      .column-middle > .card > .headline {
        font-size: 32px;
      }

      .column-right > .card > .headline {
        font-size: 24px;
      }

      .timestamp {
        padding-top: 8px;
        color: gray;
        font-size: 12px;
      }

    </style>
  </head>
  <body>
    <div id="wrapper">
      <div id="title">
        <span id="site-name">clonage</span>
        <span id="login" class="clearfix">Login</span>
      </div>
      <div id="navbar">
        <span class=nav-item>Gear</span>
        <span class=nav-item>Gaming</span>
        <span class=nav-item>Entertainment</span>
        <span class=nav-item>Tomorrow</span>
        <span class=nav-item>Video</span>
        <span class=nav-item>Reviews</span>
        <span class=nav-item>Events</span>
        <span class=nav-item>Local Edition</span>
        <span id="search" class="clearfix">โŒ•</span>
      </div>
      <div id="darkbox"></div>
      <div id="content" class="clearfix">
        <!--
        Update all the .headline-small,
        .headline-large, and .headline-medium
        class tags to the .headline class.
        -->
        <div class="column-left">
          <p id="popular">Popular Now</p>
          <div class="card">
            <div class="image">
              <img src="32-small-1.jpg">
            </div>
            <div class="headline">
              Foods that boost your learning
            </div>
            <div class="timestamp">๐Ÿ•” 2 Hours</div>
          </div>
          <div class="card">
            <div class="image">
              <img src="32-small-2.jpg">
            </div>
            <div class="headline">
              Robot arms may be the next
              technological frontier
            </div>
            <div class="timestamp">๐Ÿ•” 2 Hours</div>
          </div>
          <div class="card">
            <div class="image">
              <img src="32-small-3.jpg">
            </div>
            <div class="headline">
              Is virtual reality going to far?
            </div>
            <div class="timestamp">๐Ÿ•” 2 Hours</div>
          </div>
          <div class="card">
            <div class="image">
              <img src="32-small-4.jpg">
            </div>
            <div class="headline">
              The latest trends in cosplay
            </div>
            <div class="timestamp">๐Ÿ•” 2 Hours</div>
          </div>

        </div>
        <div class="column-middle">
          <div class="card">
            <div class="image">
              <img src="32-big-1.jpg">
            </div>
            <div class="headline">
              Before you buy, check our review of the
              hottest cars on the market
            </div>
            <div class="timestamp">๐Ÿ•” 2 Hours</div>
          </div>
          <div class="card">
            <div class="image">
              <img src="32-big-2.jpg">
            </div>
            <div class="headline">
              Health benefits of fresh fruits
            </div>
            <div class="timestamp">๐Ÿ•” 2 Hours</div>
          </div>
        </div>
        <div class="column-right">
          <div class="card">
            <div class="image">
              <img src="32-medium-1.jpg">
            </div>
            <div class="headline">
              The best places to visit on Jupiter
            </div>
            <div class="timestamp">๐Ÿ•” 2 Hours</div>
          </div>
          <div class="card">
            <div class="image">
              <img src="32-medium-2.jpg">
            </div>
            <div class="headline">
              The latest smart watches monitor your
              body's vitals while looking stylish
            </div>
            <div class="timestamp">๐Ÿ•” 2 Hours</div>
          </div>
          <div class="card">
            <div class="image">
              <img src="32-medium-3.jpg">
            </div>
            <div class="headline">
              Keeping yourself safe while shopping online
            </div>
            <div class="timestamp">๐Ÿ•” 2 Hours</div>
          </div>
        </div>
      </div>
      <div id="footer">Copyright 2018</div>
    </div>

  </body>
</html>

Final Words

Youโ€™ve received a brief introduction to one advanced CSS selector known as a combinator. This combinator (denoted with the symbol โ€˜>โ€™) specifies an explicit parent-child relationship for the selection.

The next few tutorials will cover in more detail the various combinators, pseudo-classes, and pseudo-elements that can be used for advanced CSS selection of HTML elements (there are more than 50 of them).

References

  1. CSS Selectors

  1. Ok, styling rules can become very messy, very quickly if you are not clear in what you are doing. Always ensure you constructing your rules in a well ordered rather than ad-hoc manner.โ†ฉ