Flexbox

Since the rise of the internet, laying out web sites had been done using various means

These were the bane of many web developers’ existence because of a multitude of reasons that are well covered elsewhere (LMGTFY). Let’s just be happy you can forget about them and let’s move on.

CSS

Things did get better. After many years of epic and brutal wars trying to get <frameset></frameset> and <table></table> to succumb to our will and work in all browsers, the brave and fearless web developers simply had enough and said “NO MORE!”.

Actually CSS became a viable option for layouts, because of the introduction of element positioning and z-index. This was originally proposed back in 1997 by the W3C, later replaced by CSS 2.1…blah blah. Read more here!

Just as a throw-back, remember this? www.csszengarden.com

A Brighter Future

So, without further ado…let’s talk about the hotness that is Flexbox.

In the distance, the sad panda sheds a tear of pure flexbox joy…

What is Flexbox?

At a high level, flexbox is a new layout intended for complex applications and webpages.

Flexbox is a CSS box model optimized for user interface design. In the flex layout model, the children of a flex container can be laid out in any direction, and can “flex” their sizes, either growing to fill unused space or shrinking to avoid overflowing the parent. Both horizontal and vertical alignment of the children can be easily manipulated. Nesting of these boxes (horizontal inside vertical, or vertical inside horizontal) can be used to build layouts in two dimensions. https://www.w3.org/TR/css-flexbox-1/

So, if you can imagine your flexbox container as one of those PEZ containers, your flex items are the tasty, little candy treats inside. By default, those tasty treats flow in the direction of the pez container and are constrained to the container, but you have control over much of this, as we will learn.

Key Features

  • Content can flow in any direction (left, right, down or up)
  • Displayed order can be reversed or given a specific order
  • Content can be laid out across the main axis or the cross axis.
  • Content can grow or shrink to accomodate available space.
  • Content can be aligned in respect to the their container or their siblings.
  • Content can be dynamically collapsed or uncollapsed along the main axis while preserving the containers cross size.

Key Terms

  • There is a flex container and it has flex items
  • There is a main axis and a cross axis
  • There is a main start and a main end
  • There is a cross start and a cross end
  • There is a main size and a cross size

image

Flex Container

A flexbox container can be used as block-level or inline.

.block-level-flex-container {
  display: flex;
}

.inline-flex-container {
  display: inline-flex;
}

Alignment

There are 3 ways to control alignment of flex items.

  • justify-content - How flex items align along the main axis. For now, think text-align
  • align-content - Just like justify-content, but only for flex items that wrap.
  • align-items - How flex items align along the cross axis. For now, think vertical-align
justify-content

Aligns items along the main axis of the flex container.

image

align-items

Aligns items along the cross axis of the flex container.

image

align-content

Aligns content when flex-container wraps. Note: This only makes sense to use when you also use flex-wrap: wrap or flex-wrap: wrap-reverse

image

Ordering and Orientation

Flex items can flow up, down, left or right. They can also stay on one line or wrap to multiple lines.

  • flex-direction - Controls direction of flow.
  • flex-wrap - Should flex items stay on one line or wrap to multiple lines?
  • flex-flow - Shorthand for flex-direction and flex-wrap, i.e. flex-flow: column wrap

Accessibility Tip: Always keep the order in your HTML correct. Use the order and flex-flow/flex-direction to change this visually.

flex-direction

Controls the direction of the flow along the main axis. For each of the values below, imagine we are working on an xy axis.

  • flex-direction: row - x axis, left to right
  • flex-direction: row-reverse - x axis, right to left
  • flex-direction: column - y axis, top to bottom
  • flex-direction: column-reverse - y axis, bottom to top
flex-wrap

Controls whether items will wrap or not.

  • flex-wrap: wrap - items will wrap.
  • flex-wrap: wrap-reverse - items will wrap and stack in reverse order.
  • flex-wrap: no-wrap - items will not wrap and will bleed outside of the container.

flex-wrap will respect languages that are left-to-right or right-to-left. #winning

