## Introduction #

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

Look at me!

I am a Reflex grid!

At the time of writing, browser flexbox support is at 96.63% so it's definitely time to forge ahead with flexbox, especially with a reliable inline-block fallback. 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 browser that does not support flexbox (such as Internet Explorer 9) to see for yourself!

The reason this works is because of the way browsers handle CSS properties that they do not understand. It's possible to include both your fallback and your ideal CSS properties in the same classes and let browsers use the ones that they do understand. I've written at length on this subject if you're interested in learning more.

This is version 2 of Reflex grid which is not compatible with version 1. The last release under version 1 was 1.5.0 and I have maintained the docs for version 1 in case you still need them.

### Why use reflex? #

- It's lightweight - 20KB in it's minified form and 2.5KB gzipped
- Where flexbox is supported, columns 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 with Sass/SCSS
- Easily customizable and extendable

### Intended use #

- Creating complex nested flexbox grids which take advantage of flexbox layout properties
- Using a flexbox layout inside a CSS grid page layout
- Generating a flexbox grid with dynamic content of varying height e.g. a list of products
- An addition or replacement for your current css layout framework
- A set of vendor-prefixed mixins and helper classes to get your flexbox solution off the ground faster

## Browser support #

All browser specific implementations of flexbox are supported via vendor prefixes, including the slightly problematic IE10 implementation of an early draft of the flexbox specification. Internet Explorer 6 and 7 are explicitly not supported because there are so many issues and quirks that it renders the exercise futile. However, the basic grid still works in those browsers.

### Breakpoints in ie8 #

If you want to use the grid with breakpoints in ie8 you will need to use respond.js which enables media query support in those browsers via JavaScript. There's very little downside to adding this because it's very lightweight and performs well.

### HTML5 elements #

If you wish to use html5 elements such as `section` in older browsers such as ie8 and 9, you will need to use html5Shiv. Again, there's very little downside to using this considering the extra peace of mind it gives you when using html5 elements.

### ie10 and ie11 grid heights #

ie10 and ie11 have a flexbox rendering bug which means that unless the height of the grid is set with an unit value, flex items will only stretch to be as large as their largest sibling. The grid will still work in these browsers, but it won't entirely fill the height of it's container unless a `height` in units is specified for the grid.

Please note that `min-height` and percentage heights will not work. The height must be set with `px` `em` or `vh`. There's further reading to be had on the bug itself if you wish to understand it further. You can use a CSS hack for ie10 and ie11 to set a unit height and solve these issues in your grid implementation.

    .grid {
        min-height: 300px;

        @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
            height: 600px;
        }
    }

### box-sizing: border-box #

I highly recommend using a wildcard CSS query to set all elements to `box-sizing: border-box`. Reflex grid applies this to all grid elements so it is sized appropriately but you might want to also add these properties to your CSS framework to ensure consistent behaviour across all elements inside and outside of the grid:

    *, *::after, *::before {
        -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
        box-sizing: border-box;
    }

## Usage #

### Use as CSS #

You can use the compiled css directly by downloading either the minified or non-minified version.

### Clone via github #

You could clone this repo via github which would allow you to modify the variables and build your own version of this grid. You can modify things like the number of columns or the breakpoints.

### Use with npm #

If you're familiar with npm you can use `npm install reflex-grid` to have a look around, or add it as a dependency to your node project.

Visit the reflex-grid npm page for stats and other npm related info.

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

In a nutshell, any direct child elements of a flexbox container are treated as flex items and can be layed out with flexbox css properties on either axis.

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

You can optionally set any `col-x` element to operate as a flex container using the class `col-grid` which sets `flex-direction: column` and the main axis therefore follows the vertical direction. There's more information on this in the Using flexbox in columns section.

## Anatomy of a reflex grid #

### Basic example #

I have added some colour as a visual indicator to all the examples on this page so you can clearly see how the layout works. This is just for demonstration purposes.

    <div class="grid">
        <div class="col-6">
            <content>
        </div>
        <div class="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.

### A closer look #

#### grid parent

example: `grid`

This is the top level container element and is similar to a `row` in bootstrap. Any `.col` element that is a direct child of a `.grid` is a flex item and their layout can be affected by any modifer classes placed on the parent `.grid`.

#### column child

examples: `col-10` `col-sm-6` `col-auto`

This is a child element of `.grid` and behaves as a flex item.

#### grid modifier

examples: `align-end` `no-wrap` `justify-center`

Modifier classes can be applied to the `.grid` element to modify the layout of it's direct children elements.

## 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="col-6">
            <content>
        </div>
    </div>

### Unordered list #

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

### Html5 elements #

    <section class="grid">
        <article class="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:

col-
  does not collapse
col-xs-
  collapses below 576px
