Meteor + React + F7 Integration Guide

https://github.com/killerchip/meteor-react-f7

This is project is both a starter template and an integration guide, for Meteor-React with Framework7-React.

In addition it incldues a preconfigured setup of ESLint and Prettier, for code quality and code style enforcement in your codebase.

  • Meteor is a full-stack framework for building web and hybrid mobile (web-based) apps, which supports React as its templating solution for front-end. On top of that you can use

  • Framework7 to give your mobile apps a close to native look and feel.

How to use this project

You can directly clone the project and start working on it.

1
git clone https://github.com/killerchip/meteor-react-f7.git
1
2
3
meteor run
meteor run android-device
meteor run ios-device

Manual integration and explanation

If you want to manually build this project, here are the steps taken:

Create a meteor project using CLI

1
meteor create --react <my-project>

Add necessary Headers in the project

client/main.hml

1
2
3
4
5
<head>
<title>meteor-react-f7</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui, viewport-fit=cover">
</head>

You need to add the viewport meta tag to make the app responsive and display correctly in mobile device.

Adding ESLint and Prettier

ESLint will suggest best practices for Javascript, Meteor, and React.

Prettier will suggest a unified code style (display) to make it easier to read.

Husky will enforce those rules upon commiting changes.

For more details you can refer to the following Posts:

An overview of steps are the following:

Install the necessary packages:

1
2
3
4
5
6
meteor npm install --save-dev babel-eslint eslint-config-airbnb eslint-plugin-import eslint-plugin-meteor eslint-plugin-react eslint-plugin-jsx-a11y eslint-import-resolver-meteor eslint @meteorjs/eslint-config-meteor


meteor npm install --save-dev --save-exact prettier

meteor npm install --save-dev eslint-plugin-prettier eslint-config-prettier

Then make sure the following configuration files are put in your project’s root directory. They are a suggested configuration for those modules.

Finally put the following scripts in package.json, to be able to use these tools from command-line.

1
2
3
4
5
scripts: {
"lint": "node_modules/.bin/eslint . --ext .js,.jsx",
"pretty": "node_modules/.bin/prettier './**/*.{js,jsx,scss}'",
"pretty:write": "node_modules/.bin/prettier --write './**/*.{js,jsx,scss}'",
}

Add the following in the pacakge.json file to allow automatically prettier fixes when you commit your code.

