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.
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.
.hidden-*-up
classes hide the element when the viewport is at the given breakpoint or wider..hidden-*-down
classes hide the element when the viewport is at the given breakpoint or smaller..hidden-*
classes hide the element when the viewport is at the given breakpoint.
It is possible to change these breakpoints by modifying the included variables.scss file and building a new css file.
For example:
.hidden-sm-down
to hide size sm
and smaller
.hidden-sm-up
to hide size sm
and bigger
.hidden-sm
to hide size sm
only
Extra Extra small 0px - <576px | Extra small ≥576px - <768px | Small ≥768px - <992px | Medium ≥992px - <1200px | Large ≥1200px - <1600px | Extra large ≥1600px | |
---|---|---|---|---|---|---|
.hidden-xxs |
Hidden | Visible | Visible | Visible | Visible | Visible |
.hidden-xs |
Visible | Hidden | Visible | Visible | Visible | Visible |
.hidden-sm |
Visible | Visible | Hidden | Visible | Visible | Visible |
.hidden-md |
Visible | Visible | Visible | Hidden | Visible | Visible |
.hidden-lg |
Visible | Visible | Visible | Visible | Hidden | Visible |
.hidden-xlg |
Visible | Visible | Visible | Visible | Visible | Hidden |
.hidden-xs-down |
Hidden | Hidden | Visible | Visible | Visible | Visible |
.hidden-sm-down |
Hidden | Hidden | Hidden | Visible | Visible | Visible |
.hidden-md-down |
Hidden | Hidden | Hidden | Hidden | Visible | Visible |
.hidden-lg-down |
Hidden | Hidden | Hidden | Hidden | Hidden | Visible |
.hidden-xs-up |
Visible | Hidden | Hidden | Hidden | Hidden | Hidden |
.hidden-sm-up |
Visible | Visible | Hidden | Hidden | Hidden | Hidden |
.hidden-md-up |
Visible | Visible | Visible | Hidden | Hidden | Hidden |
.hidden-lg-up |
Visible | Visible | Visible | Visible | Hidden | Hidden |
Resize the viewport to see them in action.
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.
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