CSS Flexbox — a way to create small scale layouts

Rajesh Kumar
14 min readMay 2, 2022
Photo by Sigmund on Unsplash

In this article, you will learn about the basic but very important topic of a layout which is CSS Flexbox and its important properties in an easy way.

It is very important for every developer to have a responsive page and display the content of the web application in a clean and decent manner across the browser. By using CSS we can achieve this.

CSS always has been one of the most important parts of web development. A few years ago, creating web page layouts was a very difficult job. We were using some CSS properties like float , positioning a lot of elements with position and a lot of inline-styling to create a responsive web page layout.

Now the evolution of the web has come to a point that now we have two CSS layout systems: CSS Flexbox and CSS Grid.

Since we have two different layout methods to create a responsive web page layout, different questions will arise like:

  • What’s the difference b/w them?
  • Which one is better?
  • When to use Flexbox or When to use Grid?

And many more such questions.

A very basic difference is that Flex is a 1D layout method whereas Grid is a 2D layout method.

In this article, we will only focus on Flexbox. In the next article, we will talk about Grid and discuss the differences and different use cases of Flexbox and Grid.

What is Flexbox?

CSS Flexbox is a 1-D layout method. This makes it easy to design a flexible small-scale layout structure for an application.

  • It provides more efficient ways to align and distribute space among items in the container even when the size is unknown or dynamic.

The main idea behind the flexbox is based on two axes concept:-

All the concepts of Flexbox revolve around the above picture.

  • The parent layout of a page element is called a container and is referred to as a flex-container.
  • The layout of a container’s children is called an item and is referred to as a flex-item.
  • main-axis — The axis along which the flex items are laid out of a container. In the above picture, the main axis is horizontal which means items will be laid out horizontally. But it is not necessary that the main axis should always be horizontal. it depends on the flex-direction property [will discuss more about this property below].
  • main-start | main-end — The flex items are placed within the container laid out starting from the main-start and going to the main-end in the direction of the main axis. But it is not necessary that the main-start should always be on the left or top and the main-end at the right or bottom for horizontal and vertical direction cases. It depends on the flex-direction property.
  • main size — The main size property of a flex item is either a ‘width’ or a ‘height’ property. It depends on the direction of the main axis. If the main axis is in the horizontal direction then the main size of the flex item will be width and if vertical the height will be the main size.
  • cross-axis — The axis is perpendicular to the main axis. The cross-axis direction depends on the direction of the main axis. If the direction of the main axis will be horizontal/vertical then the direction of the cross axis will be vertical/horizontal.
  • cross-start | cross-end — The flex items are placed within the container laid out starting from the cross-start and going to the cross-end in the direction of the main axis. But it is not necessary that the cross-start should always be on the top or bottom and the cross-end at the bottom or top for vertical and horizontal cases. It depends on the flex-direction property.
  • cross-size— The width or height of a flex item, whichever is in the cross axis direction, is the item’s cross-size. The cross-size property of flex items takes 100% of the width or height of a container with evenly distributed space.

Let us understand the above terminology with an illustrated representation.

In Pic — 1.1: I have defined the value of flex-direction as row . So the main axis direction will be horizontal (i.e the direction of flex-direction) and the cross axis will be vertical as it should be perpendicular to the main axis.

Now we have learned that items are laid out in the direction of the main axis. So the items are laid out from the main start(Left) to the main end (Right) and you have noticed that items are not occupying the whole width (It can take full if we will define some property ) because here the main size is the width as the main-axis direction is horizontal. The cross size is height as the direction of the cross axis is vertical so the height is occupied 100% of the available height of the container.

In Pic — 1.2: I have defined the value of flex-direction as row-reverse . So the main axis direction will be horizontal but in reverse order. [i.e items will be laid out from the main start (Right) to the main end(Left)] and the cross axis direction and cross-size remain the same as Pic 1.1.

Let us now have a look at the picture given below:-

In Pic — 2.1: I have defined the value of flex-direction as column. So the main axis direction will be vertical [i.e along the direction of flex-direction] and the direction of the cross-axis will be horizontal as it should be perpendicular to the main axis.

Items are laid out in the direction of the main axis [i.e from the main start(Top) to the main end (Bottom)]. And you have noticed that items are not occupying the whole heigh [It can take full if we will define some property ]because here the main size is the height as the main-axis direction is vertical. The cross size is the width as the direction of the cross axis is horizontal so the width is occupied 100% of the available width of the container.

In Pic — 2.2: I have defined the value of flex-direction as column-reverse . So the main axis direction will be vertical but in reverse order [i.e items will be laid out from the main start (Bottom) to the main end(Top) ]and the cross-axis direction and cross-size remain the same as Pic 2.1.

