Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maintenance: CSS flex wrapping: updates to guide 6 #34295

Merged
merged 2 commits into from
Jun 24, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ page-type: guide

{{CSSRef}}

Flexbox was designed as a single dimensional layout, meaning that it deals with laying out items as a row or as a column — but not both at once. There is however the ability to wrap flex items onto new lines, creating new rows if {{cssxref("flex-direction")}} is `row` and new columns if `flex-direction` is `column`. In this guide I will explain how this works, what it is designed for and what situations really require [CSS Grid Layout](/en-US/docs/Web/CSS/CSS_grid_layout) rather than flexbox.
Flexbox was designed as a single dimensional layout, meaning that it deals with laying out items as a row or as a column — but not both at once. That doesn't mean we can't wrap flex items onto new lines, creating new rows if {{cssxref("flex-direction")}} is `row` and new columns if `flex-direction` is `column`. This guide explains flexbox wrapping, what it is designed for and what situations really require [CSS grid layout](/en-US/docs/Web/CSS/CSS_grid_layout) rather than flexbox.
estelle marked this conversation as resolved.
Show resolved Hide resolved

## Making things wrap

The initial value of the {{cssxref("flex-wrap")}} property is `nowrap`. This means that if you have a set of flex items that are too wide for their container, they will overflow it. If you want to cause them to wrap once they become too wide you must add the `flex-wrap` property with a value of `wrap`, or use the shorthand {{cssxref("flex-flow")}} with values of `row wrap` or `column wrap`.
The initial value of the {{cssxref("flex-wrap")}} property is `nowrap`. This means if a set of flex items are too wide for their container, they will overflow it. To them wrap once they are too wide, add the `flex-wrap` property with a value of `wrap`, or use the shorthand {{cssxref("flex-flow")}} with values of `row wrap` or `column wrap`. Items will then wrap in the container.
estelle marked this conversation as resolved.
Show resolved Hide resolved

Items will then wrap in the container. In the next example I have ten items all with a `flex-basis` of `160px` and the ability to grow and shrink. Once the first row gets to a point where there is not enough space to place another 160 pixel item, a new flex line is created for the items and so on until all of the items are placed. As the items can grow, they will expand larger than 160 px in order to fill each row completely. If there is only one item on the final line it will stretch to fill the entire line.
In this example, there are ten flex items with a `flex-basis` of `160px` that can grow and shrink. Once there is not enough space to place another 160 pixel item in a row, a new flex line is created. New lines are created as needed until all of the items are placed. As the items can grow, they will expand to fill each row completely. If there is only one item on the final line it will stretch to fill the entire line.

{{EmbedGHLiveSample("css-examples/flexbox/wrapping/row-wrap.html", '100%', 650)}}

We can see the same thing happening with columns. The container will need to have a height in order that the items will start wrapping and creating new columns, and items will stretch taller to fill each column completely.
The same thing happens with flex columns. To wrap and create new columns, the container needs to have a height. In the case of columns, items stretch vertically to fill each column completely.

{{EmbedGHLiveSample("css-examples/flexbox/wrapping/column-wrap.html", '100%', 810)}}

Expand All @@ -32,33 +32,31 @@ Note that the reversing is only happening in the inline, row direction. We start

As we have seen from the above examples if our items are allowed to grow and shrink, when there are fewer items in the last row or column then those items grow to fill the available space.

There is no method in flexbox to tell items in one row to line up with items in the row above — each flex line acts like a new flex container. It deals with space distribution across the main axis. If there is only one item, and that item is allowed to grow, it will fill the axis just as if you had a single item flex container.
There are no flexbox features to tell items in one row to line up with items in the row above — each flex line acts like a new flex container. It deals with space distribution across the main axis. If there is only one item, and that item is allowed to grow, it will fill the axis just as if you had a single item flex container. If you want layout in two dimensions then you probably want grid layout.

