The Ultimate Guide to CSS Flexbox Properties

The Ultimate Guide to CSS Flexbox Properties

Part 2: Flexbox Properties

💡
Please enable light mode on Hashnode for a better experience with this article

Introduction

In the previous article, we covered the basic terminologies of Flexbox. We shall use those terms to understand flexbox properties.

This is part 2 of the CSS Flexbox 3-part series, it is the ultimate guide to Flexbox. It covers in-depth explanations of each property. By the end of this article, you should know all about:

  • Flexbox alignment properties (align-items, align-content, and more)

  • Orientation properties ( order)

  • Flex container-specific properties

  • Flex items' specific properties

Flexbox Properties

Flexbox is made up of 12 properties including 2 shorthand properties, as well as the display: flex | Inline-flex; These properties are classified into two:

Properties Applied to Flex Container

Display

.container {
display:flex | inline-flex;
}

This property defines an element as a flex container either at block level (display: flex;) or at Inline level (display:inline-flex) when placed in flow layout. This means that the direct children will become flex items and can be subjected to all the perks Flexbox has to offer.

4 rows of block in a container with black border

Above is a container with four direct children. They are block level elements, and as observed each element begins on a new line. When display is set to flex :

.container{
display:flex;
}

4 flex items arranged from right to left in a flex container

As you can see the flex items are now arranged in rows.

💡
Note that when the display is set to flex or Inline-flex, the flex item is affected by all the other flexbox properties' default values.

Flex-direction

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

default value: row

This property specifies how flex items are laid out, it also determines the main axis. Note that writing mode also affects how flex direction is used and where the main axis lies.

Another important fact to keep in mind is that the reverse properties are purely for visual ordering i.e. screen layout and navigation rely on the source code layout.

If a flex container is set to row reverse a screen reader would still read the flex content in the order it's arranged on the source code.

  • row

    4 flex items arranged in row inside a flex container

As stated earlier this is the default value, items are arranged from left to right. The main axis runs from left to right while the cross axis runs from top to bottom.

  • column

    4 flex items arranged from top to bottom in a flex container

Flex items are stacked from top to bottom and they try to take up all available space. The main axis runs from top to bottom as well, while the cross axis - being perpendicular to the main axis, will run from right to left.

  • row-reverse

    4 flex items arranged from right to left inside a container

As observed this is the opposite of row, the items are laid out from right to left.

The main axis runs from right to left, while the cross goes from top to bottom.

  • column-reverse

    4 flex items arranged from bottom to top in a container

Opposite to flex-direction: column; the items are stacked from bottom to top. The main axis runs from bottom to top while the cross axis, right to left.

Flex-wrap

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

default value:nowrap

Ordinarily, flex items want to remain on one line no matter how many they are. If they can shrink, they try to fit into one line in the container, if they can't they overflow but remain on one line still. In most cases, this doesn't look good.

Flex wrap is responsible for making items wrap onto another line if they can't fit in one. It also determines the cross-axis direction.

  • nowrap

    2 of 7 items overflowing a container

This is the default value and flex items overflow the container while staying on one line.

  • wrap

    7 flex items wrapped into 2 lines in a flex

flex items adjust to fit into the container by moving to the next line.

  • wrap-reverse

    7 flex items wrapped into 2 lines from bottom to top in a container

This is similar but opposite to wrap, while wrap stacks from top to bottom, wrap-reverse stacks from bottom to top.

Flex-flow

.container{
display: flex;
flex-flow: (flex-direction) (flex-wrap);
}

default: row nowrap;

It is the shorthand for flex-direction and flex-wrap in that order. It defines the main axis and cross axis of the container. It has 12 possible combinations and out of them, 8 combinations mirror one another. Here they are:

  • [row wrap] and [row-reverse wrap]
 .container{
display: flex;
flex-flow: row wrap;
}

flex items in row wrap format

 .container{
display: flex;
flex-flow:row-reverse wrap;
}

flex items in row-reverse wrap

  • [row-reverse wrap-reverse] and [row wrap-reverse]
 .container{
display: flex;
flex-flow:row-reverse wrap-reverse;
}

flex items in row-reverse wrap-reverse

 .container{
display: flex;
flex-flow:row wrap-reverse;
}

flex items in row wrap-reverse

  • [column wrap] and [column wrap-reverse]
 .container{
display: flex;
flex-flow:column wrap;
}

flex items in column wrap

 .container{
display: flex;
flex-flow:column wrap-reverse;
}

flex items in column wrap-reverse

  • [column-reverse wrap] and [column-reverse wrap-reverse]
 .container{
display: flex;
flex-flow:column-reverse wrap;
}


Flex items in column-reverse wrap

 .container{
display: flex;
flex-flow:column-reverse wrap-reverse;
}

flex items in Column-reverse wrap-reverse

Justify-content

.container{
display:flex;
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
}

default value: flex-start

