DEV Community

Neha Sharma
Neha Sharma

Posted on • Updated on

CSS flex-box Guide for anyone

❓ 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 :

  1. Working with Floats and positions was challenging. Due to clearing the floats, handling different resolutions, and devices.
  2. Layouts with floats and positions were hard to manage.
  3. Lot of code to meet same designs for cross browsers, OS, platforms, resolutions, etc.
  4. Creating responsive designs required extra effort.
  5. Cross-browser support was the pain.

📝 Important Concepts

  1. Axis - main and cross
  2. Row and Column
  3. Parent (container) and Children (items)
  4. Wrap
  5. Basis
  6. Order
  7. Gap
  8. Grow & Shrink
  9. Justify-content, Align-items and Align-content
  10. 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.

Alt Text

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.

Alt Text

👍 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>
Enter fullscreen mode Exit fullscreen mode
section {
   display: flex;
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode
section { 
 display: flex;
 flex-direction: column; 
}
Enter fullscreen mode Exit fullscreen mode

Alt Text

Alt Text

Alt Text

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.

💻 Code - row

💻 Code - row-reverse

💻 Code - column

💻 Code - column-reverse

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>
Enter fullscreen mode Exit fullscreen mode
section{ 
 width: 500px;
 display: flex; 
 flex-direction: row; 
 flex-wrap: wrap; 
}

section > div{
 width: 200px;
}
Enter fullscreen mode Exit fullscreen mode

flex no-wrap

flex wrap

💻 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.

available space

👍 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>
Enter fullscreen mode Exit fullscreen mode
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;
}
Enter fullscreen mode Exit fullscreen mode
<section>
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</section>
Enter fullscreen mode Exit fullscreen mode
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;
  }
}
Enter fullscreen mode Exit fullscreen mode

💻 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;
}
Enter fullscreen mode Exit fullscreen mode

💻 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>
Enter fullscreen mode Exit fullscreen mode
.one {
  order: 5;
}

.three {
  order: 1;
}
Enter fullscreen mode Exit fullscreen mode

order

💻 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 use gap

gap

section { 
 width: 400px;
 display: flex; 
 flex-direction: row; 
 flex-wrap: wrap; 
 gap:10px;
}

section > div{
 width: 200px;
}
Enter fullscreen mode Exit fullscreen mode

💻 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 the flex-direction and cross-axis is always perpendicular to the main-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 the flex-direction

<section>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
</section>
Enter fullscreen mode Exit fullscreen mode
section { 
 width: 800px;
 display: flex; 
 flex-direction: row; 
 flex-wrap: wrap; 
 justify-content: space-between;
}

section > div{
 width: 200px;
}
Enter fullscreen mode Exit fullscreen mode

Alt Text

Alt Text

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

Alt Text

<section>
   <div>1</div>
   <div>2</div>
   <div>3</div>
   <div>4</div>
   <div>5</div>
</section>
Enter fullscreen mode Exit fullscreen mode
section { 
 width: 800px;
 display: flex; 
 flex-direction: row; 
 flex-wrap: wrap; 
 align-items: center;
}

section > div{
 width: 200px;
}
Enter fullscreen mode Exit fullscreen mode
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.

Alt Text

<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>
Enter fullscreen mode Exit fullscreen mode
section { 
 width: 800px;
 display: flex; 
 flex-direction: row; 
 flex-wrap: wrap; 
 justify-content:wrap;
}

section > div{
 width: 200px;
}
Enter fullscreen mode Exit fullscreen mode
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

Before we say bye do check Caniuse.com for the support of the flex and its properties at different.

Discussion (3)

Collapse
francoisjulienne profile image
JULIENNE François

404 on link for grow and shrink section : github.com/Neha/css-flex-box/tree/...

Collapse
oneonone97 profile image
Rohan Singh

Thanks Neha for this article! Currently I'm learning Flexbox and it's very helpful for beginner as well! 🌻🌻

Collapse
hellonehha profile image
Neha Sharma Author

Thank you Rohan.

I appreciated your feedback on adding code snippets. I will update the blog with code snippets.