## What is reflex? #

Reflex gives you the ability to easily take advantage of flexbox for laying out a grid while having a reliable inline-block fallback for older browsers.

At the time of writing, global flexbox support is at 94.1% (excluding browsers with outdated or partial support) so I propose that it's time to start taking advantage of flexbox and accept that the inline-block fallback won't support everything.

Where flexbox isn't supported, your basic grid structure will remain intact and most of the layout classes still work. Try this page out in a non-flexbox browser to see for yourself!

## Why use reflex? #

- It's lightweight - 12KB in it's minified form and 1.8KB gzipped
- Where flexbox is supported, grid cells are all the same height by default
- Reflex grid cells never push each other out of the way (as with floated grids)
- Supports semantic elements e.g. you can use `ul` as a grid
- Supports nested grids
- Good cross browser support
- Built in both Sass/SCSS and LESS
- Built using BEM syntax
- Easily customizable and extendable

## Intended use #

- Creating complex nested grids which take advantage of flexbox layout properties
- Generating a reliable grid with dynamic content e.g. a list of products
- An addition or replacement to your current css framework
- A set of vendor-prefixed Sass or LESS mixins ready to be incorporated into an existing framework
- A set of vendor-prefixed helper classes to get your flexbox solution off the ground faster

## Reflex grid introduction #

    <div class="grid">
        <div class="grid__col-6">
            <content>
        </div>
        <div class="grid__col-6">
            <content>
        </div>
    </div>

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc et sagittis dui. Maecenas rhoncus justo aliquam urna finibus tincidunt et ut mauris.
Vivamus nulla leo, dignissim nec tempor vel, consequat ac dolor. Nunc dignissim in ante sed dapibus. Aenean sit amet aliquet dolor, at auctor erat.

With reference to BEM syntax, this is the anamtomy of a reflex grid:

### .grid

example: `grid`

This is the top level element and is similar to a `row` in bootstrap. It sets the following properties:

- `display: flex`
- `flex-wrap: wrap`

### .grid__element

example: `grid__col-xs-6`

This is a child element of `.grid` and is similar to a `col-x` in bootstrap. It sets the following properties:

- `display: flex`
- `flex-direction: column`

### .grid--modifier

example: `grid--align-end`

Modifier classes can be applied to both the `grid` and `grid__element`. Further examples include:

- `grid--no-wrap`
- `grid--align-end`
- `grid--justify-center`

## Browser support #

Reflex falls back to an inline-block grid for browsers that do not support flexbox. Reflex uses some css hacks to help the inline-block grid work on older browsers. It's important to note that some of the features of flexbox do not have an equivalent in the inline-block fallback so not everything will work in the fallback, but your grid will remain intact.

If you want to use the grid with breakpoints in ie8 and below you will need to use respond.js which enables media query support in those browsers via JavaScript and html5Shiv if you wish to use html5 elements such as `section`

It is possible for this framework to support ie6. You can make a tiny change to enable support but it greatly increases the filesize of the css. Look in _mixins.scss (Sass) or mixins.less (LESS) for the commented line.

## Semantic markup #

You don't have to use `div` for your grid and ideally you should use the most semantically appropriate markup for your use case with no visible difference.

### Divs #

    <div class="grid">
        <div class="grid__col-6">
            <content>
        </div>
    </div>

### Unordered list #

    <ul class="grid">
        <li class="grid__col-6">
            <content>
        </li>
    </ul>

### Html5 elements #

    <section class="grid">
        <article class="grid__col-6">
            <content>
        </article>
    </section>

## Numbered columns #

By default reflex is a 12 column grid but this can be easily changed. Regardless of how many columns you need, you will likely require extra control over the breakpoints at which your grid columns revert to 100% width. To do this you will need to use these modifier classes which determine grid columns at various viewport sizes. A grid built using numbered columns in this way will remain fully intact in the inline-block fallback.

The reflex grid breakpoints can be easily re-defined but are set to these values by default:

Class prefix | grid__col- | grid__col-xs- | grid__col-sm- | grid__col-md- | grid__col-lg- | grid__col-xlg-
Collapses at | does not collapse | < 480px | < 768px | < 992px | < 1200px | < 1600px

## Auto columns #

You can add any number of auto sizing `grid__col-auto` columns to a `grid` and therefore avoid using numbered columns. You can also use the regular breakpoints to determine when your columns revert to 100% width. A grid built using auto columns will not remain fully intact in the inline-block fallback and will not work properly in ie10 due to it's limited flexbox support but if this is a concern, you could use JavaScript for that.

