CSS Flex Fundamentals

Paul Munley
Blue Clover Web Design
9 min readJan 18, 2023

Flex is a CSS setting that is pretty straightforward but can cause some head-scratching slip-ups from time to time. Here are some of the main fundamentals of the Display: Flex CSS Property that may hopefully help you out.

What does it do?

Simply put, flex allows you to line up a list of elements nested inside of it. You can choose to line up these nested elements horizontally or vertically. One of the things that always helped me when I first started with flex is that it helps line elements up.

Settings for Flex Containers

There are settings that you can add on both the flex container and its children. Here are some of the flex container settings and how they work.

Display: Flex

This setting essentially sets up flex on the parent container.

Image of a flex container with the child elements lined up inside of the container in a row. This CSS setting is display: flex
display: flex

Justify Content

This setting controls the alignment of ALL the children elements on the horizontal axis (left & right).

Start (default setting)

This will line up all of the children elements at the beginning (start) of the flex container.

Image of a flex container with all of the child elements horizontally starting at the left side of the container due to the flex container setting, justify-content: start
justify-content: start

Center

This will line up all of the children elements at the center of the flex container.

Image of a flex container with all of the child elements horizontally in the center due to the flex container setting, justify-content: center
justify-content: center

End

This will line up all of the children elements at the end of the flex container.

Image of a flex container with all of the child elements horizontally at the end of the container due to the flex container setting, justify-content: end
justify-content: end

Space-Between

This will space out all of the children elements but will leave no spacing on the end elements. In the example below, the 1st and 4th boxes are flush on the end of the flex container’s padding instead of having spacing on their ends.

Image of a flex container with all of the child elements spaced out with the space between them being of the same amount due to the justify-content: space-between. The outer-most elements do not have any spacing on their further-most ends.
justify-content: space-between

Space-Evenly

This will space out all of the elements evenly on both sides of each element. Both sides are important to note here as you will see there is a difference in the next justify setting we talk about. In the image below, you can see that the spacing between each element on each side is even 160px throughout.

Image of a flex container with all of the child elements spaced out with the space between them being of the same amount due to the justify-content: space-evenly. The difference from this compared to justify-content: space-between is that spacing applies to the outer-most elements, further-most ends and the boundaries of the flex container.
justify-content: space-evenly

Space-Around

The easiest way that I’ve always looked at it is that there is a fixed spacing around each element. The main difference between space-around & space-evenly is that space-around will not have an even amount of space on the end elements' furthest ends. In the image below you will see that the 1st and 4th elements' furthest ends have a lower spacing from the end of the container bounds than the spacing between each element. So in this type of justifying, the end elements will not be spaced the same as the inside elements. For me, it is always best to just know that it will add space between elements but will not space all elements perfectly even as space-evenly would.

Image of a flex container with all of the child elements spaced out with the space on each edge of them being the same fixed amount. This causes the outer-most elements’ further-most edges to have less spacing between them and the ends of the flex containers boundaries compared to the elements spaced out in the middle.
justify-content: space-around

Align Items

This setting controls the alignment of ALL the children elements on the vertical axis (up & down).

Start (default setting)

This will line up all of the children elements at the beginning (start) of the cross-axis in the flex container. In the example below in which our flex items are lined up in a row, the items will line up at the start of the vertical axis.

Image of a flex container with all of the child elements vertically starting at the beginning (upper side) of the container due to the flex container setting, align-items: start
align-items: start

Center

This will line up all of the children elements at the center of the cross-axis in the flex container. In the example below in which our flex items are lined up in a row, the items will line up at the center of the vertical axis.

Image of a flex container with all of the child elements center-most point vertically lining up at the center of the container due to the flex container setting, align-items: center
align-items: center

End

This will line up all of the children elements at the end of the cross-axis in the flex container. In the example below in which our flex items are lined up in a row, the items will line up at the end of the vertical axis.

Image of a flex container with all of the child elements vertically lining up at the end (bottom) of the container due to the flex container setting, align-items: end
align-items: end

Baseline

This will line up all of the children elements based on the baseline of any text contained within them. Please see the example below for an illustration of this.

Image of a flex container with all of the child elements vertically lining up based on the baseline (bottom point) of the text inside of the containers. This is due to the flex container setting, align-items: baseline
align-items: baseline

Flex Direction

This setting controls the direction (and general order) that the children will be lined up. The options for this consist of row, row-reverse, column, and column-reverse.

Row (default setting)

This lines the child elements in a row.

Image of a flex container with all of the child elements lining up in a row (left to right) due to the flex container setting flex-direction: row
flex-direction: row

Column

This lines the child elements vertically.

Image of a flex container with all of the child elements lining up in a column (top to bottom) due to the flex container setting flex-direction: column
flex-direction: column

Row-Reverse

This is the same as row in the sense that all of the items are lined up horizontally. The difference is that the flex children are organized in reverse order.

Image of a flex container with all of the child elements lining up in a row (left to right) but are visually ordered in the opposite of the original order due to the flex container setting flex-direction: row-reverse
flex-direction: row-reverse

Column-Reverse

This is the same as column in the sense that all of the items are lined up vertically. The difference is that the flex children are organized in reverse order.

Image of a flex container with all of the child elements lining up in a column (top to bottom) but are visually ordered in the opposite of the original order due to the flex container setting flex-direction: column-reverse
flex-direction: column-reverse

Flex Wrap

This setting controls whether or not the flex children will wrap to the next line when there isn’t enough room for them.

No-Wrap (default setting)

This will prevent the flex children from wrapping when the flex container shrinks in size. Unless you have the children widths or flex-basis set to a fixed width, the children elements will continue to shrink as the flex container gets smaller.

