A couple of years in the past, I had a Eureka! second with CSS.
Up till that second, I had been studying CSS by specializing in the properties and values we write, issues like z-index: 10
or justify-content: middle
. I figured that if I understood broadly what every property did, I might have a deep understanding of the language as a complete.
The important thing realization I had is that CSS is a lot extra than a set of properties. It is a constellation of inter-connected structure algorithms. Every algorithm is a fancy system with its personal guidelines and secret mechanisms.
It is not sufficient to be taught what particular properties do. We have to find out how the structure algorithms work, and the way they use the properties we offer to them.
Have you ever ever had the unsettling expertise of writing a well-recognized chunk of CSS, one thing you’ve got used many instances earlier than, solely to get a distinct and surprising outcome? It is tremendous irritating. It makes the language really feel inconsistent and flaky. How can the very same CSS enter produce a distinct output??
This occurs as a result of the properties are appearing on a fancy system, and there is some refined context that modifications how the properties behave. Our psychological mannequin is incomplete, and it results in surprises!
Once I began digging into the structure algorithms, every part began to make extra sense. Mysteries that had bothered me for years have been solved. I noticed that CSS is definitely a fairly darn strong language, and I began to essentially take pleasure in writing it!
On this weblog publish, we’ll have a look at how this new lens might help us make sense of what is occurring in CSS. And we’ll use that lens to unravel a surprisingly-common thriller. 🕵️
So, what’s a “structure algorithm”? You are most likely already aware of a few of them. They embrace:
(Technically, they’re referred to as structure modes, not structure algorithms. However I discover “structure algorithm” to be a extra useful label.)
Because the browser renders our HTML, each component could have its structure calculated utilizing a main structure algorithm. We will choose into completely different structure algorithms with particular CSS declarations. For instance, making use of place: absolute
will swap a component to make use of Positioned structure.
Let’s take a look at an instance. Say I’ve the next CSS:
Our first order of enterprise is to determine which structure algorithm can be used to render the .field
component. Based mostly on the CSS offered, it is going to be rendered utilizing Circulate structure.
Circulate is the “OG” structure algorithm of the online. It was created in an period when the online was primarily seen as a large hyperlinked set of paperwork, just like the world’s largest archive. It is much like the structure algorithm utilized in word-processing software program like Microsoft Phrase.
Circulate is the default structure algorithm used for non-table HTML components. Until we explicitly choose in to a different structure algorithm, Circulate can be used.
The z-index
property is used to regulate stacking order, to determine which one exhibits up “on high” in the event that they overlap. However here is the factor: it isn’t applied in Circulate structure. Circulate is all about creating document-style layouts, and I’ve but to see word-processing software program that enables components to overlap.
When you had requested me about this a number of years in the past, I’d have stated one thing like:
You’ll be able to’t use
z-index
with out additionally settingplace
to one thing like “relative” or “absolute”, as a result of thez-index
property relies on theplace
property.
This is not precisely fallacious, nevertheless it’s a refined misunderstanding. It is extra correct to say that the z-index
property is not applied within the Circulate structure algorithm, and so we might want to select a distinct structure algorithm if we wish this property to have an impact.
This would possibly appear to be I am being pedantic, however this small misunderstanding can result in massive confusion. For instance, think about this:
Code Playground
On this demo, we’ve 3 siblings organized utilizing the Flexbox structure algorithm.
The center sibling units z-index
, and it really works. Strive eradicating it, and spot that it falls behind its sibling.
How can this be? We have not set place: relative
anyplace!
This works as a result of the Flexbox algorithm implements the z-index
property. When the language authors have been designing the Flexbox algorithm, they determined to wire up the z-index
property to regulate stacking order, identical to it does in Positioned structure.
That is the crucial mental-model shift. CSS properties on their very own are meaningless. It is as much as the structure algorithm to outline what they do, how they’re used within the calculations.
To be clear, there are some CSS properties that work the identical in all structure algorithms. shade: pink
will produce pink textual content it doesn’t matter what. However every structure algorithm can override the default conduct for any property. And plenty of properties have no default conduct.
Here is an instance which blew my thoughts: Do you know that the width
property is applied in another way relying on the structure algorithm?
Here is proof:
Code Playground
Our .merchandise
component has a single CSS property: width: 2000px
.
The primary occasion of .merchandise
is rendered utilizing Circulate structure, and it’ll really devour 2000px of width. In Circulate structure, width is a tough rule. It would take up 2000px of area, penalties be damned.
The second occasion of .merchandise
, nevertheless, is rendered inside a Flex container, which suggests it is utilizing Flexbox structure. Within the Flexbox algorithm, width is extra of a suggestion.
The Flexbox specification calls this the hypothetical dimension. It is the scale that the component would be, in an idyllic world, with no constraints or forces appearing upon it. In an ideal world, this merchandise could be 2000px large, nevertheless it’s been positioned in a narrower container, and so it will shrink to accommodate it.
As soon as once more, the framing is tremendous vital right here. It is not that width
has some particular caveat relating to Flexbox. It is that the Flexbox algorithm implements the width
property otherwise than the Circulate algorithm.
The properties we write are inputs, like arguments being handed to a operate. It is as much as the structure algorithm to decide on what to do with these inputs. If we need to perceive CSS, we have to perceive how the structure algorithms work. Understanding the properties alone is inadequate.
CSS does not have a layout-mode
property. There are a number of properties that may tweak the structure algorithm used, and it will possibly really get fairly tough!
In some instances, a CSS property utilized to a component will choose in to a particular structure mode. For instance:
In different instances, we have to have a look at what CSS the mother or father applies. For instance:
Once we apply show: flex
, we aren’t really utilizing the Flexbox structure algorithm for the .row
component; as an alternative, we’re saying that its kids needs to be positioned utilizing Flexbox structure.
In technical phrases, show: flex
creates a flex formatting context. All direct kids will take part on this context, and it implies that they may use Flexbox structure as an alternative of the default Circulate structure.
(show: flex
may also flip an inline component, like a <span>
right into a Block-level component, so it does have some impact on the mother or father component’s structure. Nevertheless it will not change the structure algorithm used.)
Hyperlink to this heading
Structure algorithm variants
Some structure algorithms are cut up into a number of variants.
For instance, once we use Positioned structure, that refers to a number of completely different “positioning schemes”:
Relative
Absolute
Fastened
Sticky
Every variant is sorta like its personal mini-layout algorithm, although they do share issues in widespread (eg. they’ll all use the z-index
property).
Equally, in Circulate structure, components can both be block or inline. We’ll speak extra about Circulate structure shortly.
Hyperlink to this heading
Conflicts
What occurs when a number of structure algorithms are utilized to a component?
For instance:
All three listing gadgets are kids inside a Flex container, in order that they must be positioned in accordance with Flexbox. However that center baby opts into Positioned structure, by setting place: absolute
.
As I perceive it, a component can be rendered utilizing a main structure mode. It’s kind of like specificity: sure structure modes have larger precedence than others.
I do not know the precise hierarchy, however Positioned structure tends to beat every part. And so, on this instance, the center baby will use Positioned structure, not Flexbox.
Consequently, the Flexbox calculations will act as if there are solely two kids, not three. So far as the Flexbox algorithm is anxious, that center baby does not exist. It has no influence on the algorithm in any respect.
Generally, conflicts are often fairly apparent / intentional. However in case you ever discover that a component is not behaving the way in which you’d anticipate, it may be value attempting to establish which structure algorithm it is utilizing. The reply would possibly shock you!
Alright, let us take a look at a traditional “bewildering CSS” drawback, and see how specializing in structure algorithms might help us clear up it.
Right here we’ve a basketful of cats:
Code Playground
Hmm… Why is there a bit of additional area beneath the picture?
When you examine it together with your developer instruments, you may discover a discrepancy of some pixels:
The picture is 250px tall, however the container is 258.5px tall!
When you’re aware of the field mannequin, you understand that components will be spaced utilizing padding, border, and margin. You would possibly assume that there is some margin on the picture, or some padding on the container?
On this case, none of those properties are accountable. And that is why, for years, I’ve privately referred to this as “inline magic area”. It is not brought on by the same old culprits.
To grasp what is going on on right here, we’ve to dig a bit deeper into Circulate structure.
Hyperlink to this heading
Circulate structure
As talked about, Circulate structure is designed for paperwork, much like word-processing software program.
Paperwork have the next construction:
-
Particular person characters are assembled into phrases and sentences. These components sit inline, side-by-side, and line-wrap when there is not sufficient horizontal area.
-
Paragraphs are thought-about blocks, like headings or photos. Blocks can be stacked vertically, one on high of the opposite, from the highest down.
Circulate structure relies on this construction. Particular person components will be organized as inline components (side-by-side, like phrases in a paragraph), or as block components (chunky bricks stacked from the highest down):

