The Float-Clearing Hack Ran Production CSS for 15 Years. Flexbox Solved It in One Property.
For approximately fifteen years, from the mid-1990s to the early 2010s, professional web developers used a CSS property called float to create the column layouts that every web page required. Float was designed for one thing: making text wrap around images, like a newspaper layout. It was not designed for building multi-column pages. Using it for layout required a workaround called a clearfix to prevent parent containers from collapsing when they contained only floated children. Every site that used columns had a clearfix. Every developer who joined a project had to learn which clearfix variant the codebase used.
Before float, the preferred tool for complex layouts was even worse. In the mid-1990s, when graphical web design began to require grid-based page structures, CSS support for layout was too limited to handle them. Browsers had inconsistent support for even basic properties. The solution that spread across the industry was to use HTML table elements as a layout structure: wrapping page sections in table cells to achieve column behavior. Table-based layouts were technically reliable across browsers but semantically wrong. The markup that described page structure was being used to describe page presentation, and disentangling the two was a significant problem when browsers became more diverse and accessibility requirements more stringent.
The float era replaced tables as the semantic web movement gained influence in the early 2000s, but float was not a layout tool. It was a text-flow tool pressed into service for layout because nothing better was available. The clearfix hack, documented by Tony Aslett in 2004 and refined through multiple versions over subsequent years, became one of the most copied snippets of CSS in web development history. By the late 2000s, a standard CSS framework could contain multiple clearfix variants for different browser compatibility scenarios.
How Flexbox Changed the Fundamentals
The flexbox specification was first drafted by the CSS Working Group in 2009, explicitly to solve the alignment and distribution problems that float-based layouts had forced developers to work around for a decade. Tab Atkins rewrote the complete specification in 2011 to remove the dependency on the float, table, and inline-block hacks that the first draft had still partially required. The specification went through two major syntax revisions before settling on the current form.
Internet Explorer 10, released in 2012, implemented a version of the 2011 draft syntax. Internet Explorer 11, released in 2013, implemented most of the final specification. Chrome, Firefox, and Safari reached full interoperable support by 2014. From 2014 onward, new web projects no longer needed floats for layout. The fifteen-year era of float-based layouts effectively ended, though legacy codebases continued using them for years afterward.
The central concept of flexbox is a one-dimensional flexible container. When you apply display: flex to an element, its children become flex items arranged along a main axis. The main axis can be horizontal (the default, set by flex-direction: row) or vertical (flex-direction: column). Flex items can grow to fill available space, shrink when space is tight, or remain fixed. They can be aligned along both the main axis and the perpendicular cross axis independently.
The alignment capabilities were the most transformative change. Vertically centering an element in CSS before flexbox required absolute positioning with negative margins, setting display: table-cell, or knowing the exact pixel height of the element. Vertically centering an element of unknown height was a persistent developer pain point for which there was no clean solution. With flexbox, vertical centering on the container is align-items: center. Horizontal centering is justify-content: center. Two property declarations accomplish what previously required layout hacks.
Understanding the Flex Property
The flex shorthand property is the most commonly misunderstood part of the flexbox model. It combines three values: flex-grow, flex-shrink, and flex-basis.
Flex-grow determines how much of the surplus space in the flex container the item claims. A value of 1 means the item claims a proportional share of available space. A value of 2 means the item claims twice as much surplus space as an item with value 1. A value of 0 (the default) means the item does not grow at all and stays at its natural size.
Flex-shrink determines how much the item yields when the container is too small to fit all items at their preferred sizes. A value of 1 means the item shrinks proportionally. A value of 0 means the item never shrinks below its flex-basis and may overflow the container.
Flex-basis is the starting size from which growing or shrinking occurs. The value 0% means the item starts from zero and claims space through flex-grow. The value auto means the item starts from its content size. These two different flex-basis values produce different distribution behavior when items have different content lengths, which is why flex: 1 and flex: 1 1 auto can produce visibly different layouts on the same content.
The shorthand flex: 1 expands to flex-grow: 1, flex-shrink: 1, flex-basis: 0%. Items will grow to fill available space equally, shrink equally when needed, and start from zero rather than their content size. This is the common "equal columns" pattern.
The justify-content and align-items Distinction
The two most important flex container properties are justify-content and align-items, and confusing them is the most common source of flexbox layout errors.
Justify-content controls distribution along the main axis. By default, when flex-direction is row, the main axis is horizontal. Justify-content: flex-start clusters items at the left. Justify-content: flex-end clusters them at the right. Justify-content: center centers them. Justify-content: space-between distributes items with the first at the start, the last at the end, and equal gaps between the others. Justify-content: space-around distributes items with equal space around each one, producing half-size spaces at the edges.
Align-items controls alignment along the cross axis, perpendicular to the main axis. By default, this is the vertical dimension when flex-direction is row. Align-items: stretch (the default) makes all items the same height as the tallest. Align-items: center centers items vertically. Align-items: flex-start aligns them to the top. Align-items: flex-end aligns them to the bottom.
When flex-direction is column, the axes flip. Justify-content now controls vertical distribution, and align-items controls horizontal alignment. This axis flip is the most common source of confusion when switching between row and column layouts.
The space-between behavior has a specific failure mode that appears in many CSS code reviews: when items wrap to multiple rows using flex-wrap: wrap, space-between distributes items on each row independently. The last row, which may have fewer items than the preceding rows, distributes its items as if they are the only items on a full row. A design that looks correct with three items per row and full rows fails when the last row has one or two items, spreading them to opposite ends of the container. This is usually not the intended behavior.
Where Grid Fits In
CSS Grid, the specification that the CSS Working Group developed alongside and partly in response to flexbox feedback, was designed for two-dimensional layout. It reached broad browser support in 2017, three years after flexbox. Grid defines rows and columns simultaneously and places items into cells defined by the intersection of the two. Grid is better suited for page-level layout structures where items need to align along both dimensions at once.
Flexbox and Grid are not competitors. The common pattern is to use Grid for the outer page structure, where rows and columns of a page template need to be defined, and Flexbox for component-level layout, where items within a single row or column need to be distributed and aligned. A navigation bar is typically a flex row. A card grid is typically a CSS grid. An individual card's contents use flex.
Conclusion
ToolHQ's flexbox generator lets you configure flex-direction, justify-content, align-items, flex-wrap, and the per-item flex values visually with a live preview of multiple items. The tool outputs the complete CSS for both the container and its child items. Seeing how each property change affects the layout of actual items is faster than reading property descriptions and imagining the outcome, particularly for the space-around and space-evenly distribution values, whose difference is not obvious from the names.
Frequently Asked Questions
What is a clearfix and why was it needed?
A clearfix was a CSS technique to force parent containers to expand around floated children. Floated elements are removed from normal flow, so without a clearfix the parent collapses to zero height.
What is the difference between justify-content and align-items in flexbox?
justify-content aligns items along the main axis (horizontal by default). align-items aligns items along the cross axis (vertical by default). Together they control both dimensions of flex item positioning.
What does flex: 1 mean?
flex: 1 is shorthand for flex-grow: 1, flex-shrink: 1, flex-basis: 0%. The item will grow to fill available space and shrink equally with siblings when space is limited.