Skip to content

antibland/starting_point

Repository files navigation

#Starting Point

We've all been there. You're coding something when an inner voice suddenly announces, "This should be its own thing. Don't forget to pull this code out and make it its own thing." But you're busy and you don't do it.

Six months later, you're working on a new project and can't find that useful utility you once wrote. So you write it again. And again. Can we please stop recreating our greatest hits ad infinitum?

When beginning a web project, I need these things:

  1. A small, vanila JavaScript library using the module pattern
  2. Auto minification/concatenation/JavaScript linting
  3. Reusable sass mixins and placeholders
  4. A no-bullshit SVG workflow
  5. JavaScript unit testing with Jasmine
  6. An easy way to catch accessibility issues before going live

##Browser Support## IE9+, Chrome, Firefox, Opera, Safari, iOS Safari, and Android 4+.

##What's In Here?

###Typographical Vertical Rhythm###

Establishing a typographical vertical rhythm at the outset of a web project makes your content much easier to read and understand. Compass makes this pretty easy to set up and you can read more about vertical rhythm here.

###Responsive Videos and Images###

I like having a padded main content area with 100% wide images that extend beyond the padding to the viewport edges.

<main>
  <!-- A paragraph within the padded walls -->
  <p>Some text here. Some text here. Some text here. Some text here. Some text here. Some text here. Some text here. Some text here. Some text here. </p>

  <!-- This image will hug the viewport walls -->
  <div class="img-container">
    <img src="assets/sample.jpg" alt="">
  </div>

  <!-- Other stuff -->
</main>

###JavaScript Utilities###

Have you ever wanted something to happen after your CSS transition or animation ended? Yes, you can fire that second transition or animation with a delay containing the same value as the first even duration—but that's a risky venture. This is where you would use animationend and transitionend, both stored in utilities.js.

whichTransitionEvent /* returns correct vendor prefix for desired event */

You might use it like this:

var transitionend = utilities.whichTransitionEvent();

if (transitionend) { // browser supports transitionend
  container.addEventListener(transitionend, handler, false);
}

Sometimes you want to know when a user is on a touch-supported device.

isTouchDevice

A useful place for this would be to determine the type of event listener to attach to an element.

var click_touch = utilities.isTouchDevice() ? "touchstart" : "click",
    toggle_menu = document.querySelector("#toggle-menu");

toggle_menu.addEventListener(click_touch, handler, false);

###Useful Mixins###

@mixin animation($animate...)
@mixin keyframes($animationName)
@mixin remove-tap-highlight
@mixin input-placeholder
@mixin box-size-all
@mixin mobile-smooth-scroll
@mixin respond-to($breakpoint)
@mixin form($custom_args: "")
@mixin form-label($font-size: 0.75rem)
@mixin transitions-off

###Modular CSS Approach###

This just means all the CSS is broken down into partials (footer, animations, common, forms, etc.). These partials tend to make your code much easier to manage as your project grows. Footer changes go in the footer partial; new animations go in the animations partial. CSS turns out okay if you are consistent and practical.

##Grunt Tasks## Starting Point uses Grunt to handle some common, yet tedious, tasks.

###SVG Management### svgstore is a lifesaver when it comes to managing SVG icons you wish to include in a sprite sheet. All you have to do is start grunt watch from the command line and drag an SVG icon into the svg directory. svgstore will build the SVG into a sprite sheet which you can reference in an external file. Say we add an icon to the SVG folder with the filename of ribbon.svg.

Immediately, Grunt builds the file into our SVG sprite sheet, making it available within our HTML.

<a href="http://somelink.com">
  <span class="hide-text">Click the ribbon</span>
  <svg class="icon" aria-hidden="true">
    <use xlink:href="dist/dist.svg#shape-ribbon" />
  </svg>
</a>

You can then adjust the CSS styles for your SVG. It's dead simple.

###Linting### All JavaScript in Starting Point is strict and should stay that way. While Grunt is watching, it will yell at you if you break the linter rules in some way. Missing a semi-colon? Sorry—fix it. Declared a variable at the bottom of a function? Sorry—fix it. I like having the linter around to keep my code from getting ugly.

###Minification### Ruby users are likely familiar with config.rb, a file which is created for us by Compass. There, we can set a value for the variable output_style, which determines what happens each time we save a watched sass file. I always set this variable to :compressed to make my CSS file size as light as possible.

But what of our JavaScript? That should certainly be minified, too. With a few Grunt tasks, concat and uglify, this is no longer a problem—well, almost. If we instruct concat to join all files with a .js extension before uglify does the actual minification, we could have an dependency ordering problem. We need the code in utilities.js to load first, so that the its functions are available to any other code loaded after. This is why we organize our concat task in the following way:

Gruntfile.js

concat: {
  options: {
    separator: ';'
  },
  dist: {
    src: [['js/vendor/*.js'], 'js/utilities.js', 'js/main.js', 'js/demo.js'],
    dest: 'dist/<%= pkg.name %>.js'
  }
}

###Automatic Prefixing### For a long time I have used Compass to handle all my prefixing needs. If you are a Compass user, you have probably written something like this before:

@include opacity(0.8);
@include transform(translateY(0.1em) scaleX(1.1) scaleY(.9));

And, of course, this is fine, and we can trust Compass to reliably deliver us CSS. Using autoprefixer, though, we can get right to the CSS and skip the middleman.

opacity: 0.8;
transform: translateY(0.1em), scaleX(1.1), scaleY(.9);

The resulting CSS will be the same, with the necessary prefixes included for us.

##Installation##

$ git clone https://github.com/antibland/starting_point.git
$ npm install

This is an optional step. However, if you unit test your JavaScript (or want to start), definitely proceed with this step.

$ bower install jquery jasmine-jquery --save-dev

After these files are downloaded, you'll need to include them in your Gruntfile.js

jasmine: {
  src: 'dist/starting-point.js',
  options: {
    vendor: [
      'bower_components/jquery/dist/jquery.js',
      'bower_components/jasmine-jquery/lib/jasmine-jquery.js'
    ],
    specs: 'spec/**/*.js'
  }
}

You'll then be able to run tests headlessly with the following command:

$ grunt jasmine

If you're running the tests in the demo, you should see something like this:

$ grunt watch
$ compass watch

After you have the necessary modules, you'll need to run Starting Point on a server. It will work serving a local HTML index file, but accessing the SVGs in an external file cause Chrome to throw security permission errors and serve no icons. From a Mac, the easiest way to work around this is to start a simple web server:

$ python -m SimpleHTTPServer 8000

Then just go to http://localhost:8000 and you should be in business.

##Contributing##

This is a barebones thing I've cobbled together in my spare time and is by no means complete. If you have any ideas to make Starting Point better, I'd love to work with you.

##Notes##

You're cloning the entire demo, which is probably more than you need. If you look in the sass folder, you can remove the files beginning with _custom for a cleaner start and the call to demo.init() at the bottom of index.html.

##License##

MIT