Skip to main content

Flex Box

Resources

I. Introduction

Resources

Flexbox is a layout model that provides a more efficient way to arrange, align, and distribute space among items in a container. These items will flex (grow or shrink) based on rules you can define.

1. Flex Containers & Flex Items

  • A flex container is the parent element that contains flex items and is styled with display: flex.
  • A flex item is a child element that lives directly inside of a flex container, they can be aligned and distributed inside this container. Most of the time, we can have nested flex boxes, so a flex item may be a flex container, containing other flex items.

2. The flex property

The flex declaration is a shorthand for 3 properties: flex-growflex-shrink , and flex-basis that you can set on a flex item. These properties affect how flex items size themselves within their container. The flex property may be specified using one, two, or three values:

  • One value: which can be of the following
    • a value for flex-grow which is a positive number.
    • a value for flex-basis which can be a number, px, or auto.
  • Two values:
    • The first value must be a valid value for flex-grow
    • The second value must either be a valid value for flex-shrink or flex-basis.
  • Three values: the values must be in the following order: flex-grow, flex-shrink, flex-basis

Example: The flex: 1 declaration equates to: flex-grow: 1, flex-shrink: 1, flex-basis: 0 = flex: 1 1 0.

.flex-container{
display: flex;
}
.flex-item {
flex: 1;
}
  1. flex-grow: expects a single number (not negative) as its value, this value is used as the flex item’s “growth factor”. When we don’t specify the default value of flex-grow is 0. Example:
  • When we apply flex: 1 to every div, we’re telling every div to grow the same amount. → every div is the same size.
  • When we apply flex: 2 to one of the divs, that div will grow to 2x the size of others.
<div class="flex-container">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
</div>
.flex-grow {
display: flex;
}

/* this selector selects all divs inside of .flex-container */
.flex-grow div {
background: peachpuff;
border: 4px solid brown;
height: 100px;
flex: 1 1 0%;
}

/* only div.two is selected here */
.flex-grow .two {
flex: 2 1 0%;
}
  1. flex-shrink: similar to flex-grow, but sets the “shrink factor” of a flex item. flex-shrink is only applied if the size of all flex items is larger than their parent container. → item will only shrink if the container is getting smaller than the item itself.
    • The default shrink value is flex-shrink: 1, which means all items will shrink evenly.
    • If you do not want an item to shrink, you must specify → flex-shrink: 0.
Example:
<div class="flex-shrink">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
</div
.flex-shrink {
display: flex;
}

/* this selector selects all divs inside of .flex-container */
.flex-shrink div {
background: peachpuff;
border: 4px solid brown;
height: 100px;
width: 250px;
flex: 1 1 auto;
}

.flex-shrink .two {
flex-shrink: 0;
}

Note: When you specify flex-grow or flex-shrink, the flex items don’t necessarily respect your given values for width. When the parent container is big, the items may grow bigger to fill it, when the parent container is too small, the default behavior is to shrink to fit.

  1. flex-basis: sets the initial size of a flex item along the main axis, so any sort of flex-grow or flex-shrink starts from that baseline size.

In a Flex rowflex-basis does the same thing as width. In a Flex columnflex-basis does the same thing as height.

  • When you specify flex: 1 on an element → flex-basis defaults to flex-basis: 0%.
  • When you don’t specify flex-basis, the default value is auto.
  • When we declare flex-basis: auto, we’re asking the item to check for a width declaration. (The previous example of flex-shrink does mention this.)

→ Like we saw with widthflex-basis is more of a suggestion than a hard constraint. At a certain point, there just isn't enough space for all of the elements to sit at their assigned size, so they have to compromise, to avoid an overflow.

3. flex property’s values

  1. initial: the item is sized according to the specified width and height properties.
  • shrinks to its minimum size to fit the container, but does NOT grow to absorb any extra free space in the flex container.
  • This is equivalent to setting flex: 0 1 auto.
  1. auto: the item is also sized according to the specified width and height properties.
  • grows to absorb any extra free space in the flex container, and shrinks to its minimum size to fit the container.
  • This is equivalent to setting flex: 1 1 auto.
  1. none: the item is sized according to its width and height properties.
  • Fully inflexible: it neither shrinks nor grows in relation to the flex container.
  • This is equivalent to setting flex: 0 0 auto.

II. Axes & Alignment

Resources

1. Axes

1. flex-direction

The orientation of items within a flex container can be controlled using the flex-direction property. A flexbox can work either horizontally or vertically, the default direction for a flex container is horizontally (or row) but you can always change this direction to vertical (or column).

