Essential Keys to Crack CSS

The short CSS guide that makes you say: “Ahhhhh… that’s why!”.

Leonardo Di Vittorio
Level Up Coding

--

Photo by KOBU Agency on Unsplash

Everything is a box!

Let’s start from the assumption that every HTML element when it is rendered inside the DOM is rendered as a box. Then you can start adding content or some style to make it look fancier. In the beginning, this is how our boxes actually look for the browser:

The blue rectangle represents the content size, which could be specified by the height or width property or could fit on the size of the children.

The green rectangle is the padding, which pushes all the elements contained in the box towards the inside. Internal spacing.

The light orange rectangle is the border of the box.

The dark orange rectangle is the external margin, it pushes the elements around the box further away.

These 4 dimensions, combined together, represent the physical space that our box occupies: height/width + padding + border + margin = actual space. However, This CSS box model is not so intuitive.

Let me give you an example to make this clearer. Imagine this situation:
You have two boxes with padding and border, inside a container 500px large, and you want these boxes to be next to each other inside the parent box. While you’re reading these words I bet you’re thinking: “That’s easy. I will just give them both width 50%”.

.container {
width: 500px;
}
.box {
border: 1px solid;
padding: 10px;
width: 50%;
}

Well, this will be the result:

Original CSS Box Model

Yes. This is the moment you can start saying “What the hell is going on!?”.
If you remember, we said the size of a box is equal to the width (50% of the container, so 250px), plus the padding (10px) and the border (1px) on both sides for a total of 272px. So it makes sense that they don’t fit side by side in the 500px available.

Introducing the quirky version

There is a solution though! Believe it or not, it comes from the old version of Internet Explorer. In “quirk mode” the Box Model physical space is calculated by height/width + margin = actual space. So, after the community request, this version was introduced in the CSS3 standards with the property box-sizing. By assigning the value “border-box” to this property, the padding and the border will be applied inside and, using the same style we mentioned above, the result will be the following:

Box-sizing border-box

It’s pretty common to apply this rule on every element using the “*” selector:

* {
box-sizing: border-box;
}

The two rules you must bear in mind

Most developers have a very bad relationship with CSS. They say “Why the hell is this rule not working!?” or “The damn div doesn’t go where it should!” or even worse they start using !important everywhere and giving values like ‘99999’ to z-index.

“999999”

If you are one of these people, well, once you know the following two rules, you will stop doing this and you’ll start enjoying writing CSS. Trust me!

Position

The position property defines where the element is located within the page.
With properties like “top”, “right”, “bottom”, “left”, and “z-index” it’s possible to manipulate the final position of the elements, but they will affect just positioned elements (i.e. elements that have any value other than “static”). Keep this in mind for later!

The possible values are:

  • “static”, the default value. The element will go with the normal flow* of the page.
  • “relative”. The element is “relative” to its static position, according to the normal flow, but is affected by the positional properties.
  • “absolute”. I consider this the most controversial. Everybody uses it because they think it does what they want, but nobody really knows how it works. The elements with this position’s value are physically removed from the flow. It’s important to understand that its position is now “relative to its first non-static ancestor”. Repeat it like a mantra!
  • “fixed”. Again, the element will be removed from the page flow, and its positioning will be relative to the viewport (with a few minor exceptions). Moreover, fixed elements are not affected by the scroll.

*The elements appear in the DOM accordingly to the order in which they are declared in the document, from top to bottom. This is considered the normal “flow”.

Display

Display determines the behavior of an element in relation to other elements. Once you understand how the different values affect the element and its surroundings you’ll have the key to crack the code.
In the case of “display”, we can’t say there’s a unique default value. It depends on the HTML tag we are using, each one will have a default value coming from the “computed style”* (eg. divs are “block”, spans are “inline”).

The possible values are:

  • “block”. It enforces a vertical stacking, elements with the display property set to block will take all the possible horizontal space, generating a line break before and after the box.
  • “inline”. Differently from “block”, it allows a horizontal alignment. The inline elements will be displayed one next to each other, and they will ignore any given width, height, and vertical margin.
  • “inline-block”. A mixture of the previous two. It allows a horizontal alignment and we’ll still be able to use the width and height properties.
  • “flex”. It initializes the flexbox layout system. The container (the element with display set to flex) will have control over the flow of its items. We can align the items and distribute the available space depending on the options we give.
  • “grid”. It initializes the grid layout introducing a two-dimensional grid system with columns and rows. Based on a set of rules we will be able to create “easy-to-make” responsive layouts.

In future articles, we will go in more depth talking about “grid” and “flex”.

*Browser has a user agent stylesheet that applies some built-in style to the HTML tags we use.

The mystery of z-index

Probably the most misunderstood rule of all. In order to use it correctly, we need to assume a couple of concepts. First of all, what it does: it controls the vertical stacking order of elements that overlap. This implies that it works only with positions other than static, otherwise, they can’t overlap.

The second important behavior to understand is that nesting matters. Every time we put elements inside containers, we start a brand-new stack, similar to when you have paragraphs and sub-paragraphs. We can number paragraphs like 1, 2, 3… and all the sub-paragraphs of 1 will be 1.1, 1.2, 1.3. The same way you expect all of them to be before paragraph 2, if you have an element inside another with z-index equal to 1, it will be always behind other elements that at the same level of nesting have a bigger number. You should ask your self: “Is 1.9999… bigger than 2?”. The answer is obviously “No”, so why should the element be in front?

Here you have a visual example, where the two yellow and the blue divs are children of the red one, so we should read their z-index like this: 4.1, 4.3, 4.6.

This starts making sense right!?

Takeaway

Sometimes CSS seems impossible to predict, but it’s just a matter of understanding how the rules are related to each other, which is possible by mastering a few principals of this language, and if you don’t know something, just try and see what happens.
I have a collection called “CSS fundamentals” on Codepen, each pen tackles different topics, and at the bottom of each CSS file, I explain step by step what you need to do. You can follow the instructions and see the consequences of each change.

If you have any questions or just want to talk about CSS reach me out on Linkedin.

--

--