Cool CSS Selectors

July 4, 2022
CSS and SASS Tips and Tricks

One of the spoils of using Sass/SCSS is the liberal use of nested selectors, which enables a very high level of specificity. Unfortunately, it can cause some issues sometimes, especially when you’re using media selectors in the mix, as well. It seems that in the last few years, CSS is closing the gap on SCSS and introducing a much broader feature set. The most obvious example of this is CSS Custom Properties, also known as CSS Variables. This concept has been available in SASS for as long as I remember, but other features are closing in, too.

CSS has always had super powerful selectors, from the basic to the more complex, the concept relies on specificity and “weight”. For example, a selector with a longer set of qualifiers will take precedence over a selector with a shorter set of qualifiers. However, combine that with the weight, and things may get complex. However you align your selectors, there are ways to get exactly what you need in almost every case. Here are some of my favorites.


Attribute Selectors

Attribute selectors select elements with an attribute. What’s cool about them is the qualifications of the attributes. So, if you want to style links to an affiliate site (affiliate.site) a certain way, you could use the attribute selector for that. This method will select all links to that site, whether it’s product.affiliate.site or affiliate.site/product.

a[href*="affiliate.site"] {...}

To strictly select links directly to a specific URL, just remove the asterisk.

a[href="affiliate.site/product1"] {...}

There’s more methods there, too. And this syntax can be used for any attribute, including class, title, name, whatever.

//select all inputs with a placeholder
input[placeholder] 

//select all anchor elements with href attributes ending in .io
a[href$=".io"]

//select all forms that submit to forms.google.com, over SSL or not
form[action~="forms.google.com"]

These are the most common use cases for me, but Mozilla covers all the syntax. Keep in mind that these are valid for any attribute. The attribute selector could stand alone, too, so you don’t even need to associate a specific type of element, you could select all elements with that attribute.


General Sibling Selectors

I like this one because it’s great for typography and margin setting. It allows elements that share a direct parent to be selected in kind. Consider the following HTML:

<div class='block'>
  <h3>Heading</h3>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
  </p>
  <figure>
    <img src='image.jpg' alt='A Picture of a blade of grass' />
    <caption>A Blade of Grass</caption>
  </figure>
  <p>
    Grass is cool and great. It's too bad it makes a bad yard.
  </p>
</div>

If the goal was to select all the paragraph elements, you might use .block p. But if you only wanted to select the paragraph elements that come after the figure element, that’d be a good case to use the general sibling.

.block figure ~ p {//styles}

That selector would select the paragraph elements that come after the figure element, but doesn’t need to be immediately following it. Incredibly useful. Check out this demo for a visual aide.

See the Pen General Sibling Selector by Nate Northway (@the_Northway) on CodePen.


Pseudo-classes

Pseudo-classes are added to selectors to specify a special state. A lot of these selectors are based in interaction, like :hover and :focus-visible. But, there are incredibly useful ones like :last-child and :nth-child(). Here’s a small list of my favorites

//select input elements with a placeholder that is shown
input:placeholder-shown 

//select empty input elements
input:blank

//select invalid input elements after user interaction
input:user-invalid

//select odd children (careful - this is ALL odd children, including further generation descendants)
div :nth-child(odd)

//select the root element (just like using html but with more specificity)
:root 

I’m willing to bet you’ve seen at least one of those – the root selector is what you need to use to set up CSS Variables. My favorite of the above selectors is the odd child selector, because it’d pick me, at least my mom would say so.

See the Pen :nth-child(odd) demo by Nate Northway (@the_Northway) on CodePen.


Pseudo-elements

Pseudo elements are often used to set up icon fonts and non-text features like folds and triangles. They’re also exploited in single-div CSS challenges, but I won’t get in to that here. It’s more than just the before and after pseudo elements, though, there’s a lot of utility packed in to these selectors.

//select the first line of a p element
p::first-line

//create/select an element that is the first child of the selected element
div::before,
div:before

//select the first letter of an element 
p::first-letter,
p:first-letter

Specificity is a little weird, :first-letter is more specific than :first-line, so watch out for that. Check the demo below for more.

See the Pen Pseudo-elements by Nate Northway (@the_Northway) on CodePen.


SASS Has the leg up (…for now)

The one thing CSS is missing is the “parent selector”, but that’s being worked on now. It’s got full support in Safari > 15.4 and will be/is in Chrome > 105. It’s known as the :has pseudo-class and is used to select an element if any of the relative selectors passed to the pseudo-class function would match at least one element when anchored against this element. That was kinda confusing. Let’s demo:

//anchor tags that contain an image as a direct child - aka "parent selector"
a:has(> img)

//anchor tags that are immediately followed by an anchor tag - "previous sibling" selector
a:has(+ a)

Those seem like the most common uses for me – but the spec has some great demos and better explanations.

For now, the parent selector in SASS does the job for me – but we’re talking about CSS here so I’ll keep it on topic.


Wrapping Up

Is ^ that a pun? “UP”? Like a parent selector? Get it?

Okay, here are some useful links that go a bit deeper in to what I talked about here.

Photo by Alexander Dummer on Unsplash

No Comments...yet

Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Post

SVG in CSS

From July 1, 2022

SVG can ensure clearness and proper scaling. And when used directly in CSS, cut down on a network request.

Read This Article