Most HTML components include wise defaults. <p>
and <h1>
are thought-about block-level components, whereas <span>
and <robust>
are thought-about inline.
Inline components are meant for use in the course of paragraphs, not as a part of the structure. For instance, possibly we need to add a little bit icon to the center of a sentence.
To be able to be sure that inline components do not negatively have an effect on the legibility of the encompassing textual content, a little bit of additional vertical area is added.
So, bringing this again to our thriller: why does our picture have a number of additional pixels of area? As a result of photos are inline components by default!
The Circulate structure algorithm is treating this picture as if it was a personality in a paragraph, and including a little bit of area beneath to make sure it is not uncomfortably near the characters on the (theoretical) subsequent line of textual content.
By default, inline components are “baseline” aligned. Which means the underside of the picture will align with the invisible horizontal line that textual content sits on. That is why there’s some area beneath the picture — that area is for the descenders, just like the letters j
and p
.
So it isn’t margin, or padding, or border… it is the little bit of intrinsic area that Circulate structure applies to inline components.
Hyperlink to this heading
Fixing the issue
There are a selection of how to unravel this drawback. Maybe the best is to deal with this picture as a block, inside Circulate structure:
Code Playground
Inline magic area has bitten me many instances all through my profession, and so I’ve included this precise repair into my customized CSS Reset.
Alternatively, as a result of this conduct is exclusive to Circulate structure, we may flip to a distinct structure algorithm:
Code Playground
Lastly, we may additionally clear up this by shrinking the extra area to 0, utilizing line-height
:
Code Playground
This answer removes all extra line spacing by setting it to 0. This may make multi-line textual content completely unreadable, however since this container accommodates no textual content, it isn’t a problem.
I’d advocate utilizing one of many earlier two options. This one is introduced purely as a result of it is attention-grabbing (and since it proves that the difficulty is because of line spacing!).
So, here is the purpose: When you have been focusing completely on learning what particular CSS properties do, you’d by no means perceive the place this mysterious area is coming from. It is not defined within the MDN pages for show
or line-height
.
As we have discovered on this publish, “inline magic area” is not actually magic in any respect. It is brought on by a rule inside the Circulate structure algorithm that inline components needs to be affected by line-height
. Nevertheless it appeared magical to me, for a few years, as a result of I had this massive gap in my psychological mannequin.
There are loads of structure algorithms in CSS, and so they all have their very own quirks and hidden mechanisms. Once we deal with CSS properties, we’re solely seeing the tip of the iceberg. We by no means study actually vital ideas like stacking contexts or containing blocks or cascade origins!
Sadly, a variety of CSS instruction on-line is equally shallow. It’s normal for a weblog publish or tweet to share a useful CSS snippet, with out explaining why it really works, or how the structure algorithms use it.
CSS is a difficult language to debug; we do not have error messages, or debugger
, or console.log
. Our instinct is one of the best device we’ve. And once we begin utilizing CSS snippets with out actually understanding them, it is solely a matter of time till some hidden facet of the structure algorithm throws a wrench into our gears, stopping us in our tracks.
A couple of years in the past, I made a decision to begin constructing my instinct for CSS. Every time I used to be derailed by some surprising behaviour, I might settle into the issue as if it have been a heat tub. I might dig deeper into the MDN documentation and the CSSWG specification, and tinker with the code till I felt I had actually found out what was happening.
This was a fully worthwhile funding, however my goodness, it took perpetually. 😅
I need to pace this course of up for different builders. I just lately launched a complete on-line course referred to as CSS for JavaScript Builders.
On this course, we discover how CSS works beneath the hood. It is laser-focused on offering a sturdy psychological mannequin you need to use, one which helps construct your CSS instinct one puzzle piece at a time. I am unable to promise you may by no means hit a CSS problem once more, however I might help you construct the toolkit it is advisable to overcome them.
Greater than 9500 builders have taken the course up to now, from organizations like Fb, Google, Microsoft, Netflix, and plenty of many extra. The response has been overwhelmingly constructive.
You’ll be able to be taught extra on the course homepage:
https://css-for-js.dev.