Stop Using IDs and Classes in Every HTML Element!
Tags: css, beginners, webdev, html
Published: 2022-07-24 17:15:00

Ola! So, this is something I've just come to a realisation recently and if you're a newbie in the world of web development then it's easy for you to forget all the variations of CSS attribute selectors and just opt for creating a specific class or ID to style a particular element in your page.

Case in point? Suppose you have a flex container containing 10 flex items that looks like this:

```html
<div class="flex-container-column">
<div class="item">flex item 1</div>
<div class="item">flex item 2</div>
<div class="item">flex item 3</div>
<div class="item">flex item 4</div>
<div class="item">flex item 5</div>
<div class="item">flex item 6</div>
<div class="item">flex item 7</div>
<div class="item">flex item 8</div>
<div class="item">flex item 9</div>
<div class="item">flex item 10</div>
</div>
```
You want the first flex item to have a different `background-color`. You're probably thinking of creating an ID for this since this style is only unique for this item, right? 

Well, what if we have the same flex container with 10 flex items in every page on our website? and we want the first item to have the same style? _well just add another class to it, duh!_.

Technically, that can be done but this is not the best practice! We should make use of the CSS attribute selectors, more specifically the `:pseudo-classes`.

CSS `:pseudo-classes` helps you single out an HTML element by its particular state, such as:

- `:hover` When you hover a cursor over a button
- `:active` When a link or a button is being clicked
- `:checked` When radio buttons are checked
- `:first-child` and `:last-child` Apply the style to the first and last element that appears immediately and lastly under its parent element, respectively
- `:nth-child` Applies the style to a children element with a particular position in a group of sibling elements, e.g., the third 'p' in every `div`.

With the dummy HTML code above, we can make up a few scenarios with a `background-color` use case:

{% codepen https://codepen.io/koselige/pen/LYdjEQv %}

Let's start from top to bottom there. There are two displays: a column and a row.

### Column

I want the boxes in odd positions (boxes number 1, 3, 5, 7, and 9) to be in an orange-ish color so I target them using the following :pseudo-class, specifying in the bracket that I want to target ODD numbers.

```css
.item:nth-child(odd) {
  background-color: #FEC8A7;
}
```

Same thing with the boxes with even number positions, I just replaced the word _odd_ inside the bracket with `(even)`.

```css
.item:nth-child(even) {
  background-color: #FCECA5;
}
```

### Row

On my Row display, I wanted to target only the first and last boxes. So this is where the `:first-child` and `last-child` come into play:

```css
/* targets the first flex item */
.item2:first-child {
 background-color: #A16AE8; 
}

/* targets the last flex item */
.item2:last-child {
  background-color: #4120A9;
}
```

Fun fact, alternatively you can replace the `:first-child` with `:first-of-type` or `:nth-child(1)`, along with `:last-child` being replaceable with `:last-of-type` in this use case and they'd still deliver the same result! The difference is that, `:first-of-type` will seek ONLY the first occurrence of the said element in the container/parent element, even if it's not the first child of the container/parent element. So, if I slightly change the code for the Row display above by adding an `h1` like this: 

```html
<div class="flex-container-row">
<h1>header</h1>
<div class="item2">flex item 1</div>
<div class="item2">flex item 2</div>
<div class="item2">flex item 3</div>
<div class="item2">flex item 4</div>
<div class="item2">flex item 5</div>
<div class="item2">flex item 6</div>
<div class="item2">flex item 7</div>
<div class="item2">flex item 8</div>
<div class="item2">flex item 9</div>
<div class="item2">flex item 10</div>
<div class="item2">flex item 10</div>
<div class="item2">flex item 10</div>
</div>
```

Using `:first-child` or `:nth-child(1)` will not work! Because the first child of the container is the `h1`. But it will still work with `:first-of-type`, because it will look for the first occurrence `.item2` class in the container. In other words, `:first-child` and `:nth-child` are more specific in this case and are recommended to be used in practice if you want to target a really specific element position.