1
2
3
4
"husky": {
"hooks": {
"pre-commit": "precise-commits --no-verify"
}

My personal preference is to do manual edits with my VSCode plugin.

https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode

Framework7 Integration

Install the following F7 packages.

1
meteor npm install framework7 framework7-react

According to documentation, you must initialize Framework7.

client/main.jsx

1
2
3
4
import Framework7 from 'framework7';
import Framework7React from 'framework7-react';

Framework7.use(Framework7React);

Also the Framework7 CSS must be imported. In case of Meteor app the easiest way to do it is just to import it in a file, and the Meteor builder will bundle it in the app.html file.

client/main.jsx

1
import '../node_modules/framework7/css/framework7.min.css';

Now you need to initialize the App component of framework7. So rename the default App React component to something else (e.g. Root).

client/main.jsx

1
2
3
4
5
import Root from '/imports/ui/Root.jsx';

Meteor.startup(() => {
render(<Root />, document.getElementById('react-target'));
});

And in the newly renamed Root.jsx file, initialize the framework7 App component.

imports/ui/Root.jsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import React from 'react';
import Hello from './Hello.jsx';
import Info from './Info.jsx';

/* globals App, View, Page, Navbar */

const Root = () => (
<App
params={{
name: 'Meteor React F7',
id: 'net.killerchip.meteor-react-f7',
statusbar: {
androidBackgroundColor: '#FFF',
iosBackgroundColor: '#FFF'
}
}}
>
<View main>
<Page>
<Navbar title="MeteorJS - React - F7" />
<div>
<h1>Welcome to Meteor!</h1>
<Hello />
<Info />
</div>
</Page>
</View>
</App>
);

export default Root;

Framework7’s components are included by Meteor’s builder in the bundle itself. So you can’t (actually you should not) import the framework7 react components (e.g. App, View, etc.). But because ESLint will complain, you can use the /* globals */ directive to declare them. Consider them as a replacement for import statements for these components.

Finally a cordova-plugin-statusbar is added, and the correspoing App options to set its background color.

imports/ui/Root.jsx

1
2
3
4
statusbar: {
androidBackgroundColor: '#FFF',
iosBackgroundColor: '#FFF'
}

Setting up Prettier along ESLint

In my previous article “ESlint configuration on Meteor-React project” I showed you how you can install and configure ESLint for automatically enforcing code-style to your Javascript code. With Prettier you can take this one step further and have Prettier do the actual formatting part of your code style.

This is an article on how you can easily integrate Prettier into your project in combination with ESLint.

Prettier vs ESLint

ESLint is concerned both for code quality and code formatting styles.

Prettier is only concerned with the formatting styles of your code.

So eventually you can keep ESLint for code quality and use Prettier for formatting your code.

Install Prettier

You should install Prettier pinned to a specific version. The creators most probably will introduce stylistic changes between releases. So you don’t want to automatically update your Prettier package, before you check it.

1
npm install --save-dev --save-exact prettier

Integrating with ESLint

By integrating we mean that each time you run ESLint, it will automatically run Prettier checks and report any non-compliances along with the normal ESLint issues. For this you will have to install eslint-plugin-prettier.

1
npm install --save-dev eslint-plugin-prettier

Then bind the plugin to ESLint via ESLint configuration.

.eslintrc.json

1
2
3
4
5
6
{
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error"
}
}

Disable ESLint formatting rules

Since now you will be using Prettier for code styling (not quality), you should disable the styling rules of ESLint so you don’t have conflicts between the packages. You don’t want ESLint to complain about styles that were fixed by Prettier.

The easiest way to do this, is to install eslint-config-prettier.

1
npm install --save-dev eslint-config-prettier

and in .eslintrc.json

1
2
3
{
"extends": [..., "prettier"]
}

Re-enabling some ESLint Rules

Now Prettier has disabled styling rules from ESLint but in addition some other quality rules, that MAY conflict. So you may want to re-enable these rules again in ESLint. In addition there are some configurations/rules between the two packages that need to be configured properly so they work together.

I urge you to read the special rules documentation and re-enable rules and make adjustments to your needs.

ESLint rules can be re-enabled in .eslintrc.json config file. Prettier configuration can be stored in .prettierrc.json file.

My preffered .eslintrc.json (see curly, max-len, no-confusing-arrow rules):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
{
{
"extends": [
"@meteorjs/eslint-config-meteor",
"prettier"
],
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error",
"indent": [
"error",
4
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
],
"no-console": "off",
"import/prefer-default-export": "off",
"curly": [
"error",
"all"
],
"max-len": [
"error",
{
"code": 80,
"ignoreUrls": true
}
],
"no-confusing-arrow": [
"error",
{
"allowParens": false
}
]
}
}

And my preffered .prettierrc.json file:

1
2
3
4
{
"tabWidth": 4,
"singleQuote": true
}

Calling Prettier manually

You can setup an npm script to scan your code and prettify it:

package.json

1
2
3
4
5
{
"scripts": {
"pretty:write": "node_modules/.bin/prettier --write './**/*.{js,jsx,scss}'"
}
}

It write directly to the files and make changes. So better to have committed you changes before you ‘prettify’ them. So you can revert back.

If you want to exclude specific folders/files from the script, you can setup a .prettierignore file:

.prettierignore

1
2
dist/
node_modules/

Git Hooks

A recommended approach is to ‘hook’ Prettier with git so you can prettify your files when you commit your changes.

There are various solutions to this and you can explore them here: https://prettier.io/docs/en/precommit.html

