Author
Bob V.
CoffeeCup Chief
Design
Diego N.
CoffeeCup Designer
Production rights
© CoffeeCup Software
www.coffeecup.com
Flexbox is a CSS3 module for managing the distribution of space, and the positioning of elements, across the wide variety of screen sizes.
Many layout designs that were difficult or impractical to create with CSS ‘sans-flexbox’, are are now easy to achieve. Vertically aligning or evenly spacing out elements are good examples.
And for responsive designs, the possibilities are even cooler. Changing the ordering of elements for smaller (or larger) screens, for example, is simply a matter of changing the values, e.g. from 1 to 4 , for the new order property! In short, flexbox allows us to easily manipulate the layout of an entire series of elements.
Flexbox is mostly appropriate for components, or subsets, of websites and web applications. Not necessarily for the overall grid or layout.
In this guide we will go over the flexbox syntax and look at the visual effects that can be created with them. Also included are several practical examples and showcases of layout configurations made with flexbox. Let’s dive into this box of layout freedom!
We touched upon a couple of the possibilities flexbox has to offer in the introduction above. The relatively easy to understand syntax provides a tremendous amount of layout control. There are a number of online resources available that discuss the different flexbox properties and their values. However, there are very few practical demonstrations that showcase real design examples. And as we all know, making something for production can differ significantly from showing something in an isolated setting. When using the flexbox syntax in isolation, potential conflicts with other properties are left out of the picture. An example would be using flexbox centering, together with specific margin settings for elements — in that case flexbox might seem to not exactly work as expected.
So let's get warmed up for this cool (and finally widely supported CSS3 module), and kick-off with a real life design example. In the design below most of the layout configuration is handled by flexbox. The logo and navigation container are nicely spaced out in the header without using complicated floats, inline-blocks or endless margin tweaks. The same is true for the navigation links. With flexbox, it takes just a few clicks to make them display this way.
The action items (newsletter subscribe request) are placed exactly in the middle of the area below the header. Both horizontally and vertically, something that would impose a serious challenge without the help of flexbox.
The cool thing is that if you're viewing this example in Responsive Site Designer, you can easily play with the flex property values and see how the elements behave. Go ahead, click on the picture above to select the flex parent container. Then, on the design pane, scroll down to the position section. The flex controls are located right below the display drop down.
You’ll see that changing the flex-direction is pretty intuitive. Depending on the value, the elements are stacked as a column or displayed inline as a row. Changing the justify-content drop down influence the position of the elements in that column or row. Now don’t go too wild immediately! Using flexbox is way more fun with a slightly better understanding of the mechanics.
Want to play with flexbox? Download a trial version here.
As mentioned in the introduction, the current best practice is to use flexbox for subsets of the layout, not for constructing a complex, grid-based full page layout. One of the main reasons is that for large pages and/or slow connections, the layout can shift around during page loading.
It is also not clear from the official specification if flexbox was indeed intended for that type of usage. In fact, considering that the CSS Grid Layout workgroup includes several of the same Editors, it seems more likely that the flexbox layout module was designed to address specific layout problems within parts of the overall layout, rather than to create a layout module for page or grid construction.
Don’t take me wrong, flexbox is one of the most versatile and intuitive layout systems. However, it performs best when set to a specific purpose like, for example, aligning a series of items within a container. It’s also great for changing the layout direction or even the visual order of elements over different screen widths.
Time to set up the initial flex layout, following which we can get to work on some fun demos and use cases!
A flex layout is created by setting the display property of a container element to flex. This can be any element that contains other elements, from a simple column or container, to a subgrid or list element. The container can be any type of HTML container, a simple <div> or a more semantically labelled element such as a <section> or <nav>. When the flex display value is used, the parent container becomes a flex-container, and all immediate children become flex-items.
The main characteristic of the flex container is the ability to modify the order, position, alignment, width or height of its children. This allows the designer to use the available space in the best possible way.
As we saw in the example above, even symmetrical perfection can be achieved. True, before flexbox we were able to use margin or padding to vertically center elements within a section. Or at least approach it for a static layout. But keeping multiple elements aligned is a big endeavour, especially if they are not the exact same size.
In addition, we’re living in a multi-device world where responsive design is a requirement and height changes are very common — due to, for example, wrapping text. As soon as that happens we would be entering the trouble zone, chasing height using breakpoints without a real solution to the problem.
In short, cleverly positioning elements within a container is both more powerful and less complicated with flexbox. There are five properties for the flex-container that can be used to influence the way the flex-items are laid out.
The flex-direction property is used to define the direction the flex-items follow in the flex container. The initial function is to tell the flex-items to position as (horizontal) rows or (vertical) columns.
In addition they can be instructed to change their natural order and reverse their position from right-to-left or bottom-to-top.
The design example below illustrates the directional behavior. I dropped three containers in the (single column) of a full-width row. The normal behavior of these block elements would be to stack vertically, but choosing display flex for the column and setting the flex-direction to row places them nicely next to each other.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce bibendum.
Quisque eleifend gravida libero, vitae ultricies augue blandit vel. Mauris dictum purus in dictum ultrices. Integer id odio ac erat sagittis mattis non at nunc.
Phasellus consequat, sapien id varius fermentum, justo erat ultricies ante, sed aliquet justo quam eget mi.
Using a width of 100% these containers would try to take up all the space they can get. However, flexbox tells them to split the available space in 3 (or in whatever number of elements would be placed there) so they fit next to each other.
Want to display the items in a different order? That’s no problem when using flexbox. Simply set the flex-direction to reversed-row and you’ll get the result you see below.
The white containers are not only flex-items, they are flex-containers too because they also use the flex display property for arranging the elements inside. For these three flex-containers we are using a different flex-direction: column . The justify-content property is used to center the items within the container.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce bibendum.
Quisque eleifend gravida libero, vitae ultricies augue blandit vel. Mauris dictum purus in dictum ultrices. Integer id odio ac erat sagittis mattis non at nunc.
Phasellus consequat, sapien id varius fermentum, justo erat ultricies ante, sed aliquet justo quam eget mi.
The elements inside the container get some extra styles. The paragraph text for example is centered and gets room on the sides from a 10% margin.
I also added a max-width. In theory this would not be needed since the margin takes care of it all… Unfortunately, there’s a bug in IE where paragraph text in a flex-container does not wrap. The max-width is used to battle the issue.
The project design went really smooth up until now. And that’s exactly how it is for demos that explain how flexbox works in isolated settings using stable, single-size, placeholders. But we’re dealing with a real design case here. The design has to look good, we’re using real elements, combinations of elements, and the paragraphs have different text lengths. And that’s how we find how flexbox really works!
Let’s look a bit deeper into the width settings for the container elements. Giving them a width of 100% and using the flexbox settings as explained above, gives each of them an equal amount of the available space. But if we change the width to auto , the width of each container varies. Without content inside they are all small, only as wide as defined by a default minimum width setting. With the exact same content, they all get the exact same width.
Things get interesting when different content like, for example, different paragraph lengths, is used in the same type of container. Using auto values for the width and flex-basis (we’ll get back to this property later), the flex-item is automatically sized based on the its content. In our example, the only difference is the text length of the three paragraphs. This causes the containers with more text to be wider than the containers with less text. Please note that in order to demonstrate this the max-width had to be removed from the paragraph. That also means that if you’re reading this in IE, the bug I referenced above will pop up causing the text to overlap.
Now, is this behaviour desirable? Looking at the example below, this can definitely be neat. However, with the different container sizes the images will resize differently at smaller widths. And although the containers maintain the same height when that happens, the horizontal alignment of the content is not maintained, a likely undesirable consequence for most design cases.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce bibendum.
Quisque eleifend gravida libero, vitae ultricies augue blandit vel. Mauris dictum purus in dictum ultrices. Integer id odio ac erat sagittis mattis non at nunc.
Phasellus consequat, sapien id varius fermentum, justo erat ultricies ante, sed aliquet justo quam eget mi.
The above already illustrates the powerful layout design possibilities flexbox offers. Independent of size container or element size, flex-items can be placed on a single line. This default behavior, always fitting all items onto one line can be influenced as well. That’s where the flex-wrap property comes into play.
The flex-wrap property can be used to position a series of items on a single, or on multiple lines. If there is not enough space available for the natural size of the elements, setting this property to wrap will place items that do not fit on the next line.
The flex-container (column) below contains two blockquote elements. Yep, they are nicely vertically aligned, but that is something we will talk about related to other flex properties. The point here is that when using wrap (with no-wrap being the default) as value for the flex-wrap property, these quotes will stack instead of shrink when there’s not enough room in the container to display them next to each other.
If you’re following along within Responsive Site Designer this is easy to test: select one of quotes and on the design pane, increase the max-width to 600px . With the row never being wider than 1200px this will make them stack.
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer erat a ante."
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante Lorem ipsum dolor sit amet, consectetur posuere erat a ante."
Using the width slider and decreasing the viewport width below to about 880px will have the same effect. If you’re reading this in a browser you can squish the windows to make them stack.
Both the width of an element and the available space are influenced by many parameters. Widths, heights, max-widths, paddings, and margins, they all play a role. As does the content itself.
If the width is defined in pixels, all is clear. However, in a responsive design widths are mostly relative, often with a width defined beyond which the element should not grow anymore. One would expect the browser to use the max-width value as the ‘maximum natural size’ and most of them do. This time it is Safari, or more precisely the WebKit rendering engine, that presents us with some unexpected behavior.
Whenever a width has been defined for a flex-item, WebKit uses it for calculating the remaining available space, ignoring any maximum width that may have been applied. An element with a 100% width and max-width of 400px will never be wider than the specified 400px pixel size. Still WebKit will take the 100%, inadvertently concluding that no space is available and stack the elements.
The work around? Not specifying a width! Using width: auto will do wonders. And if automatic resizing based on the content is not desirable, the max-width property can be used to restrain the content. Something that is needed on paragraphs to make IE behave anyway. Using the flex-basis property could be another option for preventing the resizing, we’ll look into that later. Now let’s see what options we have to distribute the flex-items over the horizontal or vertical space.
This property can be used to distribute the flex-items over the space defined in the flex-direction. If the flex-direction is set to row , the justify-content control determines how the elements are spaced out horizontally.
Similarly, when the flex-direction is used to create columns, this property determines how the elements are spaced out horizontally.
Let’s add some fresh images and see how the different values influence the positioning of the three containers. To better illustrate this (and save some room) I constrained their width to 180px. The elements, picture and header, were made smalle. The paragraph has been removed.
The default value for the justify-content property is flex-start . The first example shows this, the items are stacked towards the side where the flex-direction starts. As is seen on the second example, when the flex-direction changes, so will the position where the items start.
The opposite of the default value is flex-end You can easily imagine how that will work, or change the value for the design example above.
There are three other values for this property. The center value centers the flex-items along the axis of the flex-direction. Elements can also be evenly distributed across the available space using space-between . The first item is placed where it would be originally when using flex-start. The last item is placed at the end of the axis and all other items are positioned evenly in-between.
The space-around value creates equal space around the elements. Since there's equal space on both sides of the flex-items, the first and last item will be closer to the container edges than the items are to each other.
The three examples below illustrate this using the row value as flex-direction.
No more chasing heights thanks to stretching containers.
This property is used for aligning the flex-items on the cross axis of the defined direction. It’s very similar to justify-content but works on the perpendicular direction. Continuing with our example where we use row as flex-direction, we can influence the vertical alignment of the three containers. In order to show this we’ll have to make them different in height first.
To accomplish this for example below I used a maximum-height on the pictures in the first and last containers. Without flexbox this would make these white containers shrink as the height is usually determined by its contents. In this case, with the default value stretch for the align-items property, the containers will keep filling the vertical space created by the larger middle container. A really handy feature indeed, thanks flexbox!
The second and third example show what happens when the value is changed to flex-start and flex-end respectively.
The containers stop stretching. They take the height of their contents, and position themselves in the remaining vertical space created by the larger middle container.
The flex-items can also be vertically centered using the center value. The very first example of this guide uses the center values for both axes (justify-content and align-items) to create the sweet symmetrical effect on top of the background image.
The last property that can be used here is baseline . This could be useful when the different flex-items would use different fonts or font-sizes. Using baseline as value, the items would be aligned according to the baseline of the font.
Overall the align-items property works in a similar way to the justify-content property, only on the other axis than specified by the flex-direction. This means that if you change the flex-direction, the justify-content and align-items controls switch the axis they were working on. Something to take into account!
When there is more than a single line — more than a single column or row — of items, this property can be used to distribute the space between the lines. Additional lines are created when there’s not enough space for the flex-items and they are told not to shrink using the no-wrap property.
Let’s create a little playground by reusing the quote section that we looked at earlier. I extended it a bit by adding two more elements and using real customer quotes for (Responsive Site Designer) that by nature have varying text lengths.
I also removed the width constraint from the row to give the quotes more room on large monitors. The column (flex-container)now has a minimum height, giving us more vertical room to play with.
The very first thing that comes to mind when looking at that section is how awesome Responsive Site Designer is easy flexbox makes it to align elements with varying height. No matter the what display width is, the items will line up (and neatly wrap) when space is limited. There’s a little catch here though...
"I would pay thousands for this software and can't believe your prices. This is Adobe-territory, only much easier to use and a fraction of the price. "
"Responsive Site Designer is nothing less than a work of genius! A true revolution in website design."
"Thank you for such an unbelievably, awesome program."
"I think this is the best application I have used; it is simple to create some stunning sites with the minimum of technical knowledge … what a time saver"
Got some insight here? Please hit me up on twitter so we can discuss!
Using both the align-items and align-content properties together, creates a difference in some browsers with how the above blockquotes are displayed.. I found that Chrome uses different display rules than other browsers. The number of combinations is quite large though, and I have not (yet) stepped through all browsers meticulously.
However, I amsure nothing dramatic happens, the elements are aligned (slightly) differently and remain very readable and usable overall.
In the example above I am using flex-end for the align-items control and center for center for align-content. This vertically centers the boxes and aligns the bottom borders in Firefox, Safari and Internet Explorer. Chrome does this differently by positionin the elements at the bottom (flex-end) of the flex-container.
Up to now we have been looking at the layout variations using property controls and values for the flex-container. An additional number of display possibilities can be created by defining flexbox rules for the (direct) children in the flex-container.
Initially the elements inside a flex-container are displayed in the order they were added. We already saw that this order can be reversed using the flex-direction property on the flex-container.
The order property available for the flex-items gives additional control over the order in which the elements are presented. Reusing the example with the horizontally centered items, we can switch the position of the third and second flex-item.
All we need for that is to assign order values. Using a value of 1 for the last flex-item and 2 for the middle item, will make them swap positions. All integer values are allowed here. Giving the third item a value of -1 would make it the first placed element.
Since these items share the same clase, values for flexbox items should be assigned to a different selector. A good rule of thumb is to use an additional class if the value is shared between a subset of the flex-items, and to add an ID if the value is specific to only one flex element. Order numbers are generally unique so I assigned them to separate IDs.
Give that <picture> element link a follow if you have a second. It’s offering something we all should be using more!
Changing the order of items can be useful when layout changes are needed for different screens. Let’s consider a practical use case.
Product or service presentations are frequently laid out using a combination of text and images next to each other on wider screens. Then below the image-text order for the next product or feature is reversed. However, with less horizontal space available on small screens, many prefer to stack the items.
We are using a similar format on many of our pages for describing features of our software products.
On the Responsive Site Designer page, for example, we talk about increasing website performance using the <picture> element. Following that we discuss adjusting layouts for optimal viewing experience on any screen. It would be weird if the two text sections would follow each other on mobile devices; the separation of the two features would not be visually clear to the reader.
To battle that we are "pushing and pulling" the columns. This can very well be done both manually and (using the drop downs) in RSD, but requires some conceptual layout thinking. Flexbox makes this way smoother and easier
The design below uses a similar layout as just discussed.
Net Wt. 6.2 Oz
$ 24.00
Simply work into a lather with warm water and massage onto wet face, rinse clean. For traditional wet shaving: With a wet shave brush or hands, work into a rich lather with warm water and apply to damp beard. Proceed to shave with preferred razor for a close, smooth, clean and moisturizing shave. The rich lathering quality of our Glycerin along with the infused Vitamin E, Safflower, Palm and Coconut oils will protect your skin and provide optimal blade glide – without any residue left behind.
Add to cartNet Wt. 7.9 Oz
$ 29.00
Simply work into a lather with warm water and massage onto wet face, rinse clean. For traditional wet shaving: With a wet shave brush or hands, work into a rich lather with warm water and apply to damp beard. Proceed to shave with preferred razor for a close, smooth, clean and moisturizing shave. The rich lathering quality of our Glycerin along with the infused Vitamin E, Safflower, Palm and Coconut oils will protect your skin and provide optimal blade glide – without any residue left behind.
Add to cartBye bye push & pull. Hello order!
According to the natural element order, the product description and add to cart button of flex-item-1 are immediately followed by the product description of flex-item-2.
On wide screens the layout provides a nice visual separation between the two different products. On smaller screens — on the left of the 768px breakpoint — the product image and description are stacked. This would have visually created one large block of text if the order would not have been changed.
This would not only have been unappealing from an aesthetic perspective, it could also be potentially confusing for the reader. To change the order at the breakpoint I added a class to the second image and assigned an order value of -1 .
Please note that screen readers will continue to follow the natural order of the elements. If we want the screen readers to follow the image+text → image+text order, we should add the elements in that order. Then, on wide screens, we reverse the order of the image and text container to create the same visual effect as in the current design.
The ability to calculate and distribute space is one the greatest strengths of flexbox. The flex grow, shrink and basis properties can be used to influence how the available space in the parent (flex) container is allocated between the flex-items.
The flex-basis CSS property specifies the initial size of a flex item. The default value is auto which instructs the browser to use the currently calculated width or height. In our examples where each of the flex-items (the white containers) used the same width (100%), the space gets distributed equally.
A specific initial size can be defined as well. The value can be set in pixels, ems or a percentage. (Please note that in RSD we currently only provide for percentages for this and several other size related controls. We do have a unit switcher on our roadmap for one of the upcoming versions though!)
In the example below I gave each of the white containers an ID and assigned individual values for the flex-basis. The middle container is instructed to use 40% of the space, whereas the other two container each get 15% . This means that 30% of the space is left empty….but only as long as flex-grow is set to 0 !
Please note that I changed the percentages for small screens to 20%, 30%, 20%.
The flex-grow property determines what will happen with any remaining empty space. When changing the flex-grow value to 1 for flex-item-1 it will take up all the space that was left. This makes the element 45% (15% + 30%) of the column width. (Minus any allocated margin or padding.)
If the flex-grow for item-3 is set to 1 as well, the leftover space is equally distributed between both items. This is illustrated in the example below.
The flex-grow is not relative to other items. An element with flex-grow of 4 will not always be twice the size of an item with a flex-grow of 2. Increasing the flex-grow for an item just means that the amount of remaining space it receives will be increased.
Increasing, for example, the value to 2 for the first item, would give it twice as much of the leftover space as the last item. And so on.
The flex-shrink property works in a similar way. It determines which of the items needs to lose most of its size to compensate for any missing space (when the items are wider than the parent container).
It will be clear that the flex-grow (and shrink for that matter) will be less useful in the context of a fluid percentage based layout. I can see specific design cases where it could come in handy to have a certain item grow (and shrink) automatically from an initial situation where they are all sized equally. Right now this can be done by changing the values at a breakpoint, but it’s a little less automatic.
We already learned that Flexbox can be used to create cards of the exact same height, even if the contents within the cards differ. Keeping action buttons or links horizontally aligned underneath a text section, has always been one of the other challenges when using flexible layouts.
Even with similar text lengths sentences of one section would wrap before the other sections. This then would push the items underneath down, before they would get pushed down in the other sections.
The example below shows three sections, or ‘cards’ as they are often called. The images are the same size, the headings are the same, as well as the paragraph styles. The only difference is the text length of each paragraph.
It is a rather significant difference. Yet, the action buttons are perfectly aligned with each other. This happens because of two reasons. First, the cards (containers) with less content stretch as much is needed to have the same height as the container with the most content. Secondly, the paragraphs are instructed to take up any remaining available space that is created because of the stretching.
Instructing an element to take up remaining space is done through the flex-grow property. With a value of 1 — and an implied value of zero for the other elements — the paragraph is greedy and consumes all left-over space. With a background applied to the paragraph this would have been visible.
If you are reading this guide in Responsive Site Designer, I invite you to apply that background to the paragraph and look at the effect. Another useful exercise would be to remove the flex-grow class from the first (or last) paragraph. The flex-growth is tied to this selector and without it, the button will immediately move back up right under the text.
The flex-grow (and its counterpart flex-shrink) property might take a little to get used, but they can be very powerful allies in a document where element and layout dimensions changed based upon available display width. As we touched upon earlier, a flex-grow value of 2 for an elements means it can take up twice as much of the remaining space as elements with a value of 1. Can you imagine the possibilities?
Quisque eleifend gravida libero, vitae ultricies augue blandit vel. Mauris dictum purus in dictum ultrices. Integer id odio ac erat sagittis mattis non at nunc.
Add to cartPhasellus consequat, sapien id varius fermentum, justo erat ultricies ante, sed aliquet justo quam eget mi.
Add to cartThe alignment specified by align-items on a parent level can overridden for individual flex items. In the example below the first item is displayed according to the align-items: flex-start rule defined by the parent.
The second items gets an align-self: center rule specified on the ID selector. The third item is told to position at the bottom of the container using flex-end.
The vertical space that is needed for this design example is created by giving the parent container a minimum height.
The web is not a fixed-size magazine, but a fluid medium where content needs to flow and flex to provide stellar user experiences, on any of screen size or device.
Although there’s still a lot to be learned about how flexbox can make our design work both easier and better, there’s no doubt that flexbox is a great extension of our toolkit.
We are impressed and hope you are too. Flexbox is a tremendous addition to our layout design arsenal — for large monitors, small mobile screens and everything in-between. We hope this guide made you become a flexbox fan as well!
If you like what you read here you also might want to check out our guide for designing responsive table with flexbox.