Monkey CSS
Tags: css, webdev
Published: 2021-05-06 16:17:59


Sometimes CSS seems to act crazy while it's not. Let's see why with practical examples.

## z-index and the devil

`z-index` allows setting how some elements pile up on the page. Not all elements are concerned:

* only positioned elements can have a `z-index` (for example, relative, absolute, fixed)
* an element with `z-index: 1` is theoretically below an element with `z-index: 2;`

In those conditions, the following rule should "ensure" the element in the first plan:

```CSS
.myelement {
   position: absolute;
   z-index: 999;
}
```

However, it's a typical case where it might not work, and here is why: the z-index value does not determine what's on top.

Let's rewind:

> an element with `z-index: 1` is theoretically below an element with `z-index: 2;`

Not all the time. When you use very simple layouts that do not trigger **offscreen rendering**, the stacking order is pretty much the same as the order of appearance of the HTML elements.

When you have more complex layouts that involve CSS positions, z-index values, CSS transforms, or elements with an opacity value under 1, additional rules apply.

Each context will have those rules, and it take precedence over any super high z-index value you might add. It's called a **stacking context**.

I did not realize how complex it can be before writing this post, and I doubt there is an ultimate solution.

I would say you don't have to use `z-index`, but if for some reason you need to, be aware of the stacking context.

## The hell of undoing

It's something I've seen (and used a lot at the beginning). The "tricks" consists of defining classes that cancel other CSS rules:

```CSS
.no-text-decoration {
   text-decoration: none;
}
.no-padding {
   padding: 0;
}
```

This approach is not efficient. Even the gain for refactor is questionable, as you have to add meaningless HTML classes multiple times.

IMHO, it's better to use specific classes for specific elements and apply rules.

## The hell of margins

Margins and paddings are essential for any style. Roughly speaking, margins set external spaces (~ space around), and paddings are for internal white spaces.

It's pretty straighforward, but it's not that easy. Be aware of the **margin collapsing** that happens vertically:

```HTML
<p>test</p>
<p>test</p>
```

```CSS
p {
  margin: 15px 0;
}
```

The margins won't work as you might expect. Between two adjacent paragraphs, you won't get 30px but 15px.

To get 30px, you would have to use the following rule instead:

```CSS
p {
  margin: 15px 0 30px;
}
```

That's because the bigger margin wins when margins collapse vertically.

[Source: MDN - margin collapsing](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing)

## The hell of prefixes

If you need larger support than modern browsers but still want to use fancy effects and properties, there's a good chance you will spend your life on [caniuse](https://caniuse.com).

As you don't have that time, [autoprefixer](https://github.com/postcss/autoprefixer) is your friend.

Be careful. It won't automatically polyfill all cases. The idea is to add prefixes.

The principle is simple, but don't forget to add unprefixed property. For example, the tool won't work if you only write that:

```CSS
.myelement {
   -webkit-animation: spinMeRound .5s infinite linear;
}
```

Make sure you add the unprefixed property instead:

```CSS
.myelement {
   animation: spinMeRound .5s infinite linear;
}
```

## The hell of CSS units

You have many ways to measure elements and assign values in CSS. For example, there are `em`, `rem`, `px`, `%`, `pc`, `ch`, `vw`, `vh`, etc.

Which one should you use?

### The magical answer

> It depends

🎉 Thanks buddy, very helpful ^^.

### The good practice

Not all CSS units are equivalents. Some of them are relative, some of them are absolute.

In this responsive era, relative units are more appropriate. Absolute units can be used for areas that don't need responsive such as print or desktop applications.

With relative units, elements resize according to the device. I prefer using `rem` and `%` as a general rule, but asserting there are the ultimate units would be silly.

## The hell of inconsistencies

Even if browsers are now much more standardized than before (it was chaos back then ^^), there are still some inconsistencies.

Every browser has its default styles for HTML elements. 

It can be tedious to handle that manually. Fortunately, you can use a [CSS reset](https://dev.to/hankchizljaw/a-modern-css-reset-6p3). As the name suggests, it resets styles, stopping annoying differences in padding and margin.

## Respect the normal flow

Of course, you sometimes need to handle floating elements, positions, and offscreen rendering.

I'm not saying you should never use them or replace any occurrence, but my point is you must use them sparingly:

1. modern CSS with flexbox and grid probably can do the job
2. it can have a significant impact on performances

The classic example would be centering in CSS. If you don't need strong compatibility with ancient browsers, use grid:

```CSS
.mycontainer {
  display: grid;
  place-items: center;
}
```

It seems way more comfortable than absolute positions, especially if you need to handle various screen sizes.

## Wrap up

Is CSS hell? I don't know, [this website would say yes ^^](https://csshell.dev/)


CSS is also fun, but like any other language, there are complex parts.

However, CSS is one of a kind, and it's worth learning.