Learning CSS #2: CSS Diner Writeup 🍱πŸ₯’

Met up with Aviv Sarig to practice some CSS. I found CSS Diner and we went through it to hone our CSS selection skills.


Start with “Why”: why practice selectors?

I think it’s important to understand why we need selectors in the first place. The answer is simple - to select specific elements in the DOM so we can style them the way we want.

I think that building good semantic HTML is the first step to writing good CSS, and that knowing how I’ll end up selecting elements will impact how I structure the HTML itself.

CSS Diner Writeup


Like any other writeup, be warned - spoilers ahead! If you want to try it out yourself, go to CSS Diner before reading this.

type selectors

Just the name of the element (e.g. “Input”).





ID selectors

With a #.


Descendant selectors

With a space between the parent and descendant, A B.

level 4

plate apple
#fancy pickle

Class selectors

With a ..


Combining selectors

This was very interesting to me: every #, . (and later on: : and []) operator withing a selector is a logical AND. For example, level 7’s solution is:


Translates to, in logical notation:

$$ orange\space\land\space.small $$

bento orange.small

Comma combinator

And after the \(\land\) operator, we get the \(\lor\) (Logical OR) operator with ,.

plate, bento

* selector

* matches any element.

plate *

Sibling selectors

Adjacent sibling - with a +. This was the first new thing I learned so far!

This selects all B elements that directly follow A. Elements that follow one another are called siblings. They’re on the same level, or depth.

plate + apple

I didn’t understand why we need this, so I asked ChatGPT for some use cases, and got some interesting answers. One that Aviv suggested was a gradient effect on hover. Some that ChatGPT suggested:

  • Apply a different style to the first item in a list
  • Create a custom-styled checkbox
  • Highlight the current item in a navigation menu
  • Style an input field based on user interaction
  • Apply specific styles to adjacent table cells

This is a great example, IMO, of using LLMs as a learning partner. πŸ€–

Then we learned about the general sibling selector: ~.

bento ~ pickle

Child selectors

With A > B. The difference from A B is that > only selects direct children.

plate > apple

Children pseudo-selectors

First child pseudo-selector: :first-child. I’m not super sharp on what are pseudo-selectors, so I read about it.

plate > orange:first-child

Only child pseudo-selector: :only-child.

plate > *:only-child. You can also solve it with plate :only-child, and we weren’t sure which one is better.

Finally, last-child pseudo-selector: :last-child.


Nice tip from the diner:

Pro Tip β†’ In cases where there is only one element, that element counts as the first-child, only-child and last-child!

Nth child pseudo-selector: :nth-child(). This one is a bit more complicated, since it takes a parameter.


Nth last child pseudo-selector: :nth-last-child(). This one is the same as :nth-child(), but counts from the end.


Something we both failed to understand is why bento:nth-last-child(2) doesn’t work in this case, but bento:nth-last-child(3) does.


The reason is that the children selectors are type-agnostic.


Something cool about nth is that you can use interesting “formulas” to select elements. For example, even and \( A \times n + B \) :


More pseudo-selectors for more edge cases:

plate apple:only-of-type
apple:last-of-type, orange:last-of-type

Attribute selectors

The [] syntax is used for attribute selectors. For example, [type="radio"] will select all elements with type="radio". Seems like class and ID selectors are just a special case of attribute selectors. For example, #fancy can be written as [id="fancy"].


Attribute starts with! That’s new to me as well! πŸ†•


Yay! We finished the diner! πŸŽ‰ Seems like we rock at CSS.



Never stop learning! Even though I know CSS, I still learned a few new things:

  • Adjacent sibling selector
  • General sibling selector
  • Thinking about CSS selectors in terms of logical AND and OR

Also, thanks Aviv! It was fun. 🍱πŸ₯’

Shay Nehmad


1020 Words

2023-06-09 08:03 +0300