Note:

  • CSS Flexbox is a small 1-D scale layout structure method.
  • Patterns that suit flex layout very well are those where we are not so interested in having a pixel-perfect size for each item.

In CSS flexbox we don’t talk about the flow direction as left-right or top-bottom rather we talk start and end. When you are working in English, the start edge of the main axis will be on the left, the end edge on the right.

If you are working in Arabic, then the start edge of my main axis would be on the right and the end edge on the left.

In both cases, the start edge of the cross axis is at the top of the flex container and the end edge at the bottom, as both languages have a horizontal writing mode. That’s why thinking as start and end become more natural and CSS Grid follows the same pattern

Now it’s time to understand the different properties of the flex container and flex-item.

For better understanding, I have used very basic HTML code with CSS so that you can learn the concept and practice it together at the same time.

<!DOCTYPE html><html>
<head>
<style>
.boxContainer {

}
#boxItems { } </style>
</head>
<body> <div class="boxContainer">
<div id="boxItem">Item1</div>
<div id="boxItem">Item2</div>
<div id="boxItem">Item3</div>
</div>
</body>
</html>

I have used two CSS selectors .boxContainer [CSS class selector] and #boxItems [Css id selector] to apply different CSS flexbox properties to container and items respectively.

I’ll refer to the CSS selectorboxContainer for the various properties of the flex container and boxItems for the flex item. As of now, no CSS style properties have been applied.

flex container Properties

  1. display
.boxContainer {
display: flex;
}

This is the main property for creating a CSS flexbox layout. To create a flex container we set the value of the display property to flex or inline-flex .

As soon as we define the value, all the elements wrapped inside the main div will become flex-items. As with all properties in CSS, some initial values are defined, so all contained flex items will behave as follows when creating a flex container.

  • Items display in a row (the flex-direction property's default is row).
  • The items start from the start edge of the main axis.
  • The items do not stretch on the main dimension(i.e not occupying full width by default) but can shrink.
  • The items will stretch to fill the size (height)of the cross axis.
  • The flex-basis property is set to auto and flex-wrap property is set to nowrap.

2. flex-direction

This property of the container allows changing the direction of the main axis [i.e the direction in which flex item is laid out inside the container] to the desired direction [i.e row/row reverse and column/column-reverse].

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

3. flex-wrap

By default (no-wrap), flex items of the container try to fit into a single line (column or row).

But there is a possibility of the overflow of items due to too many items in a row or the total width/height of the item exceeding the width/height of the container

We can handle this overflow situation and wrap it from single line to multi-lines using this flex-wrap property.

.boxContainer {
display: flex;
flex-direction: row | row-reverse | column | column-reverse;
flex-wrap: nowrap | wrap | wrap-reverse ;
}

4. flex-flow

It’s a shorthand for the flex-direction and flex-wrap properties. The default value is row nowrap.

.boxContainer {
display: flex;
flex-flow: row wrap;
}

5. justify-content

It is used to define the alignment of the flex-items of a container along the main-axis [i.e along the direction of the flex-direction property] and to distribute the remaining space inside the container between the flex-items.

However justify-content values are not supported across all browsers. you can find more details about it here.

.boxContainer {
display: flex;
flex-flow: row wrap;
justify-content: flex-start | flex-end | center | space- between | space-around | space-evenly | start | end | left | right ;

}

Here I have assumed the direction of main-axis to be horizontal(i.e row).

  • start: items are packed toward the start of the writing-mode direction.
  • end: items are packed toward the end of the writing-mode direction.
  • left: items are packed toward the left edge of the container, unless that doesn’t make sense with flex-direction, then it behaves like start.
  • right: items are packed toward the right edge of the container unless that doesn’t make sense with the flex-direction, then it behaves like end.

6. align-items

For this property, the direction of alignment is opposite to the justify-content. [i.e flex-items are laid out along the cross axis.]

The default value of the align-items is stretch and because of its default value, the main size of the flex-item container [width/height depends on cross-axis direction] occupies all available width/height.

.boxContainer {
display: flex;
flex-flow: row wrap;
align-items: stretch | flex-start | flex-end | center | baseline ;
}

Here I have assumed the direction of the cross-axis to be vertical (i.e column).

7. align-content

The direction of alignment for this property is the same as for the align-item [i.e. along the cross axis].

One major difference between justify-content and align-items with align-content is that this property aligns the container lines [whole row or column ] which must be multiline [i.e flex-wrap value to be wrap or wrap-reverse ] whereas justify-content and align-items deal with the alignment of the flex-items.

.boxContainer {
display: flex;
flex-flow: row wrap;
align-content: normal | flex-start | flex-end | center | space-between | space-around | space-evenly | stretch ;
}

Note:

  • If the flex-wrap value is no-wrap (the default), the align-content property will not work.
  • the default value of align-content is normal which has no effect on the alignment of the line [i.e all lines will be in their default position].

Here I have assumed the direction of cross-axis to vertical (i.e column).and flex-wrap as wrap .

8. gap

It is used to control the space between the flex items. It only applies spacing between items not on the outer edges.

The gap is a shorthand property of row-gap and column-gap properties.

gap: 10px 20px; // i.e row gap = 10px & column gap =20px
OR
gap: 10px; // i.e row&column gap =10 px

We can also define row and column gaps explicitly.

row-gap: 10px;
column-gap: 20px;

Note: I have not covered some property value like right,end,start,left in some of the properties mentioned above. Because it’s alignment is relative to the writing-mode direction and is work same for all.

Now it’s time to jump into the properties of the item and see how they behave with different properties and values.

flex Item Properties

  1. order

This property is used to change the source order [the order in which we write flex items] of individual flex items and to display them in the required order.

By default, all flex-items have an order value of 0, which means the items will be displayed in the same order we wrote. It accepts a unitless value that serves as a proportion. [But the value should not be a fractional number]

But suppose you want to change the display order of the items without changing the written sequence. In this case, we only need to change the value of the order property.

The lower the order value of the item, it will appear first, and the higher the order value of the item that is displayed last.

#firstItem {
order : 1;
}

