Masuga Smile Doodle

6 CSS Selectors That Will Save You Time and Markup

David Musk Nov 25, 2020 Read time: 6 minute read
6 CSS Selectors That Will Save You Time and Markup

Here are six lesser-known CSS selectors we've used to help our clients in the past year. These aren't fancy, experimental features that only work on the latest browsers. Instead, they're practical tools you can start using today.

For most of us, CSS selectors fall into one of two categories: the ones we use every day, and the obscure ones we've never bothered to memorize. We've seen the latter around, but they aren't the first things we reach for.

However, if you’re looking to save time and markup, then adding a few more selectors to your process can make a huge difference.

The best part?

These aren't fancy, experimental features that only work on the latest browsers. These are practical tools you can start using today!

1. The Child Combinator (X > Y)

li {
    color: black; // Default list color
}

ul.main-nav > li {
    color: blue;
}

This is similar to the classic descendant combinator (X Y) except this one only targets the direct children of the first element.

For example, in the HTML below, you could target the li elements directly inside the ul.main-nav, but not the li elements inside the ul.dropdown-nav.

<ul class="main-nav">
     <li></li> <!-- Target this -->
     <li> <!-- And this -->
        <ul class="dropdown-nav">
            <li></li> <!-- But not this -->
            <li></li> <!-- Or this -->
        </ul>
    </li>
</ul>

As you can see, this is perfect for multi-level lists. It means we can change the text color in our main navigation without having to remove that style again in our dropdown menu.

2. Adjacent Sibling Combinator (X + Y)

h2 + p {
    font-weight: bold;
}

In this example, we're targeting paragraphs, but only paragraphs that directly follow an h2 element in the DOM. Nothing else is affected!

<h2></h2>
<p></p> <!-- Target this -->
<p></p> <!-- But not this -->

Note: this also works with classes. The example below is from a client site where we gave them the ability to add different colored bands, and we had to adjust the styles accordingly.

// If another gray band follows this, remove its top padding.
section.gray-background + section.gray-background {
    padding-top: 0;
}
		
// If a white band follows this, add extra padding.
section.gray-background + section.white-background {
    padding-top: 2rem;
}

3. X:first-child / X:last-child

ul li:first-child {
    border-top: none
}

ul li:last-child {
    border-bottom: none
}

Ever been in a situation where you had to add .first or .last classes to your li elements or grid items? This selector serves the same purpose, sparing you from that extra markup.

<ul class="menu">
    <li></li> <!-- :first-child -->
    <li></li>
    <li></li>
    <li></li>
    <li></li> <!-- :last-child -->
</ul>

Saving some extra classes might not seem like a big deal on a Craft site where you have full control of your templates, but this can be a lifesaver on systems that generate their markup dynamically.

4. X:nth-child(n) / X:nth-last-child(n)

ul.alternating-bands li:nth-child(2n) {
     background-color: white;
}

Similar to the last selector, but with a few differences. If you have a list, li:nth-child(1) will select the first item on that list, li:nth-child(2) will select the second, etc.

But the best part about this selector is its ability to target a variable set of children.

li:nth-child(2n) will target every list item that's a multiple of 2 (an even number.) You can also use :nth-child(odd) or :nth-child(even).

Ever wonder about those lists or bands with alternating background colors? This is one of the easiest ways to achieve that effect using only CSS.

<ul class="alternating-bands">
    <li></li>
    <li></li> <!-- :nth-child(2n) -->
    <li></li>
    <li></li> <!-- :nth-child(2n) -->
    <li></li>
    <li></li> <!-- :nth-child(2n) -->
</ul>

Now, let's say you have a long, dynamically generated list with an unknown number of items. What would you do if you needed to select the second-to-last item on that list?

That's where X:nth-last-child(n) comes in!

li:nth-last-child(2) {
   bakground-color: red;
}

This works the same way as :nth-child(2), only it starts from the end rather than the beginning.

<ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>  <!-- li:nth-last-child(2) -->
    <li></li>
</ul>

Overall, this is one of the more complicated selectors on this list, and there's a lot more you can do with it. For a more detailed explanation, Wes Bos published a useful video here.

5. Negation Pseudo-Class (X:not(Y))

section:not(.white-background) {
   color: white
}

Like many of the above selectors, the negation pseudo-class is useful when we want to keep our code clean and avoid repeating ourselves. The above example would change every section's text color to white except for those with a class of .white-background.

<section class="black-background"></section>
<section class="gray-background"></section>
<section class="white-background"></section> <!-- Don't target this -->
<section class="blue-background"></section>

You can even combine this with the previous selectors in this post.

For example:

p:not(:first-child) {}

article:not(:last-child) {}

div:not(:nth-child(2)) {}

section:not(nth-last-child(2)) {}

6. Attribute Selectors (X[href="Y"])

a[href="https://www.gomasuga.com"] {
  color: #4a7d90
}

With this selector, we can move beyond selecting elements to selecting elements with specific attributes. The example above will style all anchor elements that link to gomasuga.com. All other links will be ignored.

On its own, this tool is only so useful. But things get interesting when we introduce regular expressions to the mix.

For example, we can use the carat symbol (^) to target just the beginning of the URL like this:

a[href^="http"] {
    &:after {
        // External link icon.
    }
}

Depending on your setup, this is one way to differentiate between external links and relative links using only CSS.

You can also use the dollar sign ($) to target just the end of a URL:

a[href$=".pdf"] {
    &:after {
        // PDF icon.
    }
}

This is a great way to differentiate between web page links and other filetypes like PDFs.

Conclusion

If you found this article helpful, then there's always more to learn. Here are some more comprehensive resources regarding CSS selectors:

Mozilla Web Docs - CSS Selectors

W3 Schools CSS Selector Reference

Gray Masuga Texture Gray Masuga Texture

You Might Also Like

How to Fix an Empty H1 Tag on Your Shopify Homepage

How to Fix an Empty H1 Tag on Your Shopify Homepage

Ryan Masuga Aug 15, 2022  ·  5 minute read

Shopify's Dawn theme homepage may get an SEO warning for an empty h1 header element. This is a missed opportunity to help search engines understand what your page is about. Small edits to the theme code can fix this technical SEO issue.

Subscribe to Our Newsletter

A few times a year we send out a newsletter with tips and info related to web design, SEO, and things you may find interesting.

No spam. Unsubscribe any time.

Decorative Masuga Border