col-sm-
  collapses below 768px
col-md-
  collapses below 992px
col-lg-
  collapses below 1200px
col-xlg-
  collapses below 1600px

col-4

col-4

col-4

col-xs-4

col-xs-8

col-sm-6

col-sm-6

col-md-8

col-md-4

col-lg-4

col-lg-8

col-xlg-8

col-xlg-4

## Auto columns #

You can add any number of auto sizing `col-auto` columns to a `grid` and therefore avoid using numbered columns. You can also use the breakpoint sensitive classes such as `col-sm-auto` 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. For full browser support, you need to use numbered columns.

col-auto
col-auto
col-sm-auto
col-md-auto
col-lg-auto
col-xlg-auto

## Containers #

A Reflex grid will fill the full width of it's parent element which means you can drop it into any containing element you may already have in place.

However, Reflex grid has a responsive `.container` class available which uses a combination of margins and padding to maintain layout between elements both inside and outside of the grid. By default this uses the same breakpoints as the numbered columns. However, It is possible to modify the max width and breakpoints of the `.container` class by modifying the included variables.scss file and building a new css file.

### Responsive container #

    <div class="container">
        <p>This element is inside the container but outside of the grid</p>
        <div class="grid">
            <div class="col-6">
                <p>An element inside the grid</p>
            </div>
            <div class="col-6">
                <p>Another element inside the grid</p>
            </div>
        </div>
    </div>

This element is inside the container but outside of the grid

An element inside the grid

Another element inside the grid

### Full width container #

If you desire a full width container without a max width but with the same combination of margins and padding to maintain layout between elements both inside and outside of the grid there is also a `.container-full` class available.

    <div class="container-full">
        <p>This element is inside the <em>full width</em> container but outside of the grid</p>
        <div class="grid">
            <div class="col-6">
                <p>An element inside the grid</p>
            </div>
            <div class="col-6">
                <p>Another element inside the grid</p>
            </div>
        </div>
    </div>

This element is inside the full width container but outside of the grid

An element inside the grid

Another element inside the grid

### No container #

Without a container, the grid fills it's containing element (in this case the `body` element).

An element inside the grid

Another element inside the grid

## Nested grids #

It's possible to nest grids inside each other. Start a new `.grid` inside a `.col-x` element and everything lines up correctly. There are some more advanced examples of layouts on the examples page.

    <div class="grid">
        <div class="col-sm-6">
            <content>
        </div>
        <div class="col-sm-6">
            <div class="grid">
                <div class="col-6">
                    <content>
                </div>
                <div class="col-6">
                    <content>
                </div>
                <div class="col-6">
                    <content>
                </div>
                <div class="col-6">
                    <content>
                </div>
            </div>
        </div>
    </div>

col-sm-6

col-6

col-6

col-6

col-6

## 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

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

#### default wrap #

Grid columns wrap by default.

col-6

col-6

col-10

#### .no-wrap #

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

col-6

col-6

col-10

#### .wrap-reverse #

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

col-6 (I am first in the markup)

col-6 (I am second in the markup)

col-10 (I am third in the markup)

## Cross axis modifiers #

These modifiers can be added to your `grid` element.

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

#### .align-start #

When applied to `grid` 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.

#### .align-end #

When applied to `grid` 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.

#### .align-center #

When applied to `grid` 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.

#### .align-baseline #

When applied to `grid` sets `align-items: baseline`. This makes `col-x` elements line up according to the baseline of the first child element (as long as the first elements in each column are an inline element such as headings or paragraphs). This example should make this confusing behaviour a bit clearer:

Biggest text

Medium text

Small text

## Cross axis override modifiers #

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

#### .align-self-stretch #

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

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

.align-self-stretch

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

#### .align-self-start #

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

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

.align-self-start

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

#### .align-self-end #

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

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

align-self-end

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

#### .align-self-center #

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

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

align-self-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 `col-x` elements inside the grid.

This modifier has no effect when there is only one line of `col-x` elements in the grid so cannot be used when `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

#### .align-content-start #

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

First appear

Great blessed

Years night

Firmament you

To lights

Place good

#### .align-content-end #

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

First appear

Great blessed

Years night

Firmament you

To lights

Place good

#### .align-content-center #

When applied to `grid` sets `align-content: center`

First appear

Great blessed

Years night

Firmament you

To lights

Place good

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

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

First appear

Great blessed

Years night

Firmament you

To lights

Place good

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

When applied to `grid` 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 `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.

#### .justify-end #

When applied to `grid` 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.

#### .justify-center #

When applied to `grid` 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.

#### .justify-space-between #

When applied to `grid` 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.

#### .justify-space-around #

