Tomas Vik

CSS Week 1 - Selectors

This is another episode of my CSS learning challenge. If you’d like to know how this all started, you can read the introduction post.

This week, I’ve spent roughly an hour each day learning about CSS Selectors. I started with a FrontendMasters CSS Course to get an overview of the topic (roughly three hours), and then I followed up with reading blog posts and MDN documentation.

I choose you <div>

“I choose you

What did I know

I knew that you could select by element, class, and id. I knew that the specificity increased in that order. I also knew that you could combine the selectors with space or >, increasing specificity. I knew some pseudo-class selectors, even though I wouldn’t be able to call them that. And of course, I knew the nuke of selector specificity !important.

Selectors I was able to create and understand well:

  • div.danger, ul > li, .container h1, .content p:first-child

What did I learn

CSS selectors are designed to style the markup without programmatically adding a class attribute on every element we are interested in. This insight wasn’t quite apparent to me. And it also goes directly against the school of thought represented by Tailwind CSS where you only add classes and never custom CSS.

I learned about attribute selectors. I knew only vaguely that they exist, but now I know what they are and how to use them.

  • input[type=checkbox] Matching input type is the most common use for exact attribute match.
  • a[href$=.pdf] You can style all links that will open a PDF (to warn the user that it’s not a web page).

Also, there is some funky behaviour around case-sensitivity. HTML attributes like class and type are case insensitive, but the case must exactly match for custom attributes.

The pseudo-selectors (classes and elements) dynamically select elements. You can’t select these parts of markup with the simpler element selectors and their combinators. You can select “first paragraph in the body” or “every odd row of a table”.

I finally understand ::before and ::after. This slide from Estelle Weyl explains it the best. Basically, the ::before and ::after pseudo elements are created within the selected element (e.g. inside a <p> tag).

What I didn’t learn

My learning still feels like trying to piece together hundreds of small and often unrelated pieces of the CSS specification. Most of the articles, the CSS course and MDN documentation are all missing real-world examples. They only show small isolated exercises to explain a single property. I now understand :last-of-type, but what are the most common usages when writing production websites? Is it even important? Do engineers use it every day, every week or twice a year to solve some specific use-case?

My process

I made the mistake of trying to learn too many selectors. The kind of insight I’m looking for is: “Selectors are used to styling elements without adding too many class and id attributes. Out of the more obscure selectors like pseudo-element selectors, these two [fill in the blank] are the most useful because they help in these widespread scenarios [fill in the blank].”

I have an advantage that I should use. I have seen countless CSS files in the last decade. That means I should be able to judge whether a certain syntax is commonly used. Instead of focusing on the full breadth of specification, I should get a broad overview of the topic within the first two or three days and then try to distil the core concepts and maybe one or two useful edge-cases.

Next up: Flexbox and Grid. This is bound to be fun.