# CSS Flexbox

## Summary


In web design, the traditional way to layout elements on a page was to use CSS properties such as `float`, `clear`, and `display`. In particular, `display` property has values `inline`, `block`, `inline-block`, and `table` that help with layout. CSS Flexbox is an easier method to do layouts.

With flexbox, items are laid out within a parent container. Flexbox makes it easy to distribute or fill extra spaces within the container. It's also possible to shrink the items dynamically to prevent overflows. We can also wrap items within the container to obtain a multiline flow. This "flexing" of items is an important aspect of flexbox that makes the design responsive to device dimensions. 

Site header, side bar, centered prompt, tabs, and form footer are some examples where flexbox can be used.

## Discussion

### What are the essential terms pertaining to CSS Flexbox?

Flexbox layout involves a parent element that defines how to lay out its child elements. The parent is called **flex container** and its children are called **flex items**. CSS declarations `display: flex` or `display: inline-flex` specify the use of flexbox. 

**Flex direction** determines if flex items are laid out horizontally or vertically. In either case, the direction in which items are laid out is called **main axis**. Its perpendicular axis is called **cross axis**. 

The container's boundaries are called **main-start**, **main-end**, **cross-start** and **cross-end**. Items are placed from start to end boundaries. Normally, this is left-to-right and top-to-bottom order. However, the order gets reversed if `flex-direction` has values `row-reverse` or `column-reverse`. Also, main axis and cross axis can get swapped depending on the current writing mode. 

Container dimensions are called **main size** and **cross size**. CSS properties `width`, `height` and their min/max equivalents are applicable to the container. 


### Which are the main CSS properties to control layout in CSS Flexbox?

On the flex container, main CSS properties are: 

    + display: flex | flex-inline
    + flex-direction: row | row-reverse | column | column-reverse
    + flex-wrap: nowrap | wrap | wrap-reverse
    + flex-flow: a shorthand for 'flex-direction || flex-wrap'
    + justify-content: flex-start | flex-end | center | space-between | space-around
    + align-items: flex-start | flex-end | center | baseline | stretch
    + align-content: flex-start | flex-end | center | space-between | space-around | stretchOn flex items, main CSS properties are: 

    + order: integer
    + flex-grow: number
    + flex-shrink: number
    + flex-basis: content | 'width'
    + flex: a shorthand for 'none | [ flex-grow flex-shrink? || flex-basis ]'
    + align-self: auto | flex-start | flex-end | center | baseline | stretchAn article on CSS-Tricks visually depicts the use of these properties. It's recommended to use shorthand forms `flex-flow` and `flex`. 


### What does it mean to grow or shrink flex items?

Along the main axis, flex items might not fill the container's main size. We could use `justify-content` to distribute the leftover space; or increase the size of items to fill the extra space. On the other hand, if items are too big for the container we could shrink the items to avoid overflow. 

In (b), all items are grown in equal proportion to fill up the extra space. In (c), green items retain their original size while orange items grow. In (d), green items grow relative to orange items in the ratio 3:1. Interestingly, this results in orange items shrinking below their original size.

In (e) and (f), items are wider and would overflow the container; but they don't overflow since wrapping is enabled. Since container is 500px wide and each item is 120px wide, we would expect the first row to contain four items. However, the effect of padding (8 x 5px) results in only three items in the first row.

Item width (or height for column-wise layout) and its min/max values also affect how items can be resized. 


### How can I align and justify items in a CSS flexbox container?

Along the main axis, `justify-content` controls how items are laid out and extra spaces are distributed. For example, `justify-content:flex-start` aligns content to main-start. Excess space, if any, is towards main-end; `justify-content:center` puts leftover space towards both main-start and main-end; `justify-content:space-between`, `justify-content:space-around`, and `justify-content:space-evenly` distribute leftover space between or around all items. 

Along the cross axis, `align-items` controls the alignment. For example, `align-items:center` centers items; `align-items:stretch` stretches items to fill the container's cross size (if set) or match the longest item. 

When wrapping is enabled, `align-content` becomes relevant. Like `align-items`, it affects alignment and spacing along the cross axis. 

Container property `align-items` can be overridden on individual items with `align-self`. For example, we can align all items to cross-start (`align-items:flex-start`) and one particular item to cross-end (`align-self:flex-end`). 


### How do I use the 'order' property of CSS Flexbox?

Flex items can be assigned to ordinal groups, with each group given an integer. Within the container, items are rendered based on this order, from lower to higher numbers. This is useful because the ordering of items need not be changed in the source document. Ordering can be controlled from CSS. 

An example use case is a tabbed interface. If we wish the active tab to be the leftmost tab (main-start), then we can set `.tabs > .current { order: -1; }`. All other tabs have the default value of zero. 

However, ordering items this way is only *visual ordering*. The logical ordering is still specified by the order in the source document. *Logical ordering* is what matters for accessibility, such as, navigating the items via tab keys.  


### What are some tips and tricks for using CSS Flexbox?

CSS Flexbox is primarily for 1-D layouts. Via nesting or wrapping, it's possible to achieve 2-D flexbox layouts. An excellent approach is to combine both CSS Grid and CSS Flexbox, thus leveraging the best of both worlds. Properties `justify-content` and `align-items` are useful in such an approach. 

Flex containers are not block elements. CSS properties `float`, `clear` and `vertical-align` have no effect on flex items. Property `overflow` is applicable to the container. 

It's possible to overlap flex items using negative margins or absolute positioning. 

Beau Carnes has published informative visualizations of how CSS Flexbox works. Flexbox Patterns is a useful resource where beginners can study many flexbox examples. 

## Milestones

Jul  
2009

W3C publishes a working draft of **CSS Flexible Box Layout** or Flexbox. After multiple revisions, first Candidate Recommendation of Flexbox is released in September 2012. 

Sep  
2012

W3C publishes the first Candidate Recommendation of **CSS Flexible Box Layout Module**. A flexbox layout can be specified with `display: flex`. However, the initial draft of July 2009 used `display: box` and a later draft of March 2012 used `display: flexbox`. Older browsers might not support the currently standardized CSS rule and fallback techniques may be required. 

Mar  
2016

W3C publishes as a Candidate Recommendation **CSS Flexible Box Layout Module Level 1**. As on December 2020, the latest version of this document is from November 2018. 

May  
2017

W3C publishes **CSS Grid Layout Module Level 1** as a Candidate Recommendation. Whereas CSS Flexbox is limited to one-dimensional layouts, CSS Grid can handle two-dimensional layouts. Designers view CSS Grid as not replacing but complementing CSS Flexbox. For example, we can do a flexbox layout within a grid layout or vice versa.