When applied to `grid` 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 `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`. `col-x` elements are columns by default but can be set to behave as rows by using `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

#### .direction-row-reverse #

When applied to `grid` 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

#### .direction-column #

When applied to `grid` sets `flex-direction: column`

I am first in the markup

I am second in the markup

I am third in the markup

#### .direction-column-reverse #

When applied to `grid` 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

### .order-<n> #

When applied to `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 `col-x` elements only above certain viewport sizes.

For example: `.order-md-2`

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

When applied to `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

## Responsive offsets #

There are responsive offset classes that correspond to the available breakpoints so you can choose to offset your `col-x` elements at certain viewport sizes.

For example: `.offset-md-2`

### .offset-<breakpoint>-<n> #

When applied to `col-x` applies an offset when viewport size is above the selected breakpoint.

Offset by 3 columns at all times

Offset by 2 columns when viewport size is above 768px

Offset by 1 column when viewport size is above 1200px

## Padding modifiers #

By default, `col-x` columns have internal padding. It's possible to remove this padding on the entire grid or single columns.

### .grid-bleed #

When used on a `.grid` element, removes internal padding from all child `col-x` column elements.

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.

### .col-bleed #

Removes internal padding from a single `col-x` column element.

.col-bleed

Default column

### .col-bleed-x #

Removes internal horizontal padding from a single `col-x` column element.

.col-bleed-x

Default column

### .col-bleed-y #

Removes internal vertical padding from a single `col-x` column element.

.col-bleed-y

Default column

## 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 yourself by building the SCSS files.

.hidden-xxs

.hidden-xs

.hidden-sm

.hidden-md

.hidden-lg

.hidden-xlg

## Using flexbox in columns #

By default, a `.col-x` element behaves like a good old fashioned block element but it is possible to modify it to perform as a flexbox element with `flex-direction: column` by adding the `.col-grid` class to any `col-x` element. This will allow you to take advantage of flexbox layout and (for example) create a footer that is always at the bottom of the column.

When a column has the `.col-grid` class applied to it, any of the grid modifiers such as `.justify-space-between` will work on it but be aware that the orientation is in the column direction and therefore the main axis is vertical.

When using flexbox for column layout, be aware that flex items cannot be floated and their margins do not collapse. Here's the relevant information from the flexbox spec:

> A flex container establishes a new flex formatting context for its contents. This is the same as establishing a block formatting context, except that flex layout is used instead of block layout. For example, floats do not intrude into the flex container, and the flex container’s margins do not collapse with the margins of its contents.

As long as you're aware of these facts, you won't be surprised when you start using flexbox in columns.

### .flex-footer #

A `.flex-footer` element that is the last child of a `.col-grid` column will always appear at the bottom of the column, regardless of how much content you have above it.

    <div class="grid">
        <div class="col-6 col-grid">
            <content>
            <div class="flex-footer">
                <p>.flex-footer</p>
            </div>
        </div>
    </div>

Aliquam ornare faucibus leo, vel euismod nisi porta non. Donec at arcu eget enim bibendum facilisis. Etiam urna elit, blandit ut libero placerat, iaculis aliquam erat.

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

Aliquam ornare faucibus leo.

### .flex-img #

Responsive images are nothing new and most frameworks include classes to create them. For example, bootstrap uses this solution. However, there are some additional complexities in some browsers when using images as a flex item. Therefore, when using an image in a column with the `.col-grid` class, you should use the class `.flex-img` which solves these problems.

    <div class="grid">
        <div class="col-6 col-grid">
            <img class="flex-img" src="images/1.jpg">
        </div>
    </div>

## Cards #

A common use case for Reflex grid is to create product cards of the same height. The CSS for this is not part of Reflex grid and you would need to add your own card classes on top of reflex but I have included a few examples below and many more on the examples page to help you get started.

If you want to use these card styles as a starting point for your own implementation you can incorporate the SCSS I wrote for these cards into your CSS build.

### Amazing

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

### Crazy good

Nunc dignissim in ante sed dapibus. Aenean sit amet aliquet dolor, at auctor erat. Aliquam ornare faucibus leo, vel euismod nisi porta non.

### Lovely stuff

Aenean sit amet aliquet dolor, at auctor erat. Aliquam ornare faucibus leo, vel euismod nisi porta non. Donec at arcu eget enim bibendum facilisis.

read more

### Top destination

Aenean sit amet aliquet dolor, at auctor erat. Aliquam ornare faucibus leo, vel euismod nisi porta non. Donec at arcu eget enim bibendum facilisis.

## Examples #

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

## Acknowledgements #

I use browserstack to test this in different browsers and I'm a big fan of their service in general. Thanks Browserstack!

I would also 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
- Philip Walton for his useful info about the ie10 flexbox implementation.
- caniuse for browser coverage statistics
- lorempixel.com for placeholder images
- icons8 for the logo