Precise-Commits

The precise-commits package will trigger Prettier only for lines that you changed during commit. This can be a very convinient approach for large projects with an established code base, which you want to prettify in stages.

You can install it along with husky package to hook it into git.

1
npm install precise-commits husky@next --save-dev

And then hook it to git:

package.json

1
2
3
4
5
6
7
{
"husky": {
"hooks": {
"pre-commit": "precise-commits"
}
}
}

Each time you commit your changes, the script will run and prettify your changes (thus needing an additional commit).

VSCode plugin

If you are using VSCode editor you can alwasy install the appropriate plugin so you prettify your code while you are writing it.

https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode

ESlint configuration on Meteor-React project

The following are simple instructions / recommendation on setting up ESlint rules for a Meteor/React project.

It is based on the recommendations of Meteor Guide with additional modifications that found out working for my cases.

The lint configuration is based on Airbnb lint configuration and React-plugin.

Install ESLint

You can install ESLint for your project by issuing the command:

1
meteor npm install --save-dev babel-eslint eslint-config-airbnb eslint-plugin-import eslint-plugin-meteor eslint-plugin-react eslint-plugin-jsx-a11y eslint-import-resolver-meteor eslint @meteorjs/eslint-config-meteor

Configure ESLint

I prefer the usage of .eslintrc.json file in the root folder of my project, in order to create/override my own rules. So the basic contents of the file are:

.eslintrc.json

1
2
3
4
5
6
{
"extends": "@meteorjs/eslint-config-meteor",
"env": {
"meteor": true
}
}

It extends the rules/configuration installed by the npm packages, plus enables global variables recognition of Meteor environment.

Additional rules

You can override specific rules globally by modifying the .eslintrc.json file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
"rules": {
"indent": [
"error",
4
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
}

The above example sets indentation to 4 spaces (not tabs), uses single quotes '' and requires a semicolon ; at the end of each javascript statement.

Check via command line

You can check your code via command line. It can help even better if you setup a script in your package.json file:

package.json

1
2
3
scipts: {
"lint": "node_modules/.bin/eslint . --ext .js,.jsx"
}

So now invoking the following command, will scan all your .js and .jsx files.

1
npm run lint .

Disabling rules

ESLint rules have specific names, and you can disable them on various levels… from files to specific lines. You can disable/enable them by adding special comments inside your code files.

Disabling ESLint for entire file

1
2
3
/* eslint-disable */

alert('foo');

Disabling ESLint for block of code

1
2
3
4
5
/* eslint-disable */

alert('foo');

/* eslint-enable */

Disabling Specific rules

1
2
3
4
5
6
/* eslint-disable no-alert, no-console */

alert('foo');
console.log('bar');

/* eslint-enable no-alert, no-console */

Disabling for specific lines

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
alert('foo'); // eslint-disable-line

// eslint-disable-next-line
alert('foo');

/* eslint-disable-next-line */
alert('foo');

alert('foo'); /* eslint-disable-line */

alert('foo'); // eslint-disable-line no-alert

// eslint-disable-next-line no-alert
alert('foo');

alert('foo'); /* eslint-disable-line no-alert */

/* eslint-disable-next-line no-alert */
alert('foo');

Find more information at: ESlint website

Editor plugins

You can also use plugins to help you directly when you are writing your code with editors.

My personal favorite is VSCode and the ESLint plugin.

Find more instructions for other popular editos in Meteor Guide.

React - A Beginner's Cheatsheet

This a collection of cheatsheets for beginners in React. It is based on React JS Documentation. Keep it handy for when you want quickly to refer on how to do React stuff.

Find Github project with examples here…

Contents:

Starting a Project

Minimal HTML Page

Dowanlod the following page and start building:
Single File Example

It is for tests only. Not for production environment.

Rendering components

single-file-example.html

In HTML:

1
2
3
<body>
<div id="react-root"></div>
</body>

In JSX file:

1
2
3
4
ReactDOM.render(
<h1>Hello World</h1>,
document.getElementById('root');
);

Defining Components

Functional Components

functional-components.html:

Define a component as a function:

props is the properties passed to our component.

1
2
3
4
5
6
7
8
function Welcome(props) {
return <h1>Hello, {props.name}</h1>
}

ReactDOM.render(
<Welcome name="John Doe" />,
document.getElementById('root')
);

Class components

class-components.html:

1
2
3
4
5
class Goodbye extends React.Component {
render() {
return <h1>Goodbye, {this.props.name}</h1>
}
}

Assignable to variables

assignables.html:

1
2
3
4
5
6
const welcomeSirComponent = <Welcome name="Sir" />;

ReactDOM.render(
welcomeSirComponent,
document.getElementById('root')
);

Local State

states.html

Defining state

State can be initialized in constructor:

1
2
3
4
5
6
7
8
class TimeCounter extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: 0,
date: new Date()
};
...