Image of a flex container with all of the child elements “squishing” in and getting smaller as the width of the flex container gets smaller
flex-wrap: no-wrap

Wrap

This will cause the children to “wrap” over to the next line as the container shrinks in size.

Image of a flex container with all of the child elements wrapping as the container gets smaller and no more room is available due to the flex container setting flex-wrap: wrap
flex-wrap: wrap

Wrap-Reverse

This will do the same as a wrap but will wrap them above the current list instead of the conventional below direction. See the example below.

Image of the elements wrapping upwards on top of the list as opposed to standard downwards or below the list. This is due to the flex container setting flex-wrap: wrap-reverse
flex-wrap: wrap-reverse

Column-Gap & Row-Gap

This setting controls the spacing or “gap” between each flex item. This can be a good substitute to specify an exact unit (px, em, rem) that you would like each child element to space out by as opposed to adding margins to each child element.

Column-Gap

This setting controls the spacing between each “column”. This type of gap takes place when flex-direction is set to row. Let’s say flex-wrap was set to wrap and the flex child elements ran out of room so they started to wrap and create a new row. Even in this situation, the next rows will also have spacing between each other for the value that you set the column-gap to. Also, in the image below, notice that this column-gap spacing only applies to the spacing between each element. This spacing does NOT apply the distance between the outermost elements and the bounds of the flex container.

An image of the horizontal spacing between each element having 64px of space between them due to the flex container setting column-gap: 64px
column-gap: 64px

Row-Gap

This setting controls the spacing between each “row”. This type of gap would be important in a couple of situations:

  1. If you have the flex-direction set to column. This would then cause the children elements to be stacked, therefore now lining them up in rows. That spacing between these rows would be considered the “row gap” which you can then specify an exact unit that you would like these rows to be spaced.
  2. When you have the flex-direction set to row but set the flex-wrap to wrap. Once the width of the flex-container starts to shrink to the point that the children flex elements are no longer able to fit, they will then wrap to the next row. The row-gap set will also apply to this, as these are now rows that have been created.
An image of the vertical spacing between each row element having 64px of space between them due to the flex container setting row-gap: 64px
row-gap: 64px

Settings for Flex Children

So we just got done covering the flex container settings, here are some of the flex children settings and how they work.

Order

This allows you to control a flex child elements order appearance in the flex container. This is specified by a number value. The lower the value, the earlier it will be in the order. The higher the value, the later it will be in the order. If two or more children elements have the same order value, their order between each other will then be determined by how they are originally ordered in the DOM or HTML Markup.

Image of flex children lined up in a row with order values of 1, 2, 3, & 4. The child element with order: 1 is ordered in the first position at the way left of the row and the child element with order: 2 is ordered in the last position at the way right of the row
Row Example 1
Image of flex children lined up in a row with order values of -4, 1, 3, & 21. The child element with order: -4 is ordered in the first position at the way left of the row and the child element with order: 21 is ordered in the last position at the way right of the row
Row Example 2
Image of flex children lined up in a column with order values of 1, 2, 2, & 61. The child element with order: 1 is ordered in the first position at the way top of the column and the child element with order: 61 is ordered in the last position at the way bottom of the column
Column Example

Flex Grow

Flex grow controls the flex child element's ability to grow when there is any extra space available. You can specify how much that specific child element will grow with a numerical value. This will then compare to the rest of the child elements, flex-grow value. The higher the value, the more that specific element will be willing to grow. The lower the value, the less it will be willing to grow. If there is no flex-grow value specified, the default value for it will be 0.

Image of the flex children taking up the same amount of space because they have the same flex-grow values
All of the flex children take up the same amount of space because they have the same flex-grow values
Image of the center flex child taking up more space than the other 2 flex children because it has a higher flex-grow value
The center flex child takes up more space than the other 2 flex children because it has a higher flex-grow value

Flex Shrink

Flex shrink controls a specific flex child elements ability to shrink compared to the other flex children. This is basically the exact opposite of flex-grow except for the default value for flex-shrink is 1, whereas the default value for flex-grow is 0. In theory, the higher the flex-shrink value, the more it will shrink. Reference the examples below.

Image of none of the flex children shrinking more than the others because they all have the same flex-shrink values of 1
None of the flex children shrink more than the others because they all have the same flex-shrink values of 1
Image where the middle flex child shrinks more than the side flex children because it has a higher flex-shrink value
The middle flex child shrinks more than the side flex children because it has a higher flex-shrink value

Flex Basis

Flex basis controls the flex child’s default width before any extra space is taken into account. I kind of think of it as a width for flex children. The width and height values do take precedence over flex-basis though. So if your flex-direction is set to “row” for example, and you have a width set, that width will override any flex-basis value that you set for that element.

Align Self

Align self allows you to align a specific flex-child element. This allows you to align a child element differently from the rest of the elements.

Image of an example where the orange container is set to align-items: center. The middle flex child element though is listed as align-self: start. This then makes it align at the top of the container, differently than the other 2 elements.
In this example, the orange container is set to align-items: center. The middle flex child element though is listed as align-self: start. This then makes it align differently than the other 2 elements

Hopefully, you liked this brief summary of CSS Flex and that it was helpful to you 👍. If you are looking for a couple of further CSS Flex resources, I’ve compiled a few of them on our website.

--

--

Paul Munley
Blue Clover Web Design

Nurse 👨🏻‍⚕️ to Real Estate Agent 🏡 to Service Business Owner 🔨 to Web Designer 👾… I’m pretty sure I’m done changing careers 🙈