html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}h1{font-size:2em;margin:.67em0}img{border:0}button{color:inherit;font:inherit;margin:0}button{overflow:visible}button{text-transform:none}button{-webkit-appearance:button}button::-moz-focus-inner{border:0;padding:0}html{box-sizing:border-box;height:100%}*,:after,:before{box-sizing:inherit}body{background:#999;font-family:arial;height:100%;padding:0}h1{color:red}.container{max-width:800px;height:100%;background:#fff;margin:0auto}.container:after{content:"";display:table;clear:both}img{width:80%}.left,.right{float:left;height:100%}.left{width:70%;background:#ff69b4}.right{background:pink;width:30%}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}h1{font-size:2em;margin:.67em0}img{border:0}button{color:inherit;font:inherit;margin:0}button{overflow:visible}button{text-transform:none}button{-webkit-appearance:button}button::-moz-focus-inner{border:0;padding:0}html{box-sizing:border-box;height:100%}*,:after,:before{box-sizing:inherit}body{background:#999;font-family:arial;height:100%;padding:0}h1{color:red}.container{max-width:800px;height:100%;background:#fff;margin:0auto}.container:after{content:"";display:table;clear:both}img{width:80%}.left,.right{float:left;height:100%}.left{width:70%;background:#ff69b4}.right{background:pink;width:30%}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}h1{font-size:2em;margin:.67em0}img{border:0}button{color:inherit;font:inherit;margin:0}button{overflow:visible}button{text-transform:none}button{-webkit-appearance:button}button::-moz-focus-inner{border:0;padding:0}html{box-sizing:border-box;height:100%}*,:after,:before{box-sizing:inherit}body{background:#999;font-family:arial;height:100%;padding:0}h1{color:red}.container{max-width:800px;height:100%;background:#fff;margin:0auto}.container:after{content:"";display:table;clear:both}img{width:80%}.left,.right{float:left;height:100%}.left{width:70%;background:#ff69b4}.right{background:pink;width:30%}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}h1{font-size:2em;margin:.67em0}img{border:0}button{color:inherit;font:inherit;margin:0}button{overflow:visible}button{text-transform:none}button{-webkit-appearance:button}button::-moz-focus-inner{border:0;padding:0}html{box-sizing:border-box;height:100%}*,:after,:before{box-sizing:inherit}body{background:#999;font-family:arial;height:100%;padding:0}h1{color:red}.container{max-width:800px;height:100%;background:#fff;margin:0auto}.container:after{content:"";display:table;clear:both}img{width:80%}.left,.right{float:left;height:100%}.left{width:70%;background:#ff69b4}.right{background:pink;width:30%}
BoxTent

a frontend workflow

Download on GitHub
BoxTent illustration

overview

introduction

The plastic table-like item found in the middle of a pizza box is called a box tent and was patented in 1983. Many people in the biz now call it a pizza saver.

BoxTent is a frontend workflow that gives you the infrastructure to build your next website prescribing web development best practices to deliver a state of the art product to your users. With the help of Grunt and Bower, BoxTent automates your workflow and takes care of assets optimization, concatenation, minification and much more. BoxTent includes out of the box support for:

  • Sass (.scss) compilation
  • Images optimization and compression
  • .js concatenation
  • .html, .css and .js minification
  • .css automatic autoprefixing
  • Browser auto-reloading and live syncing across devices
  • .html includes

BoxTent is perfect for crafting small and simple .html, .css and .js performant website (like this one) but can be easily extended to suit more complex needs as well, leaving you the time to focus on what really matters: your code.

In a world of complex frontend workflows, frameworks and tools, BoxTent tries to cover all the basic needs of frontend developing, without over complicating your life. Not all websites need super complex setups, but all websites deserve to be created with performance in mind, using modern tools and with an infrastructure that grants speed and productivity.

what's in the box

BoxTent is presented as a blank canvas, not a framework. It promotes a defined workflow and comes with a very basic HTML5 template, a folder structure and some starting files to work with. All you need to do is download or fork the repository from github and install the necessary dependencies to start coding right away. You are the one in control of the technology, the plugins and the frameworks you want to use for your project.

This website is both the BoxTent official documentation and an example of its usage. If you have any doubt, be sure to check its source code on github.

installation

Requirements

BoxTent is based on Grunt for tasks automation, Bower for javascript libraries management and GIT. Get ready by installing the following items before continuing:

  • Node.js: use the installer provided on the NodeJS website.
  • Grunt: install grunt by typing npm install -g grunt-cli in the terminal.
  • Bower: install bower by typing npm install -g bower in the terminal.
  • GIT: download it on the GIT official website. GIT is needed to download libraries via Bower.

For Windows users, Ruby must be installed as well. You can find instructions here: http://jekyll-windows.juthilo.com/1-ruby-and-devkit/. This website is about installing Jekyll, but the installation principles are the same.

You can now clone or download the BoxTent repository on your machine and start by installing all default dependencies and gems to have it working.

Dependencies

gems

To support Sass, install it typing gem install sass

dependencies

To install the default BoxTent dependencies, cd to the root of the cloned repository and type npm install and then bower install.

Don't mind the deprecation warnings while installing the dependencies.
BoxTent comes with jquery 3.0.0 by default. Type bower uninstall jquery --save-dev and then bower install jquery x.y.z --save-dev to get a version of jQuery of your choosing.

Run BoxTent

Now that you have it all installed, cd to the root of the project and type grunt, browse to localhost:3000 and.. start coding! It is suggested to open two terminal windows (with GIT support) while working: one will be busy watching for changes and live reloading the browser for you, the other will be useful for downloading assets via bower on the go, to perform manual grunt tasks or to push your commits online.

If BrowerSync external url doesn't work for you, check this out: https://github.com/shakyShane/dev-ip

Folder Structure

BoxTent is based on three levels and is divided in 3 main folders:

  • _src: this is your source code, this is where you work
  • _dev: is the code you see on localhost:3000
  • _site: the final website to upload in production

You always work on _src and never edit anything on _dev or _site.

_dev is the result of low-level automations such as sass compilation, autoprefixing, browser reloading and generally tasks suited for development. At this stage, your website will be easy to debug and not perfectly optimized. The _site folder instead, will be fully optimized with performance in mind. This is the code that will go live in production.

If you don’t like the naming of the folders, you can change it and then edit the path variables in the gruntfile.js:

grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    //path variables
    source: '_src',
    dev: '_dev',
    site: '_site',
    ...

the development stage

While working on the source folder, there is a series of automations performed to help you build your website in a fast and smart way that suits development and debugging.

CSS [grunt sass]

.scss files are compiled and autoprefixed in_dev/css/main.css.

In case you want to use other sass plugins, just install the gems and update your gruntfile accordingly. For example, if you decide to use Susy as your grid system, in the terminal type gem install susy, then @import "susy"; on top of the main.scss file and edit your gruntfile like this:

sass: {
        dist: {
            options: {
                require: 'susy'
                ...

Autoprefixing is dynamic and configurable in the gruntfile. To read about configuration options and more click here.

Remember to update the autoprefixer configuration of both the postcss:dev and postcss:build task!

Fonts [grunt copy:the_fonts]

If you are using custom fonts, create a folder named fonts in the root of _src, then open the terminal and type grunt copy:the_fonts to move them in _dev. If you are using Google Fonts instead, you should load them asynchronously using webfontloader. You can look at the source code of this website to see how it is implemented.

HTML [grunt processhtml:dev]

During development, .html files are processed in _dev thanks to the processhtml:dev task processing _includes. You can find some default includes in the _includes folder.

_includes are not watched, so if you edit an include, be sure to go back to the page where it is included and hit save to see the changes.
The workflow breaks if you don’t use includes, so you must use at least one. Using includes is highly suggested as it unclutters the main .html files.

Image assets [grunt imagemin]

Save your image assets in the _src/images folder. They will be optimized and compressed in _dev/images/. Supported file formats include .gif, .jpg, .png and .svg.

If you start with a empty images folder, imagemin may not detect the first image. If you add your first image and nothing happens, type grunt imagemin manually. From now on, all new images added should be detected by the watch task and compressed automatically.

Favicons [grunt copy:favicons]

Favicons are important, and being compatible with all different types of browser and platform has become a difficult task (read more about how crazy this has become). I highly suggest using http://realfavicongenerator.net/ to automatically create all the needed favicons formats for maximum compatibility. Create a folder named favicons in _src/images and drop them there (be sure grunt is running and watching): imagemin will move most of the files in _dev automatically. Not all files are image formats though, so to move the rest of the files as well, type grunt copy:favicons on your terminal. Don’t forget to paste the generated code provided by http://realfavicongenerator.net/ in <head>. Be sure to check the paths and you’re good to go.

Javascript [grunt copy:bower]

Javascript libraries and plugins are managed via Bower, so if you need any, please install them with Bower. Most of the popular plugins are indexed and searchable in the Bower search page. If you can’t find it there or if you are unsure of its name, you can look for a reference in the plugin’s website. Installing a library with Bower is done by typing bower install name-of-the-library –-save-dev in the terminal: this will download the repository of the library in the bower_components folder and will automatically update the bower.json file with the name and version of the dependency.

When the library is installed, browse to the unminified file of the .js library you just downloaded in the bower_components folder and update the copy:bower and the concat:dist tasks in the gruntfile with the right path to the unminified file of the library.

Also include the script in the _includes/scripts.html file, wrapping them in processhtml special comments. Now type grunt copy:bower and you are good to go.

If the library you need is not installable with Bower, save the file in _src/js/custom and make sure that grunt is running so the watch task will copy the file in _dev. Even in this case, don’t forget to update the concat:dist task in the gruntfile with the path to the library and the _includes/scripts.html file as well.

To write custom javascript and write your init functions, use _src/js/custom/main.js. If you need more files, just create and use them in _src/js/custom/.

the build stage

overview

When you decide to push your code to production, type grunt build in the terminal to build the _site package. There’s an additional layer of automations that will transform your development codebase in a more performant one suited for production. Here is what happens when you type grunt build.

Clean [grunt clean]

The _site folder is completely wiped out, ready to be rebuilt.

Delete Sync [grunt delete_sync]

The delete_sync task checks for unmatched files between _dev and _src. If extra files are present, they are deleted to keep both folders clean and in sync. This applies only for .html and images files.

This is a dangerous task as this may delete important files, remove this task or edit it if needed.

CSS [grunt copy:css_build && grunt postcss:build]

main.css is minified and optimized by cssnano, a PostCSS plugin.

cssnano optimization can be pretty aggressive, if your _site doesn't look as expected, it may be cssnano's fault so be sure to check http://cssnano.co/ for optimization options.

HTML [grunt htmlmin]

All .html files are minified.

Be sure your HTML doesn't rely on non-breaking space: &nbsp;. htmlmin will strip that off.

Image assets and Fonts [grunt copy:images && grunt copy:fonts_build]

The already optimized images folder is automatically copied from _dev as well as the fonts folder (if present).

Javascript [grunt processhtml:build && grunt concat && grunt uglify]

All of your javascript assets are concatenated in a single file called production.js, which is then minified becoming production.min.js. All the single scripts lines you previously had in _scripts.html are automatically transformed in a single script path that points to the minified and concatenated file.

more

credits

The real stars of BoxTent are the Grunt plugins used in this project that were created by the web community. If you want to know more and dig deeper into each plugin, here's a list of what's under Boxtent's hood:

Special thanks to Gianzo from Ohmyboot clothing for the cool BoxTent illustration.

disclaimer

Boxtent was "assembled" by Valerio Pierbattista and it was born as a starter kit for personal projects. I decided to shape it, open-source it and create a documentation website mainly for fun, but also to let others use it and collect some feedback. And yes, I am aware of Yeoman and its thousands of generators and I'm sure that it would be the first choice of most, but hey ... whatever ;)

BoxTent was tested mainly on one page websites, it is maintained by me and it is frequently updated with bug fixes, so consider this before using it. However, Boxtent is made to be a starter kit, therefore extending, adding or removing features should be pretty easy to do.

Fork or clone Boxtent from GitHub and start coding now!