Reading State

1
2
3
4
<div>
<h1>Counting: {this.state.counter}</h1>
<p>{this.state.date.toLocaleTimeString()}</p>
</div>

Updating state

Use setState:

1
2
3
this.setState({
date: new Date()
});

Relying on previous state to update state

In this case do not rely directly to this.state object. Use the setState with arrow function parameter:

1
2
3
this.setState(
(prevState, props) => ({counter: prevState.counter + props.incValue})
);

Event Handling

event-handling.html

Simple Case

Use preventDefault and not return false to prevent bubbling up the event.

You attach an event handler function and not a string in the onClick and the other event handler properties.

1
2
3
4
5
6
7
8
9
10
11
function ALink() {
function handleClick(e) {
e.preventDefault();
alert ('You clicked button: A');
console.log('Event', e);
}

return (
<a href="#" onClick={handleClick}>Link A</a>
);
}

Event Handling in Class / bind method

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class BLink extends React.Component {

constructor(props){
super(props);
this.handleClick = this.handleClick.bind(this);
}

handleClick(e) {
e.preventDefault();
alert('You clicked button: B');
console.log(e);
console.log(this);
}

render(){
return (
<a href="#" onClick={this.handleClick}>Link B</a>
);
}

}

Event Handling / Arrow functions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class CLink extends React.Component {

//Arrow function as event handler
handleClick = (e) => {
e.preventDefault();
alert('You clicked button: C');
console.log(e);
console.log(this);
};

render(){
return (
<a href="#" onClick={this.handleClick}>Link C</a>
);
}

}

Event Handling / Arrow Callbacks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class DLink extends React.Component {

handleClick = (e) => {
e.preventDefault();
alert('You clicked button: D');
console.log(e);
console.log(this);
};

//Directly Arrow function in callback statement
render(){
return (
<a href="#" onClick={(e) => this.handleClick(e)}>Link D</a>
);
}
}

Passing Arguments with Arrow Callbacks

Event argument has to be passed to the event handler, along with other custom parameters.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class DLink extends React.Component {

handleClick = (e, name) => {
e.preventDefault();
alert(`You clicked button: D and the name is ${name}`);
console.log(e);
console.log(this);
};

render(){
return (
<a href="#" onClick={(e) => this.handleClick(e, 'John Doe')}>Link D</a>
);
}
}

Passing Arguments with Callback binding

The Event argument will be automatically be passed after any custom parameters in the .bind operation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class ELink extends React.Component {

handleClick (name, e) {
alert(`You clicked button: E and the name is ${name}`);
console.log(e);
console.log(this);
};

render(){
return (
<a href="#" onClick={this.handleClick.bind(this, "Jane Doe")}>Link E</a>
);
}
}

Passing Up State

pass-up-events.html

You can pass up state from children components to parent. The parent component passes an even handler in props and the child component calls it up.

Parent passes event handler to child

1
<NameInput onChange={ (name)=> {this.setState({name})} } />

Child calls the parent handler on state changes

