For years of my career as a developer, CSS frustrated me to no end. It consistently behaved differently than any other language and without any indication as to why.
Most of my CSS writing was in the mode of “guess and check”. That is, I try one thing and check if it looks right. If it doesn’t, I try another thing. Usually, it doesn’t look right, and so this guess-and-check scheme would continue for a while. Eventually, it looked right, but I almost never knew why. And, inevitably, I would add some CSS later to a parent element and ruin everything underneath it. To say that CSS was frustrating is an understatement.
At least, that’s how it was before I learned that there is a method to CSS’s madness and that I didn’t have to hack at the language until I got what I wanted. It sounds obvious now, but there were resources where I could learn how CSS worked. I’ve included some of these resources throughout the post.
To gain proficiency with CSS and outgrow the guess-and-check approach, we have to understand the fundamental algorithms that influence how CSS puts elements on the page. These are called Layout Algorithms. Understanding these algorithms transformed how I approached the language.
CSS has different “modes,” which determine how it lays out elements on the page. These modes are often referred to as “layout algorithms” or “layout modes.” With this bit of information in mind, we can start to deconstruct why some declarations work differently in certain situations than in others. It might be because the layout mode changed, and when the layout mode changes, a lot changes.
Of the seven layout modes in CSS, four of them are used the most. We’ll focus on those four today: flow, positioned, flexbox, and grid.
By default, CSS uses what’s called the flow layout algorithm. Flow treats every element on the page as if it belongs to a text document. If you don’t explicitly ask CSS to use a different algorithm by adding the correct declaration to a rule, you will use this layout algorithm. Luckily, this algorithm is pretty straightforward once you know the difference between inline and block elements. Every element in CSS is either a “block-level” element or an “inline-level element.”
Block-level elements display themselves on top of each other, vertically, on the page. They try to take up as much horizontal space as possible while minimizing how much vertical space they take up.
Inline elements display themselves like text in a paragraph next to each other, horizontally. They usually have a fixed width and height, which is why many properties you might otherwise want to use won’t work with these elements. You can change this behavior by changing their display property to inline-block.
Knowing these ideas can immediately make a few confusing terms in the CSS language make sense, like the margin-inline-end and margin-inline-start properties. See if you can’t work out what those do on your own with your new knowledge. Otherwise, you can check here.
If you use the position property on an element, you are now asking CSS to display that element according to the positioned layout algorithm. Within this layout mode, there are several different types of behaviors you can ask for:
You’ve likely used some of these positioned layouts before, and you may have felt a little gross doing it. Absolute positioned elements tend to get a bad reputation as a “hacky” workaround when something else isn’t working. But it doesn’t have to feel that way. There are rules to how these layouts work. In my experience, understanding the rules makes things feel less hacky.
The most important thing to understand is that depending on which value you use, you may need to consider the element’s parents. For instance, in an absolutely positioned element, the element is positioned relative to its closest positioned layout ancestor. That means CSS will look up the HTML tree and find the nearest ancestor that is also using one of these values. If it can’t find one, an absolutely positioned element will be positioned relative to the viewport.
It’s time to build your great idea.
There’s a lot more to know about the positioned layout algorithm and each of these values within it. I recommend taking a look at this article from Mozilla for a good overview.
An element lays out its children according to the flexbox layout algorithm when the display property is set to flex. Flexbox is an older layout algorithm introduced to the CSS specification in 2009. It was one of the first layout algorithms that didn’t rely on a conception of the web page as a document and instead allowed developers to lay out content in a system of columns and rows rather than paragraphs and sentences like in flow layout.
Flexbox is one of the most popular layouts today because it’s relatively easy to use, and many UI components naturally fall into the shapes and layouts that it excels at.
Once you utilize display: flex on an element, a whole range of other properties become available. For instance, you can now use flex-direction and justify-content to put children elements where you want them. If you don’t specify to CSS that you’d like to use the flexbox layout with display: flex, these other values will have no effect. If you need a good cheat sheet for all the different flexbox properties, check out this article.
Grid is very similar to Flexbox in that you begin to use the grid layout algorithm whenever you have display: grid in an element. This layout algorithm will display all the children elements according to the Grid layout algorithm.
The difference between Grid and Flexbox is that Grid is made to lay out two-dimensional content—things with columns and rows. But Flexbox is meant to lay out one-dimensional content—either a single column or row. You can learn all about grid layout and what properties it enables you to use here.
It’s helpful to know that different algorithms will take effect depending on which properties you use! If you don’t specify anything, you’ll use the flow layout. If you use “position,” you are now using “positioned” layout. And if you use display: grid/flexbox, you are using those algorithms. Now that you know which layout algorithms you’re using at any given moment, the only challenge left is to learn the rules and properties for each one, and soon you’ll have a solid basis for understanding the rest of CSS.