Flexbox Properties

Flexbox is a layout system very much like grid system (going to study next).
It is one directional at a time, either horizontal or vertical but not both together. Layout system means how will you lay various html elements on a webpage to make it look beautiful and look like your design.
In flexbox system, we have a flex parent (or container) and flex childs. By applying few properties on flex parent, we control how the child will lay on html page.

Once we apply display: flex on a parent element, then all its child becomes flex child and then we can control its child through some flex properties, defined below

And these properties are applied on its parent itself.
The most common properties always used are: flex-direction, justify-content and align-items property.

By default when we apply display: flex on a parent, a default flex-direction: row is also applied by browser, meaning that all the flex child should be placed horizontally or in x-axis.
Flex direction :
flex-direction property is responsible for placing the flex childs either horizontally (or horizontal reverse) or vertically (or vertically reverse). Its possible values are : row (horizontally), column (vetical), row-reverse (horizontal reverse), column-reverse (vertical reverse).
In the below image, row is the default value so elements will layout from left to right. row-reverse is exactly opposite of row, meaning elements will layout from right to left. Same goes for column and column-reverse but in vertical direction. column will layout elements from top to bottom while column-reverse will layout elements from bottom to top.
Flex direction
Justify content :

justify-content property is responsible for laying the flex child in different ways on main-axis. If flex-direction: row, then main-axis is horizontal axis. If flex-direction: column, then main-axis is vertical axis.
Its possible values are : space-between, space-around, space-evenly, center, flex-start and flex-end (placed in order of mostly used to least used).

In the below image, flex-start is the default value so elements will layout on main axis side by side on left side.
space-between is the most used value meaning all the child elements will have equal space between them and first & last element will go to each extreme corner of its parent and remaining child will sit at equal space from each corner.
space-around is the second most used value meaning all the child elements will have equal space in front and back of child element. In the below image, each arrow represents equal space in the front and back of child element.
space-evenly is used sometimes and it means all the child elements will have equal space around child element. In the below image, each arrow represents equal space around child element.
center is also most used value and it means all the child elements will move to center of its parent element.
flex-end is rarely used value and it means all the child elements will move to right side of its parent element.

justify content
Align items :

align-items property is responsible for laying the flex child in different ways on cross-axis. If flex-direction: row, then main-axis is horizontal axis and cross-axis is vertical axis. If flex-direction: column, then main-axis is vertical axis and cross-axis is horizontal axis.
Its possible values are : center, flex-start, flex-end, stretch and baseline (placed in order of mostly used to least used).
In the below image, normal is the default value so elements will layout as it is.
center is the most used value meaning all the child elements will sit at the center of cross axis.
stretch is also the most used value meaning all the child elements will stretch to a value equal to the whole height of its parent. flex-start is sometimes used meaning all the child elements will sit at the top edge of its parent (considering a box has right, left, top and bottom). flex-end is sometimes used meaning all the child elements will sit at the bottom edge of its parent (considering a box has right, left, top and bottom).
Please note that the above flex-start & flex-end value will behave like that for flex-direction: row scenario, if it is column then flex-start and flex-end will mean left edge and right edge of the box.

align items
Gap, Row gap, Column gap :

gap property is the combination of row-gap and column-gap property. row-gap is the space between flex childs in 2 rows and column-gap is the space between flex childs in 2 columns. An example can be seen here : flex gaps

// First way
.child1{
  gap: 20px;
}

// Second way
.child1{
  gap: 20px 10px; // row gap is 20px and column gap is 10px.
}

// Third way, putting gaps separately
.child1{
  row-gap: 20px;
  column-gap: 10px;
}
Flex wrap :

flex-wrap property decides if the flex childs will wrap and break into next row when the available width of flex parent decreases or on small width screen. This property is very useful, if not set then it will create a horizontal scrollbar, which is a bad sign . The way to use is : flex-wrap: wrap. An example can be seen here : flex wrap

Properties applied on flex child element :
All the properties used above are applied on flex parents, but very less number of properties are dedicated on flex child elements.

Think of it as we can apply a common property on all child elements consistently, but what if we need to apply a little different styling on some specific flex child elements.

These properties are : align-self, order, flex-grow, flex-shrink and flex.
Align Self :
align-self is the most commonly used property on a specific (not all) flex child to override the applied align-items property on a parent.
align-items applies the same property on all the child elements and align-self override it on specific flex child.

