CSS Layout Before Flexbox and Grid | JavaScript Tools Blog<br>Skip to content<br>Language EN RU ES FR DE IT PT 中文 日本語 AR
BLOG INDEX<br>Modern CSS feels almost effortless.
Need a responsive layout? Use Grid.
Want perfect alignment? Flexbox solves it in a few lines.
Need rounded corners, gradients, shadows, or animations? Every browser supports them without much thought.
It wasn’t always like this.
If you started building websites in the last decade, many of the techniques below will probably look strange. Some will seem unnecessarily complicated. Others will make you wonder how websites ever worked at all.
Yet these techniques powered millions of websites. Online stores, newspapers, company portals, forums, and blogs all relied on them.
Many of those ideas have disappeared.
Some never really did.
QUICK ANSWER<br>Before Flexbox and Grid, developers assembled page layouts with floats, inline-block, table display modes, absolute positioning, and sometimes actual HTML tables. The browser could render those techniques, but developers had to solve containment, alignment, equal heights, spacing, and browser inconsistencies manually.
CSS Was Much Less Capable
Today’s browser engines provide hundreds of layout features.
Fifteen or twenty years ago, developers had only a fraction of that toolbox.
There was no Grid.
Flexbox either didn’t exist or wasn’t supported consistently.
CSS variables were years away.
Container queries were science fiction.
Even centering a simple block could become a small puzzle.
As a result, front-end developers became experts at finding creative workarounds.
Sometimes those workarounds were surprisingly clever.
Sometimes they were simply painful.
Life Before box-sizing
Most modern projects start with a universal rule.
*,<br>*::before,<br>*::after {<br>box-sizing: border-box;<br>Today, when you write:
.card {<br>width: 320px;<br>padding: 20px;<br>border: 2px solid #222;
the element still occupies exactly 320 pixels .
That wasn’t the default behavior years ago.
Without border-box, browsers calculated the final width like this:
width<br>+ padding left<br>+ padding right<br>+ border left<br>+ border right<br>Instead of trusting the browser, developers often reached for calculators.
Changing a single padding value frequently meant recalculating an entire layout.
One tiny design adjustment could break multiple columns.
Building Columns With Floats
Before Flexbox, most websites relied on floats.
.wrapper::after {<br>content: "";<br>display: block;<br>clear: both;
.card {<br>float: left;<br>width: 300px;<br>margin: 10px;
At first glance, everything looked fine.
Until it didn’t.
Floating elements were removed from the normal document flow.
The parent suddenly had zero height.
The solution became one of the most famous CSS snippets ever written.
.clearfix::after {<br>content: "";<br>display: block;<br>clear: both;<br>Every experienced front-end developer has probably written a version of this class.
It appeared in almost every framework of that era.
Floats Had Another Problem
Different element heights could completely change the layout.
Imagine six cards.
The second one becomes slightly taller because someone writes a longer title.
Suddenly the fourth card jumps upward.
The fifth moves sideways.
The sixth wraps to another row.
Nothing in your CSS changed.
Only the content did.
Developers spent hours chasing one missing pixel.
Modern Grid simply doesn’t have this problem.
Inline-Block Wasn’t Perfect Either
Some developers abandoned floats and switched to inline-block.
.item {<br>display: inline-block;<br>width: 240px;<br>It solved one problem.
Then introduced another.
Whitespace between HTML elements became visible spacing.
div class="item">div><br>div class="item">div><br>div class="item">div><br>Those line breaks were rendered as actual spaces.
One common workaround looked like this.
.container {<br>font-size: 0;
.item {<br>display: inline-block;<br>font-size: 16px;<br>Another trick was even stranger.
Developers literally removed every line break from the HTML.
div class="item">div>div class="item">div>div class="item">div><br>Some template engines even generated HTML exactly this way.
Others inserted HTML comments between elements to hide whitespace.
It wasn’t elegant.
It worked.
Centering Was Surprisingly Difficult
Today we usually write this.
.container {<br>display: grid;<br>place-items: center;<br>Or this.
.container {<br>display: flex;<br>justify-content: center;<br>align-items: center;<br>Years ago, neither option existed.
One popular solution abused table layouts.
.container {<br>display: table-cell;<br>text-align: center;<br>vertical-align: middle;
.box {<br>display: inline-block;
Nothing about that code suggested “center this element.”
Yet browsers interpreted it exactly that way.
Absolute Positioning Required Math
Another classic approach involved negative margins.
.dialog {<br>position: fixed;<br>width: 320px;<br>height: 180px;
left: 50%;<br>top: 50%;
margin-left: -160px;<br>margin-top: -90px;<br>Every size change required updating the negative margins.
If the dialog...