❓ What is flex?
flex is a CSS3 property. It is used for creating the layout and manage the content placement.
Before flex, the only way to create layouts was either using 'floats', 'tables', or 'positions'.
👍 floats, tables, and positions, vs flex :
- Working with Floats and positions was challenging. Due to clearing the floats, handling different resolutions, and devices.
- Layouts with floats and positions were hard to manage.
- Lot of code to meet same designs for cross browsers, OS, platforms, resolutions, etc.
- Creating responsive designs required extra effort.
- Cross-browser support was the pain.
📝 Important Concepts
- Axis - main and cross
- Row and Column
- Parent (container) and Children (items)
- Wrap
- Basis
- Order
- Gap
- Grow & Shrink
- Justify-content, Align-items and Align-content
- Grids vs flex
💫 axis and flex
To understand how flex works and the properties associated with it we need to first understand the concept of axis
.
In flex we have 2 axis - main
and cross
. Cross axis is dependent on the main-axis. Cross-axis is always perpendicular to the main-axis.
What is main-axis? Main-axis is define based on the direction
of the flex. If the direction is row
then the main-axis
will be x-axis (horizontal). If it is column
then the main-axis
would be y-axis(vertical). Now, based on the main-axis, cross-axis will be changed.
In the below image you can see the cross-axis is always perpendicular to the main-axis. So, when main-axis
is x-axis
then cross-axis
is y-axis
and vice-versa.
👍 Defining flex
To use flex we need to use the display: flex
. The container with display:flex
become the parent and the direct elements inside it will be called children or items.
default
flex-direction
value is row. We are going to learn about flex-direction soon.
Eg:
<section>
<div>One</div>
<div>Two</div>
</section>
section {
display: flex;
}
When we declare any container as flex
flex-direction
auto declared with the value set to the row
.
💻 Code
property | values |
---|---|
display | flex, inline-flex |
👍 Row and column
In flex we can have either row or column. We cannot have both. This is the huge difference between grids and flex. Flex is 1 Dimensional. Row and column are the backbone and feature(s) of the flex. This helps in creating the layout, arranging the content. You will see with examples as we move ahead.
We use the property flex-direction
to define row/column.
<section>
<div>One</div>
<div>Two</div>
</section>
section {
display: flex;
flex-direction: column;
}
In flex
we can reverse the row and column by using just one property row-reverse
and column-reverse
. This is an easy way to achieve complex designs but this would be only the visual change there won't be any DOM changes. Hence, it is important to think about the accessibility side-effects.
property | values |
---|---|
flex-direction | row, column, row-reserve, column-reserve |
👍 wrap
While working with row and column. It is common to see items are overflowing from the flex container especially when the items are more than the container's width or height.
We can wrap (moving the items to the next row or column automatically) by using the property flex-wrap
. This will not let the items flow out of the container.
wrap
property is highly used especially when the content is dynamic.
The default value is no-wrap
.
<section>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</section>
section{
width: 500px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
section > div{
width: 200px;
}
💻 Code
property | values |
---|---|
flex-wrap | no-wrap, flex-wrap, wrap-reverse |
Responsive
Another advantage of flex is the ease of working with responsive designs. Code-writing and managing responsive designs with flex is easier.
1) We don't need to change the DOM as per the screen size. By just changing one property flex-direction
we can make the items stack or spread. A common design pattern for the responsive design.
2) We can use the available space to adjust the items (explained below)
We learned earlier that by using flex
we can make the element behave as either columns or rows. Now, we can control how the items should behave as per the available space in the container.
👍 grow and shrink
grow
and shrink
expand and contract the items (flex-children) as per the available space in the container (parent flex element).
Elements generally take the width as per the content. The width are fixed and they are not scalable as per the space available on the screen/resolution. In such cases, grow and shrink helps in scaling the elements as per the space available.
Grow and Shrink accepts numeric value (positive integer) and the items will grow accordingly.
Shrink and grow accept value as a positive integer. 1 means equal space.
<section>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</section>
section {
display: flex;
background: #e4f8ff;
padding: 10px;
width: 800px;
flex-direction: row;
flex-wrap: wrap;
}
section > div {
background: #dfffdf;
padding: 10px;
border: 1px solid #fff;
width: 50px;
flex-grow: 1;
}
<section>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</section>
section {
display: flex;
background: #f8ffe7;
padding: 10px;
width: 100%;
flex-direction: row;
flex-wrap: wrap;
}
section > div {
background: #dfffdf;
padding: 10px;
border: 1px solid #fff;
flex-basis: 100px;
flex-shrink: 1;
}
@media only screen and (min-width: 600px) {
section {
width: 800px;
flex-wrap: wrap;
}
section > div {
background: #dfffdf;
padding: 10px;
border: 1px solid #fff;
}
}
💻 Code
👍 flex-basis
flex-basis
is to set the size of the item. By default, it would be auto which means content size. If there is width declared on the item then the flex-basis
value would be respected.
If we are using size we can drop width. Ideally, when working with flex we should use size over width.
section {
width: 400px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
section > div{
flex-basis: 200px;
}
💻 Code
👍 Order
There are a few cases where we might need to change the order of the elements to appear different visually and in DOM. In such cases, we have order
from flex that helps the developer to change the order of the elements - visually
.
1) Order can accept the negative value. If given -1 then the element will stick to the first position.
2) If 2 elements have the same value then the deal-breaker would be their order in the DOM.
3) On row-reverse, the order in the DOM will be respected
<section>
<div class="one">1</div>
<div class="two">2</div>
<div class="three">3</div>
<div class="four">4</div>
<div class="five">5</div>
</section>
.one {
order: 5;
}
.three {
order: 1;
}
💻 Code
Accessibility and order: As we are changing
order
visually using CSS and not through DOM, we need to take care of the accessibility - tabbing order, focusing order, etc.
👍 gap
To give the space between the row and column we use gap
. The issue with margins is it doesn't collapsed the top/bottom margin
and we end up with the extra space. However, gap
has no such issue.
When you are working with
flex
usegap
section {
width: 400px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap:10px;
}
section > div{
width: 200px;
}
💻 Code
👍 alignment
Now, we know that flex
has a container (parent) and items (children). To align the items and container flex
provide us the following property:
1) justify-content
2) align-items
3) align-content
if you know grids, then you will notice that flex doesn't have the
justify-items
property. A good read from stack overflow on WHY?
In flex we align the items and have space between them across 'main' and 'cross' axis.
Remember
main-axis
is dependent on theflex-direction
andcross-axis
is always perpendicular to themain-axis
.
👍 justify-content
Justify-content
defines how the browser distributes space between and around content items across main-axis
.
Remember
main-axis
is dependent on theflex-direction
<section>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</section>
section {
width: 800px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
}
section > div{
width: 200px;
}
property | values |
---|---|
justify-content | start, center, end, flex-end, flex-start, space-between, space-around, space-evenly, stretch |
👍 align-items
It will align the items to the cross-axis
<section>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</section>
section {
width: 800px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}
section > div{
width: 200px;
}
property | values |
---|---|
align-items | stretch , flex-start ,flex-end , center , baseline, start, end, ... |
👍 align-content
It will align the content across the main-axis
. It doesn't work with a single line. It needs to have multiple lines. The height of the flex container should be more than the height required to display items.
In the developer language, align-content
distribute the available space between the rows and columns.
<section>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
</section>
section {
width: 800px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content:wrap;
}
section > div{
width: 200px;
}
property | values |
---|---|
align-content | flex-start , flex-end , center , space-between , space-around , space-evenly, stretch... |
💫 Shorthand
There are a few shorthands we should be aware of:
1) flex-grow + flex-shrink + flex-basis
flex: flex-grow flex-shrink flex-basis
flex: 1
: unit-less value means flex-grow
& rest is 0
flex: 2em
: declaring flex-basis
and rest is 0
flex: 1 2
: unit less value means flex-grow
and flex-shrink
2) flex-direction + flex-wrap
flex-flow: flex-direction flex-wrap
flex-flow: column no-wrap
⚡️ CSS Grids vs flex
property | grids | flex |
---|---|---|
type | 2D | 1D |
rows/columns | Can have both | Can have either row or column |
layouts | Can create complex layout | Not a good choice to create complex layout |
lines | It has grid-lines | Doesn't have flex-lines |
Justify-content | Has | Doesn't have |
align/justify | is not dependent on the rows/columns choice | dependent on the flex-direction |
Top comments (3)
404 on link for grow and shrink section : github.com/Neha/css-flex-box/tree/...
Thanks Neha for this article! Currently I'm learning Flexbox and it's very helpful for beginner as well! 🌻🌻
Thank you Rohan.
I appreciated your feedback on adding code snippets. I will update the blog with code snippets.