If you want layout in two dimensions then you probably want Grid Layout. We can compare our wrapped row example above with the CSS Grid version of that layout to see the difference. The following live sample uses CSS Grid Layout to create a layout that has as many columns of at least 160 pixels as will fit, distributing the extra space between all columns. However, in this case the items stay in their grid and don't stretch out when there are fewer of them on the final row.
This example demonstrates to the difference, using CSS grid layout to create a layout that has as many columns of at least `160px` as will fit, distributing the extra space between all columns. We use the same HTML as the [flexbox wrapped row example](#making_things_wrap) above, but set `display: grid` set. Instead of the {{cssxref("flex")}} shorthand, which has no effect outside of flexbox, we set the item's minimum width and ability to grow directly on the container with {{cssxref("grid-template-columns")}}. With grid, the last item stays in its grid cell; grid items don't stretch out when there are fewer of them in the last row.
estelle marked this conversation as resolved.
Show resolved Hide resolved

{{EmbedGHLiveSample("css-examples/flexbox/wrapping/grid-example.html", '100%', 700)}}

This is the difference between one and two-dimensional layout. In a one dimensional method like flexbox, we only control the row or column. In two dimensional layout like grid we control both at the same time. If you want the space distribution row by row, use flexbox. If you don't, use Grid.
This is the difference between one and two-dimensional layout. In a one dimensional method like flexbox, we only control the row or column. In two dimensional layout like grid, we control both at the same time. If you want the space distribution row by row, use flexbox. If you don't, use grid.
estelle marked this conversation as resolved.
Show resolved Hide resolved

## How do flexbox-based grid systems work?

Typically flexbox-based grid systems work by taking flexbox back to the familiar world of float-based layouts. If you assign percentage widths to flex items — either as `flex-basis` or by adding a width to the item itself leaving the value of `flex-basis` as `auto` — you can get the impression of a two dimensional layout. You can see this working in the example below.
Flexbox-based layouts can be forced to line up as grid systems, but that is not the intended purpose of flexible box layout. If you assign percentage widths to flex items — either as `flex-basis` or by adding a width to the item itself leaving the value of `flex-basis` as `auto` — you can get the impression of a two dimensional layout.
estelle marked this conversation as resolved.
Show resolved Hide resolved

Here I have set `flex-grow` and `flex-shrink` to `0` to make inflexible flex items and I'm then controlling flexibility using percentages, just like we used to do in float layouts.
In this example, `flex-grow` and `flex-shrink` have been set to `0` to make inflexible flex items. The flexibility is controlled via percentages.

{{EmbedGHLiveSample("css-examples/flexbox/wrapping/flex-grid.html", '100%', 650)}}

If you need flex items to line up in the cross axis, controlling the width in this way will achieve that. In most cases however, adding widths to flex items in this way demonstrates that you would probably be better served by switching to grid layout for that component.
If you need flex items to line up in the cross axis, controlling the width in this way will achieve that. When you catch yourself adding widths to flex items in this way, or adding several empty flex items to take up space, it a good indication you may want to switch to grid layout for that component.
estelle marked this conversation as resolved.
Show resolved Hide resolved

## Creating gutters between items

To create gaps or gutters between flex items, use the {{CSSXref('gap')}} property.
To create gaps or gutters between flex items, use the {{CSSXref("gap")}} property directly on the flex container to create a fixed space between adjacent flex items. The gap property in CSS is a shorthand for `row-gap` and `column-gap`, specifying the size of gutters, which is the space between rows and columns within grid, flex, and multi-column layouts.
estelle marked this conversation as resolved.
Show resolved Hide resolved

The gap property in CSS is a shorthand for `row-gap` and `column-gap`, specifying the size of gutters, which is the space between rows and columns within grid, flex, and multi-column layouts.
The `gap` property is not the only thing that can put space between items. Margins, paddings, `justify-content`, and `align-content` can also increase the size of the gutter, affecting the actual size of the gap.
estelle marked this conversation as resolved.
Show resolved Hide resolved

In Flexbox, the `gap` property is applied to the flex container. It creates a fixed space between adjacent flex items. However, the `gap` property is not the only thing that can put space between items. Margins, paddings, `justify-content`, and `align-content` can also increase the size of the gutter, affecting the actual size of the gap.

To see how the `gap` property differs from `margin` in both axes, try changing the `gap` value in the container `.box` and adding a `margin` value to the `.box > *` rule in the stylesheet below. Click the Reset button to revert to the previous values.
To see how the `gap` property differs from `margin` in both axes, try changing the `gap` value in the container `.box` and adding a `margin` value to the `.box > *` rule in the stylesheet below. Click the "Reset" button to revert to the previous values.

{{EmbedGHLiveSample("css-examples/flexbox/wrapping/gaps.html", '100%', 830)}}

Expand Down