It aligns flex items along the main axis set and distributes extra space about each item.

It has 6 values, 3 for positioning and 3 for space distribution.

Positioning values:

  • flex-start

    flex items aligned at the start of main axis

.container{
display:flex;
justify-content: flex-start;
}

Items are stacked at the main start of the flex container's main axis.

  • flex-end

    flex items aligned at the end of main axis

.container{
display:flex;
justify-content: flex-end;
}

Items are stacked at the main end of the flex container's main axis.

  • center

    flex items aligned at the center of main axis

.container{
display:flex;
justify-content: center;
}

Items are stacked at the center of the flex container's main axis.

Space distribution values:

  • space-between

    justify content, space between illustration

.container{
display:flex;
justify-content: space-between;
}

Items are aligned with equal spacing between them, with the first item stacked at the main start and the last item stacked at the main end.

  • space-around

    justify content, space around illustration

.container{
display:flex;
justify-content: space-between;
}

Items are aligned with equal spacing around them, i.e. each item has half spacing on both sides of it. From the main start, there's half space to the first item and from the main end, there's half space to the last item.

Breaking it down, item 1 has half space on the LHS and half space on the RHS. item 2 has half space on the LHS and half space on the RHS, making the space between items 1 and 2 equal to one. The same goes for items 3 to 4.

  • space-evenly

    justify content, space evenly illustration

.container{
display:flex;
justify-content: space-evenly;
}

Items are aligned with equal spacing between them, including between the main start and the first item and, between the main end and the last item.

Therefore, the space between the main start and the first item is equal to the space between the first and second item; second and third item; and so on till the last item and main end.

💡
Note: Space-evenly is not listed as a flexbox property value on W3C candidate recommendation 2018 but is still supported

Below is the browser compatibility chart for space-evenly from caniuse.com

Data on support for the justify-content-space-evenly feature across the major browsers from caniuse.com

Align-items

.container{
display:flex;
align-items: flex-start | flex-end | center | baseline | stretch;
}

default value: stretch

This aligns flex items on the cross axis set.

  • stretch
.container{
display:flex;
align-items: stretch;
}

align items, stretch illustration

Items stretch throughout the height of the container on the cross axis.

  • flex-start
.container{
display:flex;
align-items:flex-start;
}

align items, flex start illustration

Items align at the cross start on the cross axis.

  • flex-end
.container{
display:flex;
align-items: flex-end;
}

align items, flex end illustration

Items align at the cross end on the cross axis.

  • center
.container{
display:flex;
align-items:center;
}

align items, center illustration

Items align at the center of the cross axis.

  • baseline

The baseline is the invisible line upon which letters rest. from fonts.google.com

From the above, the baseline for typography is explained. The blue and red line under the text is the baseline.

.container{
display:flex;
align-items:baseline;
}

align items, baseline illustration

Items align relative to baseline. I've given the item contents different font sizes for clear observation. They all line up to the baseline regardless of size.

align items, baseline illustration

From the above, when the content is longer, you might wonder how items align to the baseline. The items align relative to the first line of the text's baseline. Therefore this is a better definition.

Align-content

.container{
display:flex;
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}

default value:stretch

This property is like a hybrid of align-items and justify-content. It aligns multi-line items (from flex-wrap: wrap | wrap-reverse;) on the cross axis. It also distributes extra space on the cross axis to the lines.

  • flex-start
.container{
display:flex;
align-content:flex-start;
}

align content, flex start illustration

Multi-line items align at the cross start of the cross axis.

  • flex-end
.container{
display:flex;
align-content:flex-end;
}

align content, flex end illustration

Multi-line items align at the cross end of the cross axis

  • center
.container{
display:flex;
align-content: center;
}

align content, center illustration

Multi-line items align at the center of the cross axis.

  • space-between
.container{
display:flex;
align-content:space-between;
}

align content, space between illustration

It distributes space between multi-lines. Check justify-content for the method of distribution.

  • space-around
.container{
display:flex;
align-content: space-around;
}

align content, space around illustration

It distributes space around multi-lines. Check justify-content for method of distribution.

  • stretch
.container{
display:flex;
align-content: stretch;
}

align content, stretch illustration

Multi-line stretch throughout the container.

Properties Applied to Flex Items

Align-self

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

default value: auto

This property, when applied to an individual, overrides the align-items value set for the container. This affects only the selected item. It shares the same values with align-items plus one, auto, this is the default value. Items will follow the value pre-assigned by align-items.

Note that like the align-items, align-self lays out item in the cross axis. Below is an example, my flex container is set to align-items:flex-start;:

flex-end

.container{
display:flex;
align-items:flex-start;
}
.item-2{
align-self:flex-end;
}

align self, flex end illustration

The item selected is stacked to the cross end on the cross axis.

center

.container{
display:flex;
align-items:flex-start;
}
.item-2{
align-self:center;
}

align self center illustration

The selected item is aligned at the center of the cross axis.