grid__col-auto
grid__col-auto
grid__col-sm-auto
grid__col-sm-auto
grid__col-md-auto

## Flexbox direction and axis #

To understand how this grid works, you'll need to first understand how flexbox works, especially in relation to the cross axis and main axis. There's a pretty good introduction to flexbox here but here's a quick demo of the main points: flex direction, main axis, and cross axis.

### row

↔ main axis

↕ cross axis

### column

↕ main axis

↔ cross axis

By default any `grid` element is set to `flex-direction: row` and the main axis therefore follows the horizontal direction.

By default any `grid__col-x` element is set to `flex-direction: column` and the main axis therefore follows the vertical direction.

This will become important when you are using the modifier classes which typically act upon either the main or cross axis

## Grid modifiers #

### Grid wrapping #

By default, the `flex-wrap` property of a `display: flex` element is set to `nowrap` but because this is a grid framework we generally need our grid to wrap so we explcitly set `flex-wrap: wrap` on our `grid` element

`grid__col-x` elements do not wrap by default, but you can make them do so by using the modifier `grid--wrap`.

In the inline-block fallback your grid columns will always wrap when they add up to 100% width (12 column by default).

#### .grid--no-wrap #

When applied to `grid` sets `flex-wrap: nowrap` and gives you this:

these

columns

do not collapse

#### .grid--wrap-reverse #

When applied to `grid` sets `flex-wrap: wrap-reverse` and gives you a grid that wraps in reverse:

I am first in the markup

I am second in the markup

I am third in the markup

### Cross axis modifiers #

These modifiers can be added to your `grid` element but also to the `grid__col-x` elements inside the grid.

#### Equal height columns by default #

In browsers that support flexbox we have equal height columns by default because the default value of `align-items` is `stretch`

First appear years night there the in them rule.

Over after behold was living together tree is very sixth let bring fish. Forth behold they're fly deep.

Be can't winged good for also saying first.

#### .grid--align-start #

When applied to `grid` or `grid__col-x` sets `align-items: flex-start` and gives you this:

First appear years night there the in them rule.

Over after behold was living together tree is very sixth let bring fish. Forth behold they're fly deep.

Be can't winged good for also saying first.

#### .grid--align-end #

When applied to `grid` or `grid__col-x` sets `align-items: flex-end`

First appear years night there the in them rule.

Over after behold was living together tree is very sixth let bring fish. Forth behold they're fly deep.

Be can't winged good for also saying first.

#### .grid--align-center #

When applied to `grid` or `grid__col-x` sets `align-items: center`

First appear years night there the in them rule.

Over after behold was living together tree is very sixth let bring fish. Forth behold they're fly deep.

Be can't winged good for also saying first.

#### .grid--align-baseline #

When applied to `grid` or `grid__col-x` sets `align-items: baseline`.

By default, different text elements in adjacent columns will be aligned by their size and margin:

## Heading 2

### Heading 3

Paragraph

With `grid--align-baseline` applied to the `grid` element the text lines up:

## Heading 2

### Heading 3

Paragraph

### Cross axis override modifiers #

You can override the cross axis alignment of a single `grid__col-x` element by using these modifers.

#### .grid--align-self-stretch #

When applied to `grid__col-x` sets `align-self: stretch`

First appear years night there the in them rule that bring fly gathered there is place good.

stretch

First appear years night there the in them rule that bring fly gathered there is place good Created rule image night firmament.

#### .grid--align-self-start #

When applied to `grid__col-x` sets `align-self: flex-start`

First appear years night there the in them rule that bring fly gathered there is place good.

start

First appear years night there the in them rule that bring fly gathered there is place good Created rule image night firmament.

#### .grid--align-self-end #

When applied to `grid__col-x` sets `align-self: flex-end`

First appear years night there the in them rule that bring fly gathered there is place good.

end

First appear years night there the in them rule that bring fly gathered there is place good Created rule image night firmament.

#### .grid--align-self-center #

When applied to `grid__col-x` sets `align-self: center`

First appear years night there the in them rule that bring fly gathered there is place good.

center

First appear years night there the in them rule that bring fly gathered there is place good Created rule image night firmament.

### Cross axis positioning #

