Key Takeaways
- Flexbox, officially known as the CSS Flexible Box Layout Module, is designed to manage layout in one directionâa row or a column.
- By adding display: flex or display: inline-flex to a containing element, its immediate children become flex items that behave according to the rules of flex layout.
- Flexbox simplifies the code necessary for a range of user interface patterns, such as creating flexible form components or vertically centering elements.
- When choosing between Flexbox and Grid, use Grid for arranging elements into rows and columns that align both horizontally and vertically, and use Flexbox for arranging items in a row or a column, when you wish to align items vertically or horizontally, but not both.
The following introduction to Flexbox is an extract from Tiffanyâs new book, CSS Master, 2nd Edition.
Before CSS Grid came along, there was Flexbox (which is officially known as the CSS Flexible Box Layout Module). Flexbox was designed to manage layout in one directionâa row (flex-direction: row or row-reverse) or a column (flex-direction: column or column-reverse). Thatâs in contrast to Grid, which accounts for rows and columns.
A basic flexible box layout is simple to create: add display: flex or display: inline-flex to the containing element. These values for display will trigger a flex formatting context for that containing elementâs children. As with Grid, both flex and inline-flex are inside display modes. We set these values on the container, which behaves like a block-level or inline-level box, respectively. The children of that container are then arranged according to the rules of flex layout.
Note: Older versions of Blink-based browsers such as Chrome (†28), and WebKit-based browsers like Safari (†8), require a vendor prefix. If your project still supports those browsers, youâll need to use display: -webkit-flex or display: -webkit-inline-flex. Older versions of Firefox (†21) also require a prefix. Use -moz-flex and -moz-inline-flex to support those browsers.
By adding display: flex or display: inline-flex to a containing element, its immediate children become flex items, as shown in the image below. Flex items may be element children or non-empty text nodes. For instance, the markup below generates three flex item boxes that each behave according to the rules of flex layout:
<div style="display: flex">
<span>This text is contained by a SPAN element.</span>
<b>This text is contained by a B element.</b>
This text node is still a flex item.
</div>
If no other properties are set, each flex item will have the same height as its tallest element (as determined by content). It will also stack horizontally (or vertically when the document has a vertical writing mode) without wrapping, and with no space between the edges of each box. Flex items may overflow the container.
A list with display: flex applied to the ul containing element
This may not seem like such a big deal, but it simplifies the code necessary for a range of user interface patterns. Letâs look at a couple of examples.
A New Media Object Component
Take the following media object code:
<div class="media__object">
<img src="video-thumb1.jpg">
<div class="media__object__text">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>
</div>
Before Flexbox, we might have paired the preceding markup with the following CSS:
.media__object img {
float: left;
height: auto;
width: 150px;
}
.media__object__text {
padding-left: 170px;
}
/* Let's use the clearfix hack! */
.media__object::after{
content: ' ';
display: block;
clear: both;
}
This layout works, but it has one major drawback: it requires us to constrain the width of our images so that we know how much padding to use. That limits our ability to use this same component in multiple contexts. You may want an image 150px wide when this component is used for a âRelated Storiesâ widget, and one thatâs only 75px wide for comments.
Letâs try this using Flexbox. Hereâs our updated CSS:
.media__object {
display: flex;
}
.media_object img {
margin-right: 20px;
}
Thatâs a lot less CSS. An added bonus is that we donât have to worry about how wide or tall our image is. Nor do we have to concern ourselves with clearing floats. Whether the image is 200px wide or 20px wide, .media__object__text will abut the margin box of our img element.
Creating Flexible Form Components with flex
Another use case for Flexbox is creating flexible, vertically aligned form components. Consider the interface pattern shown in the image below.
A form field with an adjacent button
Here, we have a form input control and an adjacent button. Both are vertically aligned, and our button is 150px wide.
What if we want our input element to expand to fill the available space in its container? Without Flexbox, weâd need some JavaScript and hand-waving to update the width of input in response to changes in the width of its parent. With Flexbox, however, we can just use flex.
The flex property is actually shorthand for three other properties.
flex-growindicates that an element should grow if necessary and must be a positive integer. Its initial value is0.flex-shrinkindicates that an element should shrink if necessary and must be a positive integer. Its initial value is1.flex-basis:indicates the initial or minimum width (when the flex axis is horizontal) or the height of an element (when itâs vertical). It may be a length or percentage, orauto, and its initial value isauto.
Though itâs possible to set each of these individually, the specification strongly recommends using the flex shorthand. Hereâs an example:
div {
display: flex;
}
input[type="text"], button {
border: 0;
font: inherit;
}
input[type="text"] {
flex: 1 0 auto;
}
button {
background: #003;
color: whitesmoke;
display: block;
text-align: center;
flex: 0 0 150px;
}
Here, weâve used flex: 1 0 auto for our input element. Since its flex-grow value is 1, it will grow to fill the available space of its parent. For the button element, however, weâve used flex: 0 0 150px. The 0 values for flex-grow and flex-shrink prevent the width of the button from increasing or decreasing, while the flex-basis value of 150px sets its width.
As you can see in the image below, our button remains the same size, but the width of input expands to fill the remaining space.
This growth is also why justify-content: space-between can appear to fail on wide screens, as covered in why justify-content: space-between stops working on wide screens.
The effect of flex: 0 0 150px
The tricky bit about flex-grow and flex-shrink values is that theyâre proportional. Yes, flex: 1 0 auto means our input element will be wider than our button. But changing the value of our buttonâs flex property to flex: 1 0 auto doesnât necessarily mean that both elements will have the same size, as shown in the following image.
Both items have the same flex value but are still different sizes
Instead, flex items will be resized to fill the container, taking their used min-width and max-width values into account (which may be their initial values).
Unfortunately, we canât use fr units with the flex or flex-basis properties. Use length or percentage values instead.
Vertical Centering with Flexbox
Finally, letâs take a look at how to vertically center content with Flexbox. Vertically centering elements is one of the more difficult tasks to achieve with CSS, particularly if the height of your content is unknown. But with Flexbox, we require just one additional line of CSSâalign-items: center:
.flex-container {
display: flex;
align-items: center;
}
Now our flex items and their contents are vertically centered within the flex container, as shown in the image below.
Distributing flex items with align-items: center
Creating Grid-like Layouts with Flexbox
In most cases, youâll want to use Grid to create grid-like layouts. However, you may find yourself wanting boxes that align when thereâs an even number of items, but expand to fill the available space when thereâs an odd number.
A grid-like layout with expanding cells
Hereâs the markup weâll use:
<ul class="flex-aligned">
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
<li>E</li>
<li>F</li>
<li>G</li>
</li>
By default, flex items donât wrap. To achieve the layout above, weâll need to make them wrap using the flex-wrap property. It accepts three values: nowrap (the inital value), wrap, and wrap-reverse. Weâll use wrap here:
.flex-aligned {
display: flex;
flex-wrap: wrap;
}
Now we just need to indicate how our flex items should behave, and what their maximum width should be. Since we want a maximum of four columns, weâll set our flex-basis value to 25%. And since we want our flex items to expand to fill the available space, weâll set flex-grow to 1. Weâll keep flex-shrink at 0 so that our boxes never occupy less than 25% of their container:
.flex-aligned li {
flex: 1 0 25%;
}
Learning More about Flexbox
Thereâs a lot more to Flexbox than what weâve covered here. CSS-Tricksâ âA Complete Guide to Flexboxâ digs into all the properties and values. You can also check out Philip Waltonâs âSolved by Flexboxâ, which showcases UI patterns that are made easier with Flexbox.
Choosing flex or grid
As you develop page or component layouts, you may find yourself wondering when itâs better to use Flexbox and when to use Grid.
- Use Grid when you want to arrange elements into rows and columns that align both horizontally and vertically.
- Use Flexbox when you want to arrange items in a row or a column, when you wish to align items vertically or horizontally, but not both.
Jen Simmonsâ video âFlexbox vs. CSS Grid â Which is Better?â walks you through some things to consider when choosing between Grid and Flexbox. Rachel Andrewâs âShould I use Grid or Flexbox?â is another great resource for understanding both.
In practice, your projects will probably mix both of these techniques, as well as floats. For instance, you may use Grid to define the overall page layout, while using Flexbox for your navigation menu or search box, and floats to place tables or images.
Frequently Asked Questions about Creating Flexible Layouts with Flexbox
What is the difference between Flexbox and CSS Grid?
Flexbox and CSS Grid are both layout models in CSS. While they may seem similar, they serve different purposes. Flexbox is a one-dimensional layout model that allows you to control the layout of items in a container along a single axis â either horizontally or vertically. Itâs ideal for components of an application or small-scale layouts. On the other hand, CSS Grid is a two-dimensional layout model that allows you to control the layout of items both horizontally and vertically at the same time. Itâs ideal for larger scale layouts that require control over both rows and columns.
How can I align items vertically in a Flexbox?
To align items vertically in a Flexbox, you can use the âalign-itemsâ property. This property aligns items along the cross axis (which is vertical if the main axis is horizontal). For example, if you want to center items vertically, you can use âalign-items: centerâ. Other possible values for this property include âflex-startâ, âflex-endâ, âbaselineâ, and âstretchâ.
What does the âflexâ property do in Flexbox?
The âflexâ property in Flexbox is a shorthand property that sets the âflex-growâ, âflex-shrinkâ, and âflex-basisâ properties in one go. It allows you to control how a flex item grows and shrinks relative to the rest of the flex items in the container, as well as its initial size before any available space is distributed. For example, âflex: 1 1 autoâ means the item can grow and shrink, and its initial size is âautoâ.
How can I reverse the order of items in a Flexbox?
To reverse the order of items in a Flexbox, you can use the âflex-directionâ property with the value ârow-reverseâ or âcolumn-reverseâ. This will reverse the order of items along the main axis. For example, âflex-direction: row-reverseâ will reverse the order of items from left to right.
Can I use Flexbox with all browsers?
Flexbox is widely supported in all modern browsers, including Chrome, Firefox, Safari, Edge, and Internet Explorer 10 and later. However, there may be some differences in how these browsers render Flexbox layouts, especially in older versions. Therefore, itâs always a good idea to test your layout in different browsers to ensure it looks and works as expected.
How can I create a responsive layout with Flexbox?
Flexbox makes it easy to create responsive layouts without having to use media queries. By using the âflex-wrapâ property, you can allow flex items to wrap onto multiple lines, creating a responsive layout. For example, âflex-wrap: wrapâ will allow items to wrap onto the next line if thereâs not enough space in the container.
What is the difference between âjustify-contentâ and âalign-itemsâ in Flexbox?
In Flexbox, âjustify-contentâ and âalign-itemsâ are used to align items along the main axis and the cross axis, respectively. âjustify-contentâ aligns items along the line on which theyâre laid out (which is horizontal if the main axis is horizontal), while âalign-itemsâ aligns items perpendicular to this line.
How can I make a flex item take up the remaining space in the container?
To make a flex item take up the remaining space in the container, you can use the âflex-growâ property with a value greater than 0. This will allow the item to grow and take up any remaining space after all items have been laid out and any space has been distributed.
Can I nest Flexbox containers?
Yes, you can nest Flexbox containers. This means you can have a Flexbox container inside another Flexbox container. This can be useful for creating complex layouts. However, keep in mind that the properties of the parent container donât affect the child containers, and vice versa.
How can I control the order of flex items?
You can control the order of flex items using the âorderâ property. This property takes an integer value, with higher values appearing later in the display order. By default, all flex items have an order of 0. For example, âorder: 1â will make an item appear after items with an order of 0.