The possible values are : flex-start, flex-end, center, baseline and stretch (all the properties are same as align-items, so i will not explain here)

Please have a look at this below image, where align-items : stretch is applied on all flex child but on 3rd flex child, we have applied a align-self: center.
align self
Order :

order is the property by which we can change the order of flex childs appearance. Meaning we can move the second child and make it the last element in the flex container or make it any element, may be first or third or anything.

The way to use is that flex childs are ordered relative to each other. If you want to make drastic changes in the placement of flex childs then, you need to apply order property on different childs. Please observe the two images, one is default ordering:

order

And the other is change by order property.

order

If you use order on only one element/child, then it will take only 2 possible values i.e -1 (make it the first element) or 1 (make it the last element).
So there is 2 system of using it, one is Minus one system and other is Plus 1 system, which means either we use -1, -2, -3, -4, etc for putting the order or we use 1, 2, 3, 4, etc for putting the order.

Now imagine we have a code snippet like this ::

<div>
  <p>One</p>
  <p class="b">Two</p>
  <p class="c">Three</p>
  <p>Four</p>
  <p class="e">Five</p>
</div>

// css
div{
  display: flex;
  justify-content: space-between;
}

.c{
  order: 1;
}

.b{
  order: 2;
}

.e{
  order: 3;
}


Now imagine we use an order value of 1 in para element(whose class is "c"), then it is moved in the last and becomes the last child. Have a look at this picture::

order


Now, if we want to make the second para element (whose class is "b") as the last element, then we use order: 2 . Same goes for para element whose class is "e". Please notice that putting order as 2 will make it the second element with respect to the element whose order is set as 1 and so order 3 will make it 3rd element with respect to the element whose order is set as 1.
Have a look at this picture::

order


Same goes for Minus one system, where order: -1 on a child, will make it the first element. And then if we put order: -2 or -3 or any negative number, then it will become second or third element with respect to the first element but on a negative axis meaning from right to left, e.g -3, -2, -1 etc.

Flex Grow :

flex-grow is a property which allows a flex child to take as much remaining space as is available in parent container.
If flex-grow: 1 on all flex childs, then all the elements will occupy same space in parent container. If flex-grow: 2 or 3 or 4 etc, on a specific flex child, then that element will occupy 2 times or 3 times or 4 times the space available (compared to other child) in parent container.

// css
.child{
  flex-grow: 3;
}
Flex Shrink :

flex-shrink is a property which allows a flex child to shrink if possible in parent container.
If flex-shrink: 1 on all flex childs, then all the elements will occupy minimum space in parent container. If flex-shrink: 2 or 3 or 4 etc, on a specific flex child, then that element will shrink 2 times or 3 times or 4 times compared to other child in parent container.

Default value of flex-grow and flex-shrink is 0.

// css
.child{
  flex-shrink: 3;
}
Flex :
flex is a property which is a combination of 3 properties such as flex-grow, flex-shrink and flex-basis
In short, flex-basis decides the default size or width of an flex child.

The default value of flex is : flex: 0 1 auto, meaning flex-grow is 0, meaning never grow even if space is available inside parent. flex-shrink is 1 meaning inside the flex container, always occupy the minimum space available. And flex-basis is auto meaning the flex child will have its width and size decided by its content. It is recommended to use flex property only and not a separate flex-grow, flex-shrink or flex-basis property.

There are 3 famous use case of flex property.
  • When you want any flex child or sidebar for example to be of always fixed width(400px), never grow, never shrink and irrespective of the screen size, then we use flex: 0 0 400px
  • When you want any flex child or sidebar for example to be of width(300px) minimum and 400px maximum, then we use flex: 0 0 400px and min-width: 300px; and max-width: 400px;
  • When you want any flex child or content section for example to be of variable width meaning taking all the available space inside parent, irrespective of the screen size, then we use flex: 1 and overflow-x: auto. The overflow property ensures that if there is more content then there will be a horizontal sidebar to accomodate that but its total width will never go more than its parent.

The below snippet is an example of a 3 column layout with sidebar, content and another sidebar forming the 3 columns and the usage of flex property too.
<div class="container">
  <div class="sidebar">Left Sidebar</div>
  <div class="content">Main content</div>
  <div class="sidebar">Right Sidebar</div>
</div>

// css
.container{
  display: flex;
}

.sidebar{
  flex: 0 0 400px;
  min-width: 300px;
  max-width: 400px;
}

.sidebar{
  flex: 1;
  overflow-x: auto;
}