So, in this case, the order value of the first item is 1 and the order value of the other items is 0 (default), which means the order in which the items will be displayed is 2,3,1.

You can see more examples below with different order values.

2. flex-grow

This is used to define the ability to grow the flex item along the direction of the main axis.

As we know that by default main size (width/height) of a flex item grows along the cross axis and occupies all of the available space in the container.

Now with this property, the flex item of the container can also occupy the full space along the main axis.

The flex-grow default value is 0 for all items, which means that all items will take up and expand to their content length but will not grow complete along the main axis.

It accepts a unitless value that serves as a proportion [But the value must not be a fractional number and negative].

If all items have flex-grow set to 1, the remaining space in the container will be distributed equally to all children. If one of the children has a value of 2, that child would take up twice as much of the space as either one of the others (or it will try, at least).

#boxItems {
flex-grow: 1;
}

If we want 2nd flex item to have double space than the other two then we can define this property on an individual item as well.

#boxItems {
flex-grow: 1;
}
#secondItem {
flex-grow: 2;
}

3. flex-shrink

It is used to shrink the flex items to fit if the main axis size of all flex items is larger than the flex container.

It accepts a unitless value that serves as a proportion [But the value should not be negative].

Now suppose each item has a default size (width) and its sum is bigger than the container and now we want to shrink the second item 3 times more than the others.

#secondItem {
flex-shrink: 3;
}

4. flex-basis

This property sets the initial main size of a flex item before the remaining space is distributed.

It’s value can be a length unit (i.e 10%, 6px, etc.) or a keyword(i.e auto,content etc).

The auto keyword refers to the “width or height property” of the main size and content keyword means “size is based on the item’s content.

If the value is set to 0, the extra space around content isn’t factored in. If set to auto, the extra space is distributed based on its flex-grow value.

NOTE: If we set value of both that main size value(i.e width/height:40px) and flex-basis:50px(or any other value) then size of item will be 50px because flex-basis priority is higher than main size of item.

5. flex

It is shorthand for flex-grow, flex-shrink and flex-basis .

The second and third parameters (flex-shrink and flex-basis) are optional. The default is 0 1 auto, but if you set it with a single number value, like flex: 7;, that changes the flex-basis to 0%, so it’s like setting flex-grow: 7; flex-shrink: 1; flex-basis: 0%;.

#boxItems {
flex: flex-grow flex-shrink flex-basis ;
}

6. align-self

This property behaves just like align-items of container properties. The only difference is it works on flex items.

#item1 {
align-self:flex-start;
},
#item2 {
align-self:stretch;
},
#item1 {
align-self:center;
},
#item4 {
align-self:flex-end;
}

That’s all about how flex-boxes and their properties work. We can use various properties of the flex-box to create a small-scale layout method. In an upcoming article, we will talk about a new layout method called CSS Grid.😎

I hope all your concepts are clear!!! If you really liked this article then click on the 👏 button below. Also, write your feedback and queries in the comment section.✍

--

--