see align-items for other values

Order

.container{
display:flex;
}
.item-n{
order:<integer>;
}

default value:0

An integer (pronounced IN-tuh-jer) is a whole number (not a fractional number) that can be positive, negative, or zero.

from techtarget.com

Normally items follow the source code layout for items, although this can be overruled with the order property. The value is an integer, and as stated above it could be zero, positive or negative.

How it works:

All items have a default order of 0, this means in ranking they are at the same tier, therefore, they automatically follow the HTML layout. When an item order has a value higher than 0, in ranking it will come after other items, like so:

.container{
display:flex;
}
.item-2{
order:1;
}
.item-3{
order:2;
}

order illustration

Items 1 and 4 don't have a defined order so they revert to default 0 and automatically follow the source code layout. Item 2 has an order value of 1 therefore, it'll come after items with lower order value. Item 3 has an order value of 2 therefore, it'll come after items with lower order value.

.container{
display:flex;
}
.item-2{
order:1;
}
.item-3{
order:2;
}
.item-4{
  order:-1;
}

order illustration

Now item 4 comes first, that because the order is set to -1 which is less than 0. Items now stack according to ranking, from lowest to highest.

💡
Note that, like reverse values, order only affects visual layout and non-visual media will follow the source code layout.

flex-grow

💡
Note the shorthand property - flex should be used instead of i
.container{
display:flex;
}
.item{
/*negative numbers are invalid*/
flex-grow:<number>;
}

default value:0

The flex-grow property is used to control flex item growth when extra space is distributed about the items. It also controls the rate at which the item should grow. The default value is zero meaning no item will grow even if the viewport size increases.

order illustration

order illustration

.container{
display:flex;
}
.item-1{
flex-grow:1;

flex grow illustration

flex grow illustration

As observed the extra space would be attached to item 1. What happens when all items are set to flex-grow:1;?:

flex grow illustration

flex grow illustration

If you guessed that the extra space would be distributed among the items equally? then you're right👍.

I'll demonstrate how flex-grow controls growth:

If screen size is adjusted you'll notice item 1 grows faster than item 3, this is because item 1 has a greater flex-grow value compared to item 3. The extra space is distributed in such a way that item 1 grows two times as fast as item 3.

Flex-shrink and Flex-basis

note the shorthand property - flex should be used instead of it

flex-shrink

default value:1

.container{
display:flex;
}
.item{
/*negative numbers are invalid*/
flex-shrink:<number>;
}

flex-basis

default value: auto

.container{
display:flex;
}
.item{
flex-basis:content | <width>;
}

Flex-shrink controls the shrink factor of flex items, it is observable when paired with the flex-basis property.

Flex-basis determines the width of flex items before any extra space is distributed about them. It can take units of %, pixel, rem, em etc. but units like vw cannot be used. I would use 3 cases to illustrate how both affect each other:

  • Case 1(flex-shrink:0;) %[codepen.io/lanieee/pen/XWEQaaL]

  • The flex item is set to a specified width

  • The item is set to flex-shrink:1; (item will not shrink)

  • If the item width can't fit into the container when the viewport is smaller it'll overflow

  • Case 2(flex-shrink:1;)

  • The flex item is set to a specified width

  • The item is set to flex-shrink:1; (item will shrink)

  • when the viewport is smaller and the item width will not fit into the container, the item will shrink

  • when the viewport is larger, the item will retain the flex-basis value

  • Case 3: comparing flex-shrink values

The item with a larger flex-basis value will shrink faster than the other item.

Flex

.container{
display:flex;
}
.item{
flex: flex-grow | flex-shrink | flex-basis;
}

default value:0 1 auto

Flex is a shorthand property for flex-grow, flex-shrink, and flex-basis in that order. It's best to use the flex property as opposed to the individual properties. It is also responsible for the flexibility attributed to Flexbox.

You can set the values to suit your goal or you can use the global values available:

  • flex: initial; which is the same as flex: 0 1 auto; (the default value) %[codepen.io/lanieee/pen/XWEQEwx]

  • flex: auto; which is the same as flex: 1 1 auto; (for complete flexibility)

To learn more about these values check the 2018 W3C candidate recommendation on CSS Flexbox.

Browser Compatibility

Data on support for the flexbox feature across the major browsers from caniuse.com

For more information check caniuse.com

Conclusion

We've covered all there is to flexbox properties, which will make positioning items and space distribution easier. From display: flex; to flex: auto;, you've learned how to align items on the main and cross axis, you've also learned how to make flexible items and loads more.

Be consistent and you'd soon be well on your way to becoming a Flexbox pro. Want to practice what you've learned in a fun environment check flexbox froggy.

I hope you've had as much fun reading and learning, as I did putting this tutorial together. In the next and final part of this series, we'll practice using the properties.

if you find this article useful do well to share it😌. Suggestions and feedbacks are welcome, share them in the comment section