CSS Smart Selectors, Part 2 of 2

Dave Gash
7 min readApr 25, 2018

--

It’s still all about pattern matching

Our Story So Far

In Part 1 of this article, we explained the HTML maintenance problem caused by over-reliance on CSS classes. We proposed a solution in coding smarter CSS rule selectors, and explored the first two kinds of contextual selectors, combinators and pseudo-classes.

In this second and final part of the article, we’ll cover the other two kinds of smart selectors, pseudo-elements and attribute selectors.

Pseudo-elements

CSS pseudo-elements identify parts of HTML elements which, like pseudo-classes, is just another way to define their context. In a selector, pseudo-elements are appended to elements with two colons (::). That is, element::pseudo-element { . . . }.

Note: The two-colon notation was introduced in CSS3 to distinguish between pseudo-elements and pseudo-classes, which use one colon. To maintain backward compatibility with existing stylesheets, the CSS specification requires that browsers must continue to accept one-colon notation, at least for now. Bottom line: There’s no need to change your existing stylesheets, but use double colons for pseudo-elements as you write new CSS.

There aren’t many pseudo-elements, and they’re fairly intuitive. Two of them, ::before and ::after, are typically used with the CSS content property to insert style-related content near a selected element. In these two examples, they’re used to add an image to H1s, either before or after.

In the next two examples, we use pseudo-elements to identify and modify the first-letter and first-line of paragraphs.

Question

So, how much HTML maintenance was required to make that CSS work?

Are you seeing a pattern here?

Attribute Selectors

Finally, let’s explore attribute selectors. Syntactically, they’re a bit more complex than other contextual selectors, but that complexity makes them very, very smart. Attribute selectors identify elements that have certain HTML attributes, or elements that have certain HTML attributes that have certain values. This is yet another way to determine element context. In a selector, attribute selectors are appended to elements with brackets [ ] (or “square brackets”, as we typically and redundantly call them) and, optionally, with a comparison operator and value. That is, either element[attribute] { . . . } or element[attribute=value] { . . . }.

That might seem confusing, but it’s easier than it sounds; let’s break it down.

Let’s say that in an HTML page we have a number of plain old hyperlinks that just jump to another page in the same window/tab; that is, the new page replaces the current page. That’s common, and perfectly okay. But on that same page we also have some links that deliberately open in a new window/tab. This is also okay, and the way we force that behavior, of course, is to use the target="_blank" attribute on those links. So let’s have the CSS identify and modify only those new-window links. The selector for that rule says, “select a link only if it has a target attrubute with a value of _blank.” Example:

The equals operator = works beautifully, but it’s pretty restrictive. One value either exactly matches another or it doesn’t; there’s no in between. So, for flexibility, attribute selectors also provide other operators, notably:

  • *= means “contains”
  • ^= means “starts with”
  • $= means “ends with”

Still confused? Let’s go to the examples.

This selector selects any element that has a class attribute whose value contains the string “test”.

This selector selects any element that has a class attribute whose value starts with the string “top”.

And this selector selects any element that has a class attribute whose value ends with the string “test”.

Question

How much HTML did we have to change to make that CSS work?

Thaaaaaaaaaaaaaaaaaat’s right

Practical Examples

Okay, I’m sure you’re tired of tiny, isolated examples; you want to see some real-world uses, actual everyday cases where you can use smart selectors to avoid adding classes all over your HTML.

Let’s revisit the “Stupid Stuff You Can Do” page from the Part 1 introduction. Here’s the CSS code and part of the resulting styles as rendered on the HTML.

If that’s a bit too small to read, here are the smart selectors by themselves.

I suggest you check out the full TryIt page and play around with the CSS; it’s all at my website, here: http://www.davegash.com/smartselectors.

Really, go ahead. Feel free to change any of the CSS you like and then click the green Run button to see the effects on the HTML. And don’t worry — you can’t save the code, so you can’t break it for the next person. BWWAAAAAHHHHAAAHAHAHAHAAAAAA!!!!!

Some things to look for in the completed page:

  • The red warning headings and text
  • The arrow icons following the external links
  • The PDF icon following the PDF link
  • The appearing underline on the links in the unordered list
  • The dropcaps on each H3’s first paragraph
  • The zebra table alternating colors

Okay, so What?

An excellent question! Sure, we can do all those stylistic things to our HTML page but, honestly, this one is still major fugly. What’s really the point here?

Not the Point

Let’s start with what’s not the point. What’s not the point is how we modified the HTML elements; that is, the CSS rules with the property/value pairs and the effects they have on the HTML is most decidedly, definitely, absotively, posilutely not the point!!! (That’s right, I used three !s; deal with it.) Sure, CSS properties are indeed capable of some amazing effects — exactly none of which we used in this article. I mean, the most outrageous property we used here was content, and it’s really more of a “hmm” thing than a “wow” thing.

The Point

What is the point is how we selected the HTML elements to be modified; that is, how we crafted those simple rules with smart selectors that can examine the elements’ contexts and work out for themselves when and when not to apply. That, folks, is a BFD (hint: not “Brilliant Functional Development”) because it allowed us to create all those stylistic effects without adding a single class attribute to a single HTML element.

So, if I asked you one final question, like, “How much HTML editing did we have to do to make all of that CSS work?”, you might answer thusly:

And you’d be right

Bingo! We created and coded a batch of CSS rules that include no classes at all (dependent or independent) and thus are in no way reliant on the presence of any HTML class attributes.

Smart selectors FTW!

Summary

We can say, then, that CSS smart selectors do a few main things.

  • Simplify CSS coding (no, really)
  • Reflect, but don’t influence, HTML structure
  • Reduce or eliminate dependence on HTML class attributes
  • Reduce CSS-related HTML maintenance and attendant problems

Resources

Here are some links with CSS selector information that you might find useful.

Thanks!

Thank you for reading this article; I hope you had fun and learned something along the way! Comments or questions? Contact the author, Dave Gash, at dave@davegash.com.

--

--

Dave Gash

Dave is a retired technical publications specialist and has been a frequent speaker at User Assistance conferences around the world since 1998.