diff --git a/files/en-us/web/css/css_flexible_box_layout/aligning_items_in_a_flex_container/index.md b/files/en-us/web/css/css_flexible_box_layout/aligning_items_in_a_flex_container/index.md index 095493e66bbb9c4..5d4cd38c06ae35e 100644 --- a/files/en-us/web/css/css_flexible_box_layout/aligning_items_in_a_flex_container/index.md +++ b/files/en-us/web/css/css_flexible_box_layout/aligning_items_in_a_flex_container/index.md @@ -6,33 +6,33 @@ page-type: guide {{CSSRef}} -One of the reasons that flexbox quickly caught the interest of web developers is that it brought proper alignment capabilities to the web for the first time. It enabled proper vertical alignment, so we can at last easily center a box. In this guide, we will take a thorough look at how the alignment and justification properties work in Flexbox. +One of the reasons flexbox is so useful is that it enables proper alignment, including providing a quick method of vertically centering elements. In this guide, we will take a thorough look at how the alignment and justification properties work in flexbox. -To center our box we use the `align-items` property to align our item on the cross axis, which in this case is the block axis running vertically. We use `justify-content` to align the item on the main axis, which in this case is the inline axis running horizontally. +Flexbox provides several properties to control alignment and spacing, with `align-items` and `justify-content` being fundamental for centering elements. To center an element, we use the {{cssxref("align-items")}} property to align the item on the {{glossary("cross axis")}}, which in this case is the [block axis](/en-US/docs/Glossary/Flow_relative_values) running vertically. We use {{cssxref("justify-content")}} to align the item on the main axis, which in this case is the inline axis running horizontally. -![A containing element with another box centered inside it.](align1.png) +![The cross axis is the vertical axis and the main axis is the horizontal axis.](align1.png) -You can take a look at the code of this example below. Change the size of the container or nested element and the nested element always remains centered. +Change the size of the container or nested element in the code example below. The nested element always remains centered. {{EmbedGHLiveSample("css-examples/flexbox/alignment/intro.html", '100%', 700)}} -## Properties that control alignment +## Properties for controlling alignment in flexbox The properties we will look at in this guide are as follows. -- {{cssxref("justify-content")}} — controls alignment of all items on the main axis. -- {{cssxref("align-items")}} — controls alignment of all items on the cross axis. -- {{cssxref("align-self")}} — controls alignment of an individual flex item on the cross axis. -- {{cssxref("align-content")}} — described in the spec as for "packing flex lines"; controls space between flex lines on the cross axis. -- {{cssxref("gap")}}, {{cssxref("column-gap")}}, and {{cssxref("row-gap")}} — used to create gaps or gutters between flex items. +- {{cssxref("justify-content")}}: Controls the alignment of all items on the main axis. +- {{cssxref("align-items")}}: Controls the alignment of all items on the cross axis. +- {{cssxref("align-self")}}: Controls the alignment of an individual flex item on the cross axis. +- {{cssxref("align-content")}}: Controls the space between flex lines on the cross axis. +- {{cssxref("gap")}}, {{cssxref("column-gap")}}, and {{cssxref("row-gap")}}: Used to create gaps or gutters between flex items. We will also discover how auto margins can be used for alignment in flexbox. -## The Cross Axis +## Aligning items on the cross axis -The `align-items` and `align-self` properties control alignment of our flex items on the cross axis, down the columns if `flex-direction` is `row` and along the row if `flex-direction` is `column`. +The {{cssxref("align-items")}} property, set on the flex container, and the {{cssxref("align-self")}} property, set on flex items, control the alignment of flex items on the cross axis. The cross axis runs down the columns if {{cssxref("flex-direction")}} is `row` and along the rows if `flex-direction` is `column`. -We are making use of cross-axis alignment in the most simple flex example. If we add `display: flex` to a container, the child items all become flex items arranged in a row. They will all stretch to be as tall as the tallest item, as that item is defining the height of the items on the cross axis. If your flex container has a height set, then the items will stretch to that height, regardless of how much content is in the item. +In this basic flex example, we're using cross-axis alignment. When we add `display: flex` to a container, the child items become flex items arranged in a row. By default, they will all stretch to match the height of the tallest item, as that item defines the height of the items on the cross axis. If the flex container has a height set, the items will stretch to that height, regardless of how much content is in each item. ![Three items, one with additional text causing it to be taller than the others.](align2.png) @@ -42,31 +42,35 @@ The reason the items become the same height is that the initial value of `align- We can use other values to control how the items align: +- `align-items: stretch` - `align-items: flex-start` - `align-items: flex-end` +- `align-items: start` +- `align-items: end` - `align-items: center` -- `align-items: stretch` - `align-items: baseline` +- `align-items: first baseline` +- `align-items: last baseline` -In the live example below, the value of `align-items` is `stretch`. Try the other values and see how all of the items align against each other in the flex container. +In the example below, the value of `align-items` is `stretch`. Try the other values and see how the items align against each other in the flex container. {{EmbedGHLiveSample("css-examples/flexbox/alignment/align-items.html", '100%', 520)}} ### Aligning one item with `align-self` -The `align-items` property sets the `align-self` property on all of the flex items as a group. This means you can explicitly declare the `align-self` property to target a single item. The `align-self` property accepts all of the same values as `align-items` plus a value of `auto`, which will reset the value to that which is defined on the flex container. +The `align-items` property sets the `align-self` property on all of the flex items as a group. This means you can explicitly declare the {{cssxref("align-self")}} property to target a single item. The `align-self` property accepts all of the same values as `align-items`, plus a value of `auto`, which resets the value to that defined on the flex container. -In this next live example, the flex container has `align-items: flex-start`, which means the items are all aligned to the start of the cross axis. I have targeted the first item using a `first-child` selector and set that item to `align-self: stretch`; another item has been selected using its class of `selected` and given `align-self: center`. You can change the value of `align-items` or change the values of `align-self` on the individual items to see how this works. +In this next live example, the flex container has `align-items: flex-start`, which means the items are all aligned to the start of the cross axis. Using the `first-child` selector, the first item is set to `align-self: stretch`. Another item with the `selected` class has `align-self: center` set. Change the value of `align-items` or change the values of `align-self` on the individual items to see how this works. {{EmbedGHLiveSample("css-examples/flexbox/alignment/align-self.html", '100%', 650)}} ### Changing the main axis -So far we have looked at the behavior when our `flex-direction` is `row`, and while working in a language written top to bottom. This means that the main axis runs along the row horizontally, and our cross axis alignment moves the items up and down. +Thus far, we have looked at alignment behavior when the `flex-direction` defaults to `row` while working in a language written top to bottom, with a horizontal main axis and vertical cross axis. ![Three items, the first aligned to flex-start, second to center, third to flex-end. Aligning on the vertical axis.](align4.png) -If we change our `flex-direction` to column, `align-items` and `align-self` will align the items to the left and right. +Keeping the same writing mode, when the `flex-direction` is changed to `column`, the `align-items` and `align-self` properties will align the items to the left and right instead of top and bottom; these properties are still aligning items along the cross axis, but the cross axis is now horizontal! ![Three items, the first aligned to flex-start, second to center, third to flex-end. Aligning on the horizontal axis.](align5.png) @@ -74,23 +78,29 @@ You can try this out in the example below, which has a flex container with `flex {{EmbedGHLiveSample("css-examples/flexbox/alignment/align-self-column.html", '100%', 730)}} -## Aligning content on the cross axis — the align-content property +## Aligning content on the cross axis with the `align-content` property -So far we have been aligning the items, or an individual item inside the area defined by the flex-container. If you have a wrapped multiple-line flex container then you might also want to use the `align-content` property to control the distribution of space between the rows. In the specification this is described as [packing flex lines](https://drafts.csswg.org/css-flexbox/#align-content-property). +So far, we have focused on aligning items or an individual items inside the area defined by a {{glossary("flex_container")}} containing a single line of flex items. When flex items are allowed to wrap across multiple lines, the {{cssxref("align-content")}} property can be used to control the distribution of space between the lines, also known as **packing flex lines**. -For `align-content` to work you need more height in your flex container than is required to display the items. It then works on all the items as a set, and dictates what happens with that free space, and the alignment of the entire set of items within it. +For `align-content` to have an effect, the cross axis dimension (the height in this case) of the flex container must be greater than needed to display the items. It then works on all the items as a set. The `align-content` values dictate what happens with the extra available space and the alignment of the entire set of items within it. The `align-content` property takes the following values: - `align-content: flex-start` - `align-content: flex-end` +- `align-content: start` +- `align-content: fend` - `align-content: center` - `align-content: space-between` - `align-content: space-around` +- `align-content: space-evenly` - `align-content: stretch` -- `align-content: space-evenly` (not defined in the Flexbox specification) +- `align-content: normal` (behaves as `stretch`) +- `align-content: baseline` +- `align-content: first baseline` +- `align-content: last baseline` -In the live example below, the flex container has a height of 400 pixels, which is more than needed to display our items. The value of `align-content` is `space-between`, which means that the available space is shared out _between_ the flex lines, which are placed flush with the start and end of the container on the cross axis. +In the live example below, the flex container has a height of `400 pixels`, which is more than needed to display our items. The value of `align-content` is `space-between`, which means that the available space is shared out _between_ the flex lines, which are placed flush with the start and end of the container on the cross axis. Try out the other values to see how the `align-content` property works. @@ -100,24 +110,28 @@ Once again we can switch our `flex-direction` to `column` in order to see how th {{EmbedGHLiveSample("css-examples/flexbox/alignment/align-content-column.html", '100%', 860)}} -> **Note:** The value `space-evenly` is not defined in the flexbox specification and is a later addition to the Box Alignment specification. Browser support for this value is not as good as that of the values defined in the flexbox spec. - ## Aligning content on the main axis Now that we have seen how alignment works on the cross axis, we can take a look at the main axis. Here we only have one property available to us — `justify-content`. This is because we are only dealing with items as a group on the main axis. With `justify-content` we control what happens with available space, should there be more space than is needed to display the items. -In our initial example with `display: flex` on the container, the items display as a row and all line up at the start of the container. This is due to the initial value of `justify-content` being `flex-start`. Any available space is placed at the end of the items. +In our initial example with `display: flex` on the container, the items display as a row and all line up at the start of the container. This is due to the initial value of `justify-content` being `normal`, which behaves as `start`. Any available space is placed at the end of the items. ![Three items, each 100 pixels wide in a 500 pixel container. The available space is at the end of the items.](align6.png) -The `justify-content` property accepts the same values as `align-content`. +The `baseline` values aren't relevant in this dimension. Otherwise, `justify-content` property accepts the same values as `align-content`. - `justify-content: flex-start` - `justify-content: flex-end` +- `justify-content: start` +- `justify-content: end` +- `justify-content: left` +- `justify-content: right` - `justify-content: center` - `justify-content: space-between` - `justify-content: space-around` -- `justify-content: space-evenly` (not defined in the Flexbox specification) +- `justify-content: space-evenly` +- `justify-content: stretch` (behaves as start) +- `justify-content: normal` (behaves as stretch, which behaves as start) In the example below, the value of `justify-content` is `space-between`. The available space after displaying the items is distributed between the items. The left and right item line up flush with the start and end. @@ -127,9 +141,9 @@ If the main axis is in the block direction because `flex-direction` is set to `c {{EmbedGHLiveSample("css-examples/flexbox/alignment/justify-content-column.html", '100%', 880)}} -### Alignment and Writing Modes +### Alignment and writing modes -Remember that with all of these alignment methods, the values of `flex-start` and `flex-end` are writing mode-aware. If the value of `justify-content` is `flex-start` and the writing mode is left-to-right as in English, the items will line up starting at the left side of the container. +Remember that with all of these alignment methods, the values of `start` and `end` are writing mode-aware. If the value of `justify-content` is `start` and the writing mode is left-to-right, as in English, the items will align starting at the left side of the container. ![Three items lined up on the left](basics5.png) @@ -141,23 +155,23 @@ The live example below has the `direction` property set to `rtl` to force a righ {{EmbedGHLiveSample("css-examples/flexbox/alignment/justify-content-writing-mode.html", '100%', 440)}} -## Alignment and flex-direction +## Alignment and `flex-direction` -The start line will also change if you change the `flex-direction` property — for example using `row-reverse` instead of `row`. +The direction of `start` of the line will also change if you change the `flex-direction` property — for example, using `row-reverse` instead of `row`. -In this next example I have items laid out with `flex-direction: row-reverse` and `justify-content: flex-end`. In a left to right language the items all line up on the left. Try changing `flex-direction: row-reverse` to `flex-direction: row`. You will see that the items now move to the right-hand side. +In this next example, `flex-direction: row-reverse` and `justify-content: flex-end` define the direction and location of the items within the flex container. In a left to right language, the items line up on the left. Try changing `flex-direction: row-reverse` to `flex-direction: row`. You will see that the items now move to the right-hand side, and the visual order of the items is reversed. {{EmbedGHLiveSample("css-examples/flexbox/alignment/justify-content-reverse.html", '100%', 440)}} -While this may all seem a little confusing, the rule to remember is that unless you do something to change it, flex items lay themselves out in the direction that words are laid out in the language of your document along the inline, row axis. `flex-start` will be where the start of a sentence of text would begin. +While this may all seem a little confusing, the rule to remember is that unless you do something to change it, flex items lay themselves out in the direction that words are laid out in the language of your document along the inline, row axis. `start` and `flex-start` will be where the beginning of a sentence of text would start. ![Diagram showing start on the left and end on the right.](align8.png) -You can switch them to display in the block direction for the language of your document by selecting `flex-direction: column`. Then `flex-start` will then be where the top of your first paragraph of text would start. +You can switch them to display in the block direction for the language of your document by selecting `flex-direction: column`. Then, `start` and `flex-start` will be where the top of your first paragraph of text would start. ![Diagram showing start at the top and end at the bottom.](align10.png) -If you change `flex-direction` to one of the reverse values, they will lay themselves out from the end axis and in the reverse order to the way words are written in the language of your document. Then, `flex-start` will change to the end of that axis — so to the location where your lines would wrap if working in rows, or at the end of your last paragraph of text in the block direction. +If you change `flex-direction` to one of the reverse values, they will lay themselves out from the end axis and in the reverse order to the way words are written in the language of your document. Then, `start` and `flex-start` will change to the end of that axis — so to the location where your lines would wrap if working in rows, or at the end of your last paragraph of text in the block direction. ![Diagram showing start on the right and end on the left.](align9.png) @@ -167,24 +181,30 @@ If you change `flex-direction` to one of the reverse values, they will lay thems We don't have a `justify-items` or `justify-self` property available to us on the main axis as our items are treated as a group on that axis. However it is possible to do some individual alignment in order to separate an item or a group of items from others by using auto margins along with flexbox. -A common pattern is a navigation bar where some key items are aligned to the right, with the main group on the left. You might think that this should be a use case for a `justify-self` property, however consider the image below. I have three items on one side and two on the other. If I were able to use `justify-self` on item _d_, it would also change the alignment of item _e_ that follows, which may or may not be my intention. +A common pattern is a navigation bar where some key items are aligned to the right, with the main group on the left. You might think that this should be a use case for a `justify-self` property. However, consider the image below. As an example, take the following image with three items on one side and two on the other. If `justify-self` were to work on flex items and was set on item _d_, it would also change the alignment of item _e_ that follows, which may or may not be what is intended. ![Five items, in two groups. Three on the left and two on the right.](align7.png) -Instead we can target item 4 and separate it from the first three items by giving it a `margin-left` value of `auto`. Auto margins will take up all of the space that they can in their axis — it is how centering a block with margin auto left and right works. Each side tries to take as much space as it can, and so the block is pushed into the middle. +Instead, the _d_ item can be pushed over using CSS margins. -In this live example, I have flex items arranged into a row with the basic flex values, and the class `push` has `margin-left: auto`. You can try removing this, or adding the class to another item to see how it works. +In this live example, item 4 is separated from the first three items by setting {{cssxref("margin-left")}} to `auto`, which consumes all the space it can in its axis. This is how centering a block with {{cssxref("margin")}} auto left and right works. Each side tries to take as much space as it can, and so the block is pushed into the middle. + +In this live example, the flex items are arranged in a row with the basic flex values, and the class `push`, set on the fourth item, applies `margin-left: auto` to that item. Try removing the class on the fourth item or adding the class to a different item to see how it works. {{EmbedGHLiveSample("css-examples/flexbox/alignment/auto-margins.html", '100%', 470)}} ## Creating gaps between items -To create a gap between flex items, use the {{cssxref("gap")}}, {{cssxref("column-gap")}}, and {{cssxref("row-gap")}} properties. The {{cssxref("column-gap")}} property creates gaps between items in a row. The {{cssxref("row-gap")}} property creates gaps between flex lines, when you have {{cssxref("flex-wrap")}} set to `wrap`. The {{cssxref("gap")}} property is a shorthand that sets both together. +To create a gap between flex items, use the {{cssxref("gap")}}, {{cssxref("column-gap")}}, and {{cssxref("row-gap")}} properties. The {{cssxref("column-gap")}} property creates gaps between items in a row. The {{cssxref("row-gap")}} property creates gaps between flex lines when you have {{cssxref("flex-wrap")}} set to `wrap`. + +The {{cssxref("gap")}} property is a shorthand that sets both `row-gap` and `column-gap`. +The gap between flex items or between flex line depends on the direction. If the {{cssxref("flex-direction")}} property creates rows, the first value defines the gap between flex lines, and the second value defines the gap between items within each line. With columns (when `flex-direction` is set to `column` or `column-reverse`), the first value defines the gap between flex items, and the second value defines the gaps between flex lines. {{EmbedGHLiveSample("css-examples/box-alignment/flexbox/gap.html", '100%', 700)}} ## See also -- [Box alignment](/en-US/docs/Web/CSS/CSS_box_alignment) +- [CSS box alignment](/en-US/docs/Web/CSS/CSS_box_alignment) module +- [CSS flexible box layout](/en-US/docs/Web/CSS/CSS_flexible_box_layout) module - [Box alignment in flexbox](/en-US/docs/Web/CSS/CSS_box_alignment/Box_alignment_in_flexbox) - [Box alignment in grid layout](/en-US/docs/Web/CSS/CSS_box_alignment/Box_alignment_in_grid_layout)