These modifers set the value of `align-content` which determine the position of your grid elements when there is extra space available in the cross-axis (usually because you've set a height on the grid that is larger than the contents). These modifiers can be added to your `grid` element but also to the `grid__col-x` elements inside the grid.

This modifier has no effect when there is only one line of `grid__col-x` elements in the grid so cannot be used when `grid--no-wrap` is present on the grid or when you only have a single row of columns

#### Stretch by default #

In browsers that support flexbox we have equal height columns that stretch to fill the available space by default because the default value of `align-content` is `stretch`

First appear

Great blessed

Years night

Firmament you

To lights

Place good

#### .grid--align-content-start #

When applied to `grid` or `grid__col-x` sets `align-content: flex-start`

First appear

Great blessed

Years night

Firmament you

To lights

Place good

#### .grid--align-content-end #

When applied to `grid` or `grid__col-x` sets `align-content: flex-end`

First appear

Great blessed

Years night

Firmament you

To lights

Place good

#### .grid--align-content-center #

When applied to `grid` or `grid__col-x` sets `align-content: center`

First appear

Great blessed

Years night

Firmament you

To lights

Place good

#### .grid--align-content-space-between #

When applied to `grid` or `grid__col-x` sets `align-content: space-between`

First appear

Great blessed

Years night

Firmament you

To lights

Place good

#### .grid--align-content-space-around #

When applied to `grid` or `grid__col-x` sets `align-content: space-around`

First appear

Great blessed

Years night

Firmament you

To lights

Place good

### Main axis alignment #

These modifers set the value of `justify-content` which determine the position of your grid elements when there is extra space available in the main-axis (usually because your columns do not make up the full width of a grid). These modifiers can be added to your `grid` element but also to the `grid__col-x` elements inside the grid.

#### Left aligned by default #

Grid elements are aligned to the left by default because the default value of `justify-content` is `flex-start`

First appear years night there the in them rule.

Be can't winged good for also saying first. Shall, fourth Greater cattle.

#### .grid--justify-end #

When applied to `grid` or `grid__col-x` sets `justify-content: flex-end`

First appear years night there the in them rule.

Be can't winged good for also saying first. Shall, fourth Greater cattle.

#### .grid--justify-center #

When applied to `grid` or `grid__col-x` sets `justify-content: center`

First appear years night there the in them rule.

Be can't winged good for also saying first. Shall, fourth Greater cattle.

#### .grid--justify-space-between #

When applied to `grid` or `grid__col-x` sets `justify-content: space-between`

First appear years night there the in them rule.

Be can't winged good for also saying first. Shall, fourth Greater cattle.

First appear years night there the in them rule.

First appear years night there the in them rule.

Be can't winged good for also saying first. Shall, fourth Greater cattle.

#### .grid--justify-space-around #

When applied to `grid` or `grid__col-x` sets `justify-content: space-around`

First appear years night there the in them rule.

Be can't winged good for also saying first. Shall, fourth Greater cattle.

First appear years night there the in them rule.

First appear years night there the in them rule.

Be can't winged good for also saying first. Shall, fourth Greater cattle.

### Flex direction #

These modifers set the value of `flex-direction`. These modifiers can be added to your `grid` element but also to the `grid__col-x` elements inside the grid.

#### Rows by default #

`grid` elements are in rows by default because the default value of `flex-direction` is `row`. `grid__col-x` elements are columns by default but can be set to behave as rows by using `grid--direction-row`

I am first in the markup

I am second in the markup

I am third in the markup

I am fourth in the markup

I am fifth in the markup

#### .grid--direction-row-reverse #

When applied to `grid` or `grid__col-x` sets `flex-direction: row-reverse`

I am first in the markup

I am second in the markup

I am third in the markup

I am fourth in the markup

I am fifth in the markup

#### .grid--direction-column #

When applied to `grid` or `grid__col-x` sets `flex-direction: column`

I am first in the markup

I am second in the markup

I am third in the markup

#### .grid--direction-column-reverse #

When applied to `grid` or `grid__col-x` sets `flex-direction: column-reverse`

I am first in the markup

I am second in the markup

I am third in the markup

### Ordering grid elements #

These helper classes allow you to easily set `order` to your grid elements. This is useful because it allows you to have your markup in the correct semantic order for accessiblity purposes but in a different order visually.

By default there are 12 ordering helpers to match the default 12 columns. Changing the number of columns by editing the variable will also produce a matching number of order helper classes

### .grid--order-<n> #

When applied to `grid__col-x` sets `order: n`

I am first in the markup but ordered second

I am second in the markup but ordered third

I am third in the markup but ordered first

### Responsive ordering #

There are responsive ordering classes that correspond to both the number of columns and the breakpoints so you can choose to change the order of `grid__col-x` elements only above certain viewport sizes.

For example: `.grid--order-2-md`

### .grid--order-<n>-<breakpoint> #

When applied to `grid__col-x` sets `order: n` when viewport size is above the selected breakpoint.

I am first in the markup but ordered second when viewport size is above 992px

I am second in the markup but ordered third when viewport size is above 992px

I am third in the markup but ordered first when viewport size is above 992px

## Advanced grid layout #

### .grid__cell #

There are some nuances with flexbox that may make your life difficult if you're not expecting them. There is a wealth of information available on this subject in the flexbox working draft.

This is part of flexbox, and is entirely expected. However, flexbox layout is not always appropriate so it's possible to add a `grid__cell` child element to your `grid__col-x` columns which defines an area of your column as `display: block` allowing you to lay out the contents of your grid elements like you would normally.

### Flexbox differences

- Margins on adjacent elements do not collapse
- Margins set to `auto` absorb extra space and can be used for alignment
- `float`, `clear` and `vertical-align` have no effect on a flex item

### Column content by default

    <div class="grid">
        <div class="grid__col-6">
            <content>
        </div>
        <div class="grid__col-6">
            <content>
        </div>
    </div>

float: right

float: left

The top and bottom margins on these paragraphs do not collapse together as you would expect

The top and bottom margins on these paragraphs do not collapse together as you would expect

### Column content using .grid__cell

    <div class="grid">
        <div class="grid__col-6">
            <div class="grid__cell">
                <content>
            </div>
        </div>
        <div class="grid__col-6">
            <div class="grid__cell">
                <content>
            </div>
        </div>
    </div>

float: right

float: left

The top and bottom margins on these paragraphs collapse together as you would expect

The top and bottom margins on these paragraphs collapse together as you would expect

### .grid__cell-img #

If you're using a `grid__cell` as above, you can simply use your regular responsive image solution such as the solution used in bootstrap.

If you're not using a `grid__cell`, flex images need to be handled differently to make them responsive and you should use `grid__cell-img`.

    <div class="grid">
        <div class="grid__col-sm-4">
            <img class="grid__cell-img" src="">
        </div>
    </div>

### .grid__cell-footer #

It's possible to set up a footer section in a `grid__col-x` element that is always aligned to the bottom by using `grid__cell-footer`. This footer element is set up as a flex box so all the usual grid modifers work on it.

- Consectetur adipiscing elit, sed do eiusmod.

  grid__cell-footer

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc et sagittis dui. Maecenas rhoncus justo aliquam urna finibus tincidunt et ut mauris.

  grid__cell-footer

### .grid--bleed #

By default, `grid__col-x` elements have padding to space the grid out. It's possible to override this in all `grid__col-x` child elements in a grid by applying the modifer `grid--bleed` to your `grid` element.

- Consectetur adipiscing elit, sed do eiusmod.

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc et sagittis dui. Maecenas rhoncus justo aliquam urna finibus tincidunt et ut mauris.

### .grid__col--bleed #

You can override the padding on individual `grid__col-x` elements by using `grid__col--bleed`.

- Default

- `grid__col--bleed` applied

### .grid__col--bleed-x #

You can override the left and right padding on individual `grid__col-x` elements by using `grid__col--bleed-x`.

- Default

- `grid__col--bleed-x` applied

### .grid__col--bleed-y #

You can override the top and bottom padding on individual `grid__col-x` elements by using `grid__col--bleed-y`.

- Default

- `grid__col--bleed-y` applied

### .grid__col--bg #

You can add a background image to `grid__col-x` elements by using `grid__col--bg`.

- You can add a background image to `grid__col-x` elements by using `grid__col--bg`.

### .grid__cell--padding-x #

You can apply padding to individual `grid__cell` elements by using `grid__cell--padding-x`.

- padding-sm

- padding-md

- padding-lg

## Visibility helpers #

You can use some generic visibility helpers that can be applied to any element, not just grid elements. resize the viewport to see them in action. The breakpoints can be changed if you're building the css via less or sass/SCSS.

.hidden-xxs
.hidden-xs
.hidden-sm
.hidden-md
.hidden-lg

## Examples #

There are a handful of examples to show you what is possible with minimal effort on the demo page

## Acknowledgements #

I would like to acknowledge the following resources which all helped in some way while I was building this:

- bootstrap for some of the calculations and mixins
- css-tricks for their flexbox introduction
- caniuse for browser coverage statistics
- lorempixel.com for placeholder images