6 CSS Selectors That Will Save You Time and Markup

David Musk Nov 25, 2020 Read time: 6 minute read
Selectors hero

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 -->

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!

<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> <!-- :last-child -->

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> <!-- :nth-child(2n) -->
    <li></li> <!-- :nth-child(2n) -->
    <li></li> <!-- :nth-child(2n) -->

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.

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

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.


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

Subscribe to our newsletter!

A few times a year we send out a newsletter with tips and info related to Craft CMS, technical SEO, and things we find interesting. No spam. Unsubscribe any time.

You Might Also Like

Organizing Craft CMS Assets

Organizing Assets in Craft CMS [New Video]

Catherine Kleimeier Jun 3, 2021  ·  1 minute read

Effective file management and organization is an often-overlooked feature of a content management system. Doing it right helps with everything from boosting SEO to saving server space. Our video demonstrates how to organize assets in Craft CMS.

Converting Google Maps to Mapbox

Converting Google Maps to Mapbox

Catherine Kleimeier May 27, 2021  ·  5 minute read

If your website has a Google Map on it that hasn't been touched in years, there's a pretty good chance that it doesn't work anymore. If your Google Map no longer works because you don't have a valid billing account, or if you want a unique (less expensive) map solution, consider switching to Mapbox! In this post, we'll show you how we did it on our own site.

Google Analytics Alternatives For Better Privacy

Google Analytics Alternatives For Better Privacy

Ryan Masuga Apr 30, 2021  ·  4 minute read

User privacy is a growing concern on the web. Websites using Google Analytics to track user behavior contribute to the privacy problem, but there are many privacy-focused web analytics alternatives to use instead.