flex-flow

Shorthand for flex-direction and flex-wrap.

  • flex-flow: row
  • flex-flow: column wrap
  • flex-flow: row-reverse wrap-reverse

Flex Items

The direct descendants of your flex container are your flex items.

The exception is text without a tag, i.e. Just some text vs <span>I'm a flex item</span>.

Example

See the Pen Flexbox Examples - Flex items by Matti Salokangas (@sturdynut) on CodePen.

Flex Item Alignment

Flex items can override the align-items property of it’s flex container by using align-self.

align-self

Sometimes you want a specific flex item to behave differently than the rules set on the flex container.

align-self is the same as align-items but is just for a specific flex item.

image

Flex Item Flexibility

Depending on the size of the flex container, flex items can grow, shrink and also have a minimum width/height (depending on flex-direction).

  • flex-grow
  • flex-shrink
  • flex-basis

The defining aspect of flex layout is the ability to make the flex items “flex”, altering their width/height to fill the available space in the main dimension. This is done with the flex property. https://www.w3.org/TR/css-flexbox-1/#flexibility

flex-grow

Determines how a flex item will grow relative to the other flex items in the container when there is additional space to distribute.

Example

See the Pen Flexbox Examples - flex-grow by Matti Salokangas (@sturdynut) on CodePen.

flex-shrink

Determines how a flex item will shrink relative to the other flex items in the container when there is additional space to distribute. Flex-shrink is calculated by multiplying the flex-shrink value by the flex-basis (auto by default) when distributing negative space.

Example

See the Pen Flexbox Examples - flex-shrink by Matti Salokangas (@sturdynut) on CodePen.

flex-basis

Sets the initial size of the flex item prior to flex-grow and/or flex-shrink being applied.

Example

See the Pen Flexbox Examples - flex-basis by Matti Salokangas (@sturdynut) on CodePen.

flex

Shorthand for flex-grow, flex-shrink and flex-basis.

flex: [flex-grow] [flex-shrink] [flex-basis]

Example

  • flex: initial, equivolent to flex: 0 1 auto;
  • flex: auto, equivolent to flex: 1 1 auto;
  • flex: none, equivolent to flex: 0 0 auto;
  • flex: [positive-number], equivolent to flex: [positive-number] 1 0

Flex Item Ordering, Z-Index and Visibility

order
  • Flex items are ordered by the order modifier in place or the raw document order.

Examples

The items below would be displayed in reverse.

.item-1 {
  order: 3;
}
.item-2 {
  order: 2;
}
.item-3 {
  order: 1;
}

.item-3 would always be the first since it has a lower order than the default value of 0

.item-1 {
}
.item-2 {
}
.item-3 {
  order: -1;
}
z-index
  • Z-index values will stack elements even if position is static.
collapse
  • visibility: collapse will collapse a flex item affecting the containers main size, but will have no effect on the cross axis.

Umm…WAT?

This means that if you collapse a flex-item the width doesn’t change, so it isn’t jumpy. However, visibility: collapse is expensive, so only use it when you need it.

Margins and Padding

  • Margins of adjacent items do not collapse.
  • Percentage margins and paddings should be avoided as they will get different behavior in different browsers.
  • Auto margins expand to absorb extra space, which is awesome because you can use auto margins for alignment or to push items apart.

Minimum Size

A new value auto is now used as the initial value for min-width and min-height. This provides an intuitive experience because your flex items will fit to the flex container by default.

Tips

There are some nuances of Flexbox you should be aware of, if you are accustomed to using display: block.

  • column-* for multi-column layouts have no effect on a flex container.
  • float and clear will not work
  • vertical-align will not work
  • ::first-line and ::first-letter will not work

If you look at the browser support for Flexbox, we have full evergreen browser support. This means you can start using this now!

That’s it!

Hopefully you have a better feel for flexbox. If you want to dig into any of this deeper I recommend combing through the official documentation.

Still hungry? Here are some great resources for flexbox:

Top