1
<input type="text" onChange={(e) => {this.props.onChange(e.target.value)}}></input>

Children Components

children-props.html

A component can handle children components by having direct access to their JSX via the props.children property.

A component can have ‘content’:

1
2
3
4
<Bordered>
<p>Dear John</p>
<p>I wish you Happy Birthday!!</p>
</Bordered>

And the Bordered component can access and manipulate the content:

1
2
3
4
5
6
7
8
9
10
11
12
class Bordered extends React.Component {
render(){
return (
<div>
Letter:
<div className="fancy-border content">
{this.props.children}
</div>
</div>
);
}
}

Multiple Children Components

You can pass them as custom JSX props.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class NewsPaperPage extends React.Component {
render() {

const columnLeft = (...);
const columnMiddle = (...);
const columnRight = ();

return (
<PaperPage
columnLeft={columnLeft}
columnMiddle={columnMiddle}
columnRight={columnRight}
/>
);

}
}

And the PaperPage Component:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class PaperPage extends React.Component {
render(){
return (
<div className="paper-page">
<div className="column column-left">
{this.props.columnLeft}
</div>
<div className="column column-middle">
{this.props.columnMiddle}
</div>
<div className="column column-right">
{this.props.columnRight}
</div>
</div>
);
}
}

Responsive Layout Example

The project here demonstrates basic elements of a Responsive Design Layout as a reference.

It follows the mobile first approach. For small screens all columns are displayed on their own lines.
As the width grows, they are grouped in lines, but they are also re-ordered.



See the main.css for more details.

Tricks that are used:

  • Flexbox containers
  • Column widths are expressed in relative (%) widths
  • Order can change using flex ‘order’ property.
  • After the last breakpoint the layout stays the same. We just add margins to left and right

Responsive Side Menu

This is an example of how to create a side menu, without using any framework but pure HTML/CSS/JS

Find here my full project here

In our page we define a nav section which will be our menu.

1
2
3
4
5
6
7
8
9
10
11
<body>

<nav class="menu">
<h2>Menu</h2>
<p>Click outside the menu to close it.</p>
</nav>

<main class="page-content">
<!-- Page content goes here -->
</main>
</body>

In CSS we initially set the main page content height to 100%:

1
2
3
4
5
6
7
8
9
html,
body,
main {
/* We put "main" as 100% so
* when the user clicks anywhere
* on the page, the menu closes
*/
height: 100%;
}

We also do the same for the menu

1
2
3
4
5
6
7
8
9
nav {
background-color: darkblue;
color: white;
padding: 0.5em;

height: 100%;
width: 300px;
margin: 0;
}

Then we position the menu in its normal position and hide it (initially)

1
2
3
4
5
6
7
8
9
10
11
nav {
/* We set the side menu normal position initially */
position: absolute;
left: 0;
top: 0;

/* Here we hide the side menu by positioning it off canvas */
-webkit-transform: translate(-308px, 0);
transform: translate(-300px, 0);
transition: transform 0.3s ease;
}

Then by assigning the class open to the nav menu we bring it into display

1
2
3
4
nav.open {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}

Bootstrap Starter Templates

This is a collection of starter template HTML pages with Bootstrap 4.1.1 capabilities.

Use these pages to start a new page / project. It contains the necessary references to bootstrap related files.

Find the code at the correspoding GitHub Project

Bootstrap Full

bootstrap.full.html

This is the full package that includes the Bootstrap framework and additional Javascript files required.

See Bootstrap documentation for more details.

Bootstrap Full - No popper.js

bootstrap.full.no-popper.html

This is the full package that includes the Bootstrap framework and additional Javascript files required, except for Popper.

Use this if you do not want to use:

  • Tooltips and popovers for displaying and positioning (also requires Popper.js)
  • Dropdowns for displaying and positioning (also requires Popper.js)

See Bootstrap documentation for more details.

Bootstrap Full - CSS Only

bootstrap.full.css-only.html

