Deep Tech Point
first stop in your tech adventure

Flexbox tutorial: a quick guide to flex container and flex items properties and values

July 28, 2021 | CSS

In short, flexbox layout is based on a direction – either horizontal or vertical (flex-flow direction) and its purpose is to align flex items in a flex container. Compared to block which is vertically-based and inline which is horizontally-based, and they work pretty well for pages, it is also important to bring out they have a flexibility problem and cannot hold up complex applications, especially when it comes to responsive design that deals with lots of orientation changing, stretching and shrinking. So, you think flexbox solves all that? Not really. Flexbox does not deal well with the complexity of big-scale layouts. Grid does. At the end of the day, grid is two-dimensional and the flexbox is one-dimensional. We talked about that and other differences in an article about Grid vs. flexbox in CSS: how are they different and when should we use them?. However, flexbox is still an appropriate approach for small-scale layouts and parts of an application and its goal is to enable a more flexible layout, in terms of aligning and distributing space among flex items in a flex container.

.my-flex-container {
  display: flex; 
}

display: flex; defines that .my-flex-container will be a flex container. It can have one of the two values, either block or inline, and is it allows a flex context for all its direct children.

Properties for the flex container (the parent)

What is a flex-direction?

So, we’ve already met the first two most important components of a flexbox module – flex container (parent) and flex item (child) in the introduction. flex-direction is another important flexbox concept – it is the most basic property behind the one-dimensional approach of the flexbox module.

.my-flex-container {
  flex-direction: row | row-reverse | column | column-reverse;
}

With the flex-direction property we can define the flex items to be positioned:

What flex-wrap has to do with a flex-direction?

Everything indirectly. By default, flex items will all try to align in one line (nowrap value), horizontally or vertically, depends how you defined the flex-direction property in the first place. However, you can allow the flex items to wrap with the flex-wrap property.

.my-flex-container {
  flex-wrap: nowrap | wrap | wrap-reverse;
}

The wrap value will wrap flex items in multiple lines, from top to bottom, while the wrap-reverse will wrap flex items in multiple lines from bottom to top.

flex-flow – a shorthand property for flex-direction and flex-wrap properties

flex-flow: flex-direction flex-wrap|initial|inherit;

The default value for flex-flow is row nowrap, but the showcase below reveals the flexible items will display in reverse order, and they will wrap if needed.

div {
  display: flex;
  flex-flow: row-reverse wrap;
}

justify-content defines how items should align horizontally

So, justify-content has everything to do with x-axis alignment: it defines how the browser distributes space between and around content items along the main-axis of a flex container. The purpose of this property is to help spread extra free space that is left and to control the alignment of flex items when they overflow the line. Below you will find a list of values that are possible with the justify-content property. At this point, we will only say that the flex-start is the default value and it defines the flex items to be packed toward the start of the flex-direction.

.my-flex-container {
  justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right ... + safe | unsafe;
}

align-items defines how flex items should be aligned vertically

Exactly, you got it right – the align-items is the justify-content version for the cross-axis (y-axis). The default value is stretch which fills the container, but still respecting the minimum and maximum width of the column. Here’s a list of values that are possible with the align-items property.

.my-flex-container {
  align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end + ... safe | unsafe;
}

align-content aligns a flex container’s lines within it when there is extra space in the cross-axis

This sub-property of the flexbox module works very similar to how justify-content aligns individual items within the main-axis, but only if flex-flow is set to either wrap or wrap-reverse. Obviously, if your flexbox has only one line, this property won’t have any effect.

The values of the align-content subproperty are:

.my-flex-container {
  align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end | baseline | first baseline | last baseline + ... safe | unsafe;
}

Properties for the flex items (the children)

order property to control the order in which flex items be shown in the flex container

With order property every flex item is assigned a number (an integer) that represents their group, and then items are positioned in the visual order according to every integer. The lowest values come first, and negative numbers are not allowed. If two flex items have the same value, then the flex item that has the lowest source order comes first. For example, we have 4 flex items and we assign them the following order values:

Source item 1: order: 2
Source item 2: order: 3
Source item 3: order: 1
Source item 5: order: 1

These items would be displayed on the page in the order that gives an advantage to the lowest source because two items have the same visual order, like so:

Source item 3: order: 1
Source item 5: order: 1
Source item 1: order: 2
Source item 2: order: 3

flex-grow property specifies the ability for a flex item to grow, either horizontally or vertically

flex-grow property defines the flex grow factor – in other words how much of the remaining space (remaining space is the size of the flex container minus the size of all flex items’ sizes together). That space could be either width or height of the item depends on the assigned flex-direction value. By default the value is 0 (negative numbers are not allowed). If all flex items have flex-growth specified to 1 all children in the flex container will recieve the same amount of the remaining space. If one child has a value of 3 and all other have the value 1, the remaining space for the child with a value 3 will try to take up three times as much space as the children that have a value 1.
For example, if all items have flex-grow set to 1, every child will set to an equal size inside the container. If you were to give one of the children a value of 2, that child would take up twice as much space as the others.

flex-shrink property defines the ability for a flex item to shrink

This property sets the flex shrink factor of a flex item. If flex container is smaller than the size of all flex items, the flex items will shrink proportionally (the will follow the flex-shrink specification). The default value is 1, and negative values aren’t allowed. We use flex-shrink alongside other flex properties – flex-grow and flex-basis, and these are also merged in the flex property that we’ll take a look at the end of this article.

flex-basis specifies the default size of an element before the remaining space is distributed

The value of flex-basis property can be specified with length units (%, px, etc.) or a keyword (for example auto, initial, none…). If we do not define the flex-basis, the property is actually item’s width property, and if no width is specified, then the property falls back to the computed width of the item’s contents. If it’s set to 0, the extra space around the content won’t be factored in, but if it’s set to auto, the extra space will be distributed based on its flex-grow value. It is also good to know that flex-basis is bound by min-width and max-width. If you want to learn more about flex-basis vs. width and what are the differences and similarities and when to use each, you should read this article.

flex stands for a shorthand CSS property that bundles up flex-grow, flex-shrink and flex-basis property

This property defines how a flex item will grow or shrink to fit the space available in its flex container. As with other sub-properties specified in this shorthand, if the element is not a flexible item, the flex property has no effect.

.my-flex-item {
  flex: [flex-grow] [flex-shrink] [flex-basis]; */ default values are 0 1 auto */
}

The align-self property is closely connected to the flex item’s align-items value

Why is that? Well, if we define the align-self property, we overwrite the align-items value. In flexbox, the align-self property aligns the item on the cross axis (y axis). For example, if we define one child with a align-self value, we position it along the bottom of a flex parent instead of the top where all other children are positioned. Possible values for the align-self property are the same as those defined for the align-items:

.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}