.flex-container{
display: flex;
flex-direction: column;
}

A flex-container contains 2 axes: the main axis and the cross axis. When we declare the flex-direction, we are changing the direction of the main axis. The cross axis is always perpendicular to the main axis, hence, it changes direction with the main axis when we declare flex-direction. ‘ Here are a few common values of flex-direction:

  • flex-direction: row: the main axis goes from left - right → the cross axis is now top - bottom.
  • flex-direction: column: the main axis goes from top - bottom → the cross axis is now left - right.
  • flex-direction: row-reverse: the main axis goes from right - left.
  • flex-direction: column-reverse: the main axis goes from bottom-top.

Note: By default, the flex-direction: row and flex-basis value refers to the width of an element. However, in a column flex-container, flex-basis refers to the height. This is because flex-basis refers to the size of the item along the main axis. Try this piece of code to see how flex-direction: column affects flex: 1.

 .flex-container {
display: flex;
flex-direction: column;
}
.flex-item{
height: 80px;
flex: 1;
}

→ Because flex: 1 , that means flex-basis: 0 → the initial height of the item is now set to 0, and the div collapses because there’s no height or width inside to fill the div.

Note: flex-direction technically changes the direction and orientation of the main axis, to change the direction of the cross axis (left → right, top → bottom), we can use flex-wrap: wrap-reverse, which will be further discussed in flex-wrap section.

2. order

In addition to reversing the order in which flex items are visually displayed, you can target individual items and change where they appear using order.

Example:
  • Source item 1: order: 2
  • Source item 2: order: 3
  • Source item 3: order: 1
  • Source item 4: order: 3
  • Source item 5: order: 1

These items would be displayed on the page in the following order.

Flex items have a default order value of 0 → Items with an order value greater than 0 will be displayed after any items that have not been given an explicit order value.

order can also take in negative values. As this is lower than 0, the item will always be displayed first, before any items that have not been given an explicit order value.

2. Alignment

Resources

Using flex: 1 for the items makes each of the items grow to fill the available space in the flex container. But what if we want the flex items to stay with the width and height we give them, but distribute themselves differently within the container? We can use alignment properties for the flex-container.

1. justify-content

aligns and distributes space among items across the main axis. This property can have the following common values:

  • Positional:
    • center: aligns all items in the container to the center.
    • start, end: aligns all items in the container to the start or end of the main axis.
    • flex-start, flex-end: does the same thing as start or end, but is affected by flex-direction: -reverse, when the flex direction changes
    • left, right: aligns all items in the container to the left or right.
  • Distributed Alignment:
    • space-between: evenly distributes all items within the flex container along the main axis. The spacing between each pair of the adjacent items is the same, however, the first item has no space with the main-start edge, and the last item has no space with the main-end edge.
    • space-around: evenly distributes all items within the container along the main axis, just like space-between. However, the difference is, that the spacing between each pair of adjacent items is the same, AND the space between the first item and after the last item equals half of the space between each pair of adjacent items.
    • space-evenly: evenly distributes all items within the container along the main axis. However, the spacing between each pair of adjacent items, the main-start edge and the first item, and the main-end edge and the last item, are the same.
    • stretch: For flexbox, the stretch value behaves as flex-start or start. This is because, in flexbox, stretching is controlled using the flex-grow property.

2. align-items

aligns and distributes items across the cross-axis. This property can have the following common values:

  • center: the flex items' margin boxes are centered within the line on the cross-axis.
  • start, end: the items are pushed to the start/end edge of the alignment container in the appropriate axis.
  • flex-start, flex-end: does the same thing as start or end, but is affected by flex-wrap: wrap-reverse, when the flex-direction changes.
  • self-start, self-end:
  • stretch: If the items are smaller than the alignment container, auto-sized items will be equally enlarged to fill the container, respecting the items' width and height limits.

Obvious Note: Because justify-content and align-items are based on the main and cross-axis of your container, their behavior changes when you change the flex-direction of a flex-container.

3. Gap - the gap property

The gap on a flex container adds a specified space between flex items, similar to adding a margin to the items themselves.

.flex-container{
gap: 5px;
}

4. The flex-wrap property

The flex-wrap property sets whether flex items are forced onto one line or can wrap onto multiple lines. If wrapping is allowed, it sets the direction in which the lines are stacked. The flex-wrap property can have the following values:

  1. nowrap: this is the default value. The flex items are laid out in a single line which may cause the flex container to overflow.
  2. wrap: The flex items break into multiple lines.
  3. wrap-reverse: Behaves the same as wrap but cross-axis start and cross-axis end are permuted.