This is the full package that includes the Bootstrap framework - CSS file only.

Use this if you do not want to use:

  • Alerts for dismissing
  • Buttons for toggling states and checkbox/radio functionality
  • Carousel for all slide behaviors, controls, and indicators
  • Collapse for toggling visibility of content
  • Dropdowns for displaying and positioning (also requires Popper.js)
  • Modals for displaying, positioning, and scroll behavior
  • Navbar for extending our Collapse plugin to implement responsive behavior
  • Tooltips and popovers for displaying and positioning (also requires Popper.js)
  • Scrollspy for scroll behavior and navigation updates

See Bootstrap documentation for more details.

Bootstrap - Grid only

bootstrap.full.grid-only.html

Use this if you do not want to use Grid and Flexbox only capabilities:

See Bootstrap documentation for more details.

Bootstrap - Reboot only

bootstrap.full.reboot-only.html

Use this if you do not want to use the Reboot only capabilites:

See Bootstrap documentation for more details.

ngx-model Recipes

Code recipes, tips-n-tricks and more for Angular’s ngx-model.

ngx-model offers simple state management, one way data flow, multiple model support and immutable data exposed as RxJS Observable.

The following recipes build on the core ngx-model and add commonly needed functionality. It focuses on hosting model as immutable classes that have both properties and methods, and not simple objects/interfaces.

Contents:

Find the full project here: https://github.com/killerchip/ngx-model-recipes/

From Mockup Design to HTML code

Here follows a checklist / guide on how to create HTML5 code from a mockup design.

Start from here:

And finish here:

Checklist

Page Layout

  • Identify Boxes and sub-boxes
  • Position Boxes / Use Grid system
  • Put (placeholder) content

Repeat the above steps progressively per ‘level’… from outer boxes to inner boxes. (See example below).

Box Layout

  • Use a CSS normalizer
  • Identify margins & paddings
  • Identify box styles
    • background color/style
    • border color/style
  • Identify content text styles
    • Font family, weight, color, style, etc…
    • Text positioning, overflow, etc…

Details…

Please visit the Github Project: From Mockup to Code

A Simple CSS Grid system

Github project: https://github.com/killerchip/html5-cheatsheet/tree/simple-grid-framework

This is a very minimum grid system that you can apply in simple cases and you do not wish to include a full-force commercial framework.

It is using a 12-column grid.

How to use

  1. Copy the contents of my-fmw/grid.css into your project.
  2. Reference it from your HTML5 page: <link rel="stylesheet" href="grid.css">
  3. Enclose your layout in grid class so you can define a maximum width
  4. Create your rows with row class
  5. Define your colums with col-1 to col-11 classes

Example

home.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<!DOCTYPE html>

<!--
Demo page that demonstrates the use of a simple Grid framework.
-->

<html lang="en">

<head>
<meta charset="utf-8">
<title>Grid test</title>
<!-- This is the actual grid imported -->
<link rel="stylesheet" href="./my-fmw/grid.css">

<!-- Additional stylesheet to help visualize the grid system-->
<link rel="stylesheet" href="./grid-test.css">
</head>

<body>

<div class="grid">
<div class="row">
<div class="col-1">1/12</div>
<div class="col-11">11/12</div>
</div>

<div class="row">
<div class="col-2">2/12</div>
<div class="col-10">10/12</div>
</div>

<div class="row">
<div class="col-3">3/12</div>
<div class="col-9">9/12</div>
</div>

<div class="row">
<div class="col-4">4/12</div>
<div class="col-8">8/12</div>
</div>

<div class="row">
<div class="col-5">5/12</div>
<div class="col-7">7/12</div>
</div>

<div class="row">
<div class="col-6">6/12</div>
<div class="col-6">6/12</div>
</div>
</div>

</body>

</html>

Project contents

grid.css - The actual grid system file

home.html - A page demonstrating how to use the grid system

grid-test.css - Additional styles to visual the grid system demonstration