Fast color helpers with SASS Lists

Yep, it’s that time of the week again. Time for more insanely optimized helper classes in SASS.

Let’s talk about colors. So, say you have a list of color variables:

1
2
3
4
5
6
7
8
$blue:      #0ab0ed;
$blue-dark: #0064cd;
$green:     #8da1ae;
$red:       #f06338;
$yellow:    #e7dfb1;
$orange:    #f89406;
$pink:      #c3325f;
$purple:    #7a43b6;

You probably want some helper classes to pepper through your code, like .color-blue or .bg-blue. Fortunately, with SASS lists, this process is almost as easy as typing out the variables in the first place.

Set up a list:
variables_and_overrides.scss
1
2
3
4
5
6
7
8
9
10
$colors: (
  $blue blue,
  $blue-dark blue-dark,
  $green green,
  $red red,
  $yellow yellow,
  $orange orange,
  $pink pink,
  $purple purple
  );

Simple enough, right? Okay, now let’s set up our mixins.

Set up some mixins using interpolation and nth:
variables_and_overrides.scss
1
2
3
4
5
6
7
8
9
10
11
12
13
@mixin generate-colors() {
  @each $color in $colors {
    .color-#{nth($color, 2)} {
      color: nth($color, 1);
    }
    .bg-#{nth($color, 2)} {
      background: nth($color, 1);
    }
    .border-#{nth($color, 2)} {
      border-color: nth($color, 1);
    }
  }
}
Call your mixin:
variables_and_overrides.scss
1
@include generate-colors();
Lust at the beautiful helpers at your fingertips:
application.css
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
.color-blue {
  color: #0ab0ed; }

.bg-blue {
  background: #0ab0ed; }

.border-blue {
  border-color: #0ab0ed; }

.color-blue-dark {
  color: #0064cd; }

.bg-blue-dark {
  background: #0064cd; }

.border-blue-dark {
  border-color: #0064cd; }

.color-green {
  color: #8da1ae; }

.bg-green {
  background: #8da1ae; }

.border-green {
  border-color: #8da1ae; }

.color-red {
  color: #f06338; }
...
Side note on speed:

If you aren’t using it yet, I really encourage you to start using gulp-sass, which is built ontop of node-sass right now.

File saves are often under 200ms, which is practically instant; and you can get away with doing some pretty insane loops and code generation really quickly and easily. I’m working on a few Rails projects and plan on continuing to use this process instead of the native Rails SASS simply because the speed is extraordinary.

Rapid Development with Sublime Text

If you scan the posts in my blog, you’ll quickly see they all have one thing in common: Speed. I like to learn things that help me move quickly for two reasons: I get to ship more code (service more Clients) and I get to learn more things. Win win.

One thing I spend every few months or so going through is my Sublime Text workflow.

This is an old feature, but man oh man did it help save a lot of time this week. If you’re like me, you’re probably jumping through a lot of files trying to find Class definitons, variables, and the like.

Goto -> Goto Symbol in Project can help with that, especially with namedspaced top level classes.

At the same time, this is all great, but by default it will search everything, which is bad. If you’re using CoffeeScript, you probably don’t want to hit all of your .js files, and the same goes for CSS preprocessors.

Sublime Project Settings for the win!

Hit the Project menu and go to Save Project As.... Then, hit Edit Project in the same menu, and add something like this:

my_project.sublime-project
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
  "folders": [{
    "file_exclude_patterns": [
      ".gitignore"
      "apps/**/*.js",
      "dist/js/**/*.js",
      "dist/js/*.js",
      "dist/stylesheets/*.css"
    ],
    "folder_exclude_patterns": [
      "assets/components",
      "gulp",
      "docs",
      "dist/build"
    ],
    "follow_symlinks": true,
    "path": "src"
  }]
}

Boom. All those nasty artifact files are completely ignored from the listing. You can exclude entire directories, just files, or as you can see hear use patterns to define files to ignore.

Overall performance, file indexing, and searching across your codebase is also vastly improved with this. I haven’t even taken it to the level I want to yet (there are a few more patterns I’d like to add), but this is a huge step in the right direction.

The cool thing here is, as you write rules and save this file, it’ll automatically refresh your folder list. So, you can temporarily and quickly add a folder pattern back into the view and not worry about reopening the project or relaunching Sublime.

I’m way behind the ball with this feature, I know, but hey, give me some credit that I’ve made it this long without finding a building to jump off of. Good day!

Speeding Up WordPress, Advanced Custom Fields, and more with helper functions

I don’t particularly love working in WordPress, because at this point I feel everything I’ve ever needed to do, I’ve done many times before. I’ve just seen about everything imagineable when it comes to WordPress development, and until tonight thought it was mostly a cut and run kind of deal.

With a recent project I’ve been focusing on really, really optimizing and elegantly developing my theme using DRY code. It’s been an admittedly fun process seeing my templates completely dry up, and while PHP is often messy (it’s official, I now hate semicolons, by the way) it has saved me quite a bit of time rolling boilerplate code.

I’m using the awesome Advanced Custom Fields plugin, which I have to give credit to Elliot Condon for. He’s really made a powerful system that in my opinion is one of the best open-sourced CMS platforms I’ve ever seen. It’s quite incredible what you can do with it now, really.

Here are a few examples of tricky things I’ve integrated into my theme that have helped save tons of time:

Button helper:

Outputs a quick button with optional internal page-link or external options. That there saved me 10 lines of boilerplate code.

page-home.php
1
<?php _s_custom_field_link('btn btn-primary'); ?>
functions-custom.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
 * custom field link helper
 * @param  string $className
 *         add a custom class name to element
 * @return string
 *         returns button text for view.
 */
function _s_custom_field_link($className) {
  $text = get_sub_field('button_text');
  if (!$className) {
    $className = 'btn btn-primary';
  }
  if (get_sub_field('external_button_link')) {
    // external link stuff
    $link = get_sub_field('external_button_link');
  } else {
    $link = get_sub_field('button_link');
  }
  // echo "<a href="$link">$text</a>";
  echo "<a class='$className' href='$link'>$text</a>";
}
Field conditional

Or take this for example, which I’ve found I do a lot. Say I want to have a field displayed, wrapped in an HTML tag, only if it’s present. And I want to avoid writing get_field vs. get_sub_field every time:

page-home.php
1
<?php _s_custom_field('title', 'h2', 'title', true); ?>
functions.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function _s_custom_field($name, $tag, $class = '', $subField = false) {
  if ($subField) {
    $function = get_sub_field;
  } else {
    $function = get_field;
  }
  if ($function($name)) {
    $str = '';
    $str .= "<{$tag} class='{$class}'>";
    $str .= $function($name);
    $str .= "</{$tag}>";
    echo $str;
  }
}

Link conditional, magic.

Grid wrappers

..or, avoid the semi-annoying Bootstrap grid wrappers:

page-home.php
1
2
3
<?php _s_grid_wrapper_start('col-md-6', true, 'hero'); ?>
  <h2>Hi, I am inside the <code>.col-md-6</code></h2>
<?php _s_grid_wrapper_end(); ?>
functions.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function _s_grid_wrapper_start($className = "col-md-12", $container = true, $containerClassName = "") {
  if ($container) {
    echo "<div class='container'>";
  }
  echo "<div class='row'>"
  ."<div class='$className'>";
}
// grid wrapper end
function _s_grid_wrapper_end($container = true) {
  echo "</div> <!-- .col- -->"
  ."</div> <!-- .row -->";
  if ($container) {
    echo "</div> <!-- .container -->";
  }
}

Voila, grid-ified:

1
2
3
4
5
6
7
<div class="container hero">
  <div class="row">
    <div class="col-md-6">
      <h2>Hi, I am inside the <code>.col-md-6</code></h2>
    </div>
  </div>
</div>

Just a few examples of using functions.php to help me cut up on writing code over and over again.

Side note: While working on this, I had an idea that would make it even more smooth. I’d love to see someone using Gulp and with a bleeding edge mentality develop a boilerplate theme using JADE templates or the otherwise. Any takers? Anyone out there trying to write advanced themes using WordPress?

Converting Gulp into Coffee

I originally wrote all of my Gulp stuff using vanilla Javascript for one reason, and that was because from what I had seen, it was somewhat annoying to use Gulp with CoffeeScript, at least out of box.

I had a friend show me a way to easily integrate CoffeeScript into Gulp, and I’m not looking back.

If you didn’t notice before, I use a modular approach to organizing my Gulp, so I have quite a few JS files to convert. Needless to say, I didn’t want to have to do it manually, so I found some tools to help automate.

Here’s how quickly you can do it:

1) Install JS2Coffee.

shell
1
npm install -g js2coffee

2) Install this awesome script to convert all of your Javascript into Coffee recursively within a directory.

shell
1
2
3
$ touch /usr/local/bin/all2coffee
$ vim /usr/local/bin/all2coffee
# (...insert code and save file, and set permissions)

3) Convert all of your Javascript files and Gulpfile into CoffeeScript, then remove all the JS.

shell
1
2
3
$ cd gulp/
$ all2coffee
$ rm -rf **/*.js

4) Add a simple Gulpfile.js with this in it:

gulpfile.js
1
2
require('coffee-script/register');
require('./gulpfile.coffee');

You should be good to go!

Generating Style Guides with KSS

Documenting style will always be a challenge. I think it’s up to you to decide the project’s balance between:

  • The need for providing clear documentation.
  • The practical use a styleguide would actually serve to the project’s stakeholders

And here’s the key one I’ve usually found a challenge on most projects:

For a style guide to be effective and worth your time,

It takes the concern and vested interest of the other developers on the team to carefully contribute to the documentation, while sticking to a set of style structure and organization.

This last one is always a problem. I’ve found that on the many projects I’ve been involved with, more often than not, the prjoect turns into a mess of tangled CSS code and rules. It doesn’t matter how well we structure the files and folders from the beginning; when push comes to shove, deadlines and pressure cause us to be messy developers. I’m guilty of it as well.

On this particular project, the team already had a style guide set up using static HTML. I knew there had to be a better way, and I found a perfect way to do it.

That’s where Knyle Style Sheets come in. The developer, Kyle Neath seems to enjoy the way Github does it and has created a nice solution to do it. It automatically parses your .scss, .less, or .css files when you write in the approrpiate syntax and generates some static HTML for you.

Unfortunately, when it comes to the grunt and node stack, it was really tricky for me to get it spinning up.

I ended up finding a winning combination: I used grunt-styleguide and this awesome template, plus a couple hacks to get it working.

I’ll leave out the entire Gruntfile. Our project compiles styles from assets/styles into the public/css/ directory.

styleguide task:
Gruntfile.coffee
1
2
3
4
5
6
7
8
9
10
11
styleguide:
  options:
    template:
      src: 'assets/vendor/styleguide-template'
    framework:
      name: 'kss'
      options:
        includeType: 'sass'
        includePath: 'public/css/application.css'
  all:
    files: ['_styleguide': 'assets/styles/**/*.scss']

assets/vendor/styleguide-template is a clone of the template repo mentioned earlier, with some minor customizations to the template.

This task generates static HTML/CSS for a styleguide into the _styleguide directory.

The tricky part was getting my styles to show up in the outputted code. Unfortuantely, though the grunt-styleguide docs say you can run precompiled code through and it will take care of the rest, no matter how hard I tried, that didn’t work.

In the end, it was just a simple matter of adding to my copy and watch tasks to copy the compiled CSS over.

watch task:
Gruntfile.coffee
1
2
3
4
5
6
7
8
9
10
11
12
watch:
  options:
    livereload: false
    spawn: false

  'sass-application':
    livereload: false
    files: [
      'assets/styles/application.scss',
      'assets/styles/**/*.scss'
    ]
    tasks: ['sass:application', 'copy:styles', 'styleguide']
copy:styles task:
Gruntfile.coffee
1
2
3
4
5
6
7
8
copy:
  styles:
    files: [
      expand: true
      cwd: 'public/css'
      src: '**/*'
      dest: '_styleguide/css'
    ]

As a bonus, add grunt-contrib-connect and have it boot up a little preview server. This was helpful on a project I was running because index.html wasn’t accessible.

Gruntfile.coffee
1
2
3
4
5
6
7
8
9
connect:
  styleguide:
    options:
      port: 9001
      base: '_styleguide'
      keepalive: true
      open:
        target: 'http://localhost:9001'
        appName: 'Google Chrome'

Pretty cool, huh? Now, in my _modules.scss file, I can add this before the code block I want to add:

_modules.scss
1
2
3
4
5
6
7
// Spacer
//
// A basic separator element to break up sections.
//
// Markup: <div class="spacer"></div>
//
// Styleguide 2.1

The kss-node project is pretty finicky, but when it works, it’s awesome. You can add modifier classes, and it will generate nice code samples and output for each of those modifier classes. You can even add markdown within your descriptions.

_modules.sass
1
2
3
4
5
6
7
8
9
10
// Alerts
//
// Indicate failure or success. <em>Required: `alert-success` or `alert-error`</em>
//
// Markup: <div class="alert {$modifiers}">You mistyped your password.</div>
//
// .alert-error - Indicate an error
// .alert-success - Indicate success
//
// Styleguide 2.2
Screenshot:

If you find things aren’t working, check to make sure you’re numbering things in the right order, that you haven’t already documented a section. I had to move a few of my sections around to match the order of the @import statements in my main .scss file.

You can pretty quickly and easily customize that template as well, if needed.

Here’s to hoping this helps our team stay on a solid set of rules and continued documentation!

Synchronous Streams with Gulp

I’ve been a huge Grunt fan for awhile now, and it wasn’t until recently that I started using an up and coming tool Gulp for my tasks.

Special thanks to Dan Tello over at Viget for his post that really inspired me to get into this.

With Gulp, it’s all about the stream, man. You use asyncronous node pipe methods to chain streams together. It’s really tricky to understand if you’re not familiar with this concept, and it took me awhile (I’m still only now just getting it as I type).

With Grunt, it’s all about configuration; with Gulp, it’s all about building your tasks dynamically. It only took me an hour or two to migrate an existing Gruntfile over to a gulpfile. Including a learning curve with a new framework, this isn’t too bad.

I won’t dive too deep into it today, but one problem I ran into was with actually getting the tasks to finish before I started another one. It seemed like a bug, until I realized what was happening:

Gulp was working so fast, one stream hadn’t finished in time for the other to occur.

Example:

A common use case for this is compiling CSS, then minifying it. Seems simple, right? With Grunt, you’d just stack the tasks together, and since Grunt runs them one at a time, you have no issues.

Gruntfile.js
1
grunt.registerTask('default', ["coffee", "stylus", "jst", "concurrent:compress", "watch"]);

With Gulp, however, it’s not quite as simple.

Just an FYI here, I’m following Dan’s model of modularizing my tasks into individual files, hence the alternate filenames in the task definitions below. If you’re going with a basic setup, these can all live in your gulpfile.

gulpfile.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
gulp.task("compile", [
  "coffee",
  "stylus"
]);

gulp.task("compress", [
  "concat_app",
  "concat_vendor",
  "uglify_vendor",
  "cssmin"
]);

gulp.task("default", [
  "compile",
  "compress",
  "watch"
]);

gulp.task("build", [
  "compile",
  "compress"
]);

This doesn’t work as you expect. If you remove all CSS files from your project and run gulp build, you’ll end up with a compiled CSS file, but no minified version. However, if you run gulp build again, you’ll get your minified version, because the CSS file is already there.

Fortunately, gulp ships with an orchestrator that allows you to essentially specify dependencies that other tasks require. These dependencies are other Gulp task definitions that return a stream.

To specify one, just add an array after you task name, as with my cssmin task below, where I’ve added ['stylus'].

Cssmin task:
cssmin.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var cssmin = require('gulp-cssmin'),
  rename = require('gulp-rename');

module.exports = function() {
  return gulp.task("cssmin", ['stylus'], function() {
    gulp.src("public/stylesheets/vendor.css")
      .pipe(cssmin())
      .pipe(rename("vendor.min.css"))
      .pipe(gulp.dest("public/stylesheets"));

    gulp.src("public/stylesheets/application.css")
      .pipe(cssmin())
      .pipe(rename("application.min.css"))
      .pipe(gulp.dest("public/stylesheets"));
  });

}
Stylus task:
stylus.js
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
var gulp = require("gulp"),
  accord = require("gulp-accord"),
  cssmin = require("gulp-minify-css"),
  rename = require("gulp-rename"),
  notify = require("gulp-notify"),
  livereload = require("gulp-livereload"),
  stylus = require('gulp-stylus');

module.exports = function() {
  gulp.task("stylus", function() {
    gulp.src("public/stylesheets/styl/application.styl")
      .pipe(stylus({
        set: [
          "resolve url",
          "include-css",
          "linenos",
          "compress"
        ]
      })).on("error", notify.onError({
        message: "<%= error.message %>",
        title: "Stylus Error"
      }))
      .pipe(gulp.dest("public/stylesheets"))
      .pipe(livereload());

    return gulp.src("public/stylesheets/styl/vendor.styl")
      .pipe(stylus({
        set: [
          "include css",
          "linenos"
        ]
      })).on("error", notify.onError({
        message: "<%= error.message %>",
        title: "Stylus Error"
      }))
      .pipe(gulp.dest("public/stylesheets"));
  });
};

Now for the tricky part. See on line 33 where I’m returning the task itself? If you omit this line, the dependency is considered resolved and will never run. This line is super important and was confusing the hell out of me for quite awhile there, so I thought I’d share in case someone else ends up confused.

Ideally, I could split this task into two separate task definitions, but for this project that was good enough. I always want my vendor to be compiled, and though it rarely changes, with Gulp the compilation was so fast it was not even noticeable without it.

That’s all for today: make sure you return that stream!

Soft Injecting CSS

This task has been changed. It’s now called grunt-browser-sync.

I am a big fan (if you haven’t noticed in my prior posts) of optimizing my workflow. One thing I’ve never found until recently was a solid way to deal with styles and a live workflow. In comes grunt-style-injector.

The task is simple.

gruntfile.coffee
1
2
3
4
5
6
styleinjector:
  files:
    src: 'css/application.css'
    options:
      watchTask: false
      debugInfo: true

You simply type in:

1
2
3
4
5
6
7
8
9
⇒ grunt styleinjector
Running "styleinjector:files" (styleinjector) task
   info  - socket.io started


All Set Up! Now copy & paste this snippet just before the closing </body> tag in your website.

<script src='http://192.168.1.113:3000/socket.io/socket.io.js'></script>
<script src='http://192.168.1.113:3001/style-injector-client.min.js'></script>

Put those snippets in your index.html (or partial of choice) and make sure you don’t commit said file, and you’re good to go. Since it’s framework agnostic, you can use whatever compilation process you want, and it never falsely reloads CSS (something I found) happened all the time with LiveReload.

Open files recursively with a Simple Grunt task.

I kicked off a project tonight and had a bunch of HTML files I wanted to open. I thought to myself, this has happened more than once, why not fire off a quick Grunt task?

Let’s get this fired off:

1
2
3
$ npm init
$ (... follow prompts)
$ npm install -g grunt-cli grunt

We’ll need a the open npm module. The other dependencies are baked into node.

1
$ npm install open --save

I decided to set up a couple basic options, to at least make it feel like a more modular task I could use elsewhere:

  • A base filename to open (in this case, index.html)
  • Firefox as the appName for the open task, so as to not bog down my Chrome windows
  • A base path to start from (in this case, just using the current path)

Here’s the finalized Gruntfile.coffee:

Gruntfile.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
open = require('open')
fs = require('fs')

module.exports = (grunt) ->
  grunt.initConfig
    openFiles:
      options:
        filename: "index.html"
        appName: "Firefox"
      path: "./"

  grunt.registerMultiTask 'openFiles', 'open', ->
    options = @options()
    basePath = @data.toString()
    files = fs.readdirSync(basePath)
    for i of files
      continue unless files.hasOwnProperty(i)
      name = basePath + files[i]
      if fs.statSync(name).isDirectory()
        open(name + "/" + options.filename, options.appName)

  grunt.registerTask("default", "openFiles")

Pretty slick. All I need to do is type grunt in the terminal, it checks to ensure what it’s trying to open is a directory, and then fires it up.

Note:

Since all of the directories were named similarly, I was able to follow a pretty standard pattern. Of course, we could set this up a little more elegantly, say, by using a conditional to make sure the files exist, a limit to how many files we want to open, etc.

This might be a one off use case, but just shows you how powerful (and easy) it can be to use Grunt to automate even more simple tasks.

Loops and Mixins in SASS and Stylus

Check out how easy this is to do with Stylus; added instructions and example at the end of this post.

The beauty of freelancing is twofold: you work on a lot of different projects simultaneously, and have to learn to quickly dive into a various set of systems at any given moment.

One challenge I run into in my work is building scalable, modular CSS, and lately I’ve been making a strong effort to write more modular code.

Here’s a pattern I ran into today. Say I want to add a simple spacer class that adds a little padding or margin on an element. I’d rather not have to do anything beyond editing the HTML markup, so let’s generate some CSS classes using a SASS @each loop.

My first take was to set up some $spaceamounts, then generate a few mixins:

helpers.scss
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
$spaceamounts: (5, 10, 15, 20, 25, 30);

@mixin generate-margin-bottom() {
  @each $space in $spaceamounts {
    .mb-#{$space} {
      margin-bottom: #{$space}px;
    }
  }
}
@mixin generate-margin-right() {
  @each $space in $spaceamounts {
    .mr-#{$space} {
      margin-right: #{$space}px;
    }
  }
}
@mixin generate-margin-top() {
  @each $space in $spaceamounts {
    .mt-#{$space} {
      margin-top: #{$space}px;
    }
  }
}
@mixin generate-padding-top() {
  @each $space in $spaceamounts {
    .pt-#{$space} {
      padding-top: #{$space}px;
    }
  }
}
@mixin generate-padding-bottom() {
  @each $space in $spaceamounts {
    .pb-#{$space} {
      padding-bottom: #{$space}px;
    }
  }
}

@include generate-margin-bottom();
@include generate-margin-right();
@include generate-margin-top();
@include generate-padding-bottom();
@include generate-padding-top();

This approach definitely works. I get some sensibly generated CSS:

application.css
1
2
3
4
5
6
7
8
9
10
11
.ml-5 {
  margin-left: 5px; }

.ml-10 {
  margin-left: 10px; }

.ml-15 {
  margin-left: 15px; }

...

But, that’s a lot of copying and pasting. How about optimizing a bit?

With the relatively new @each loop and nested array functions in SASS, you can set comma delimited lists for use in dynamic variables.

helpers.scss
1
2
3
4
5
// let's generate some CSS!
// loops through array:
// vars: amt, direction, class-suffix
$default-space-amounts-with-direction: (5 left l, 10 left l, 15 left l, 25 left l, 30 left l);

We set up a basic iteration loop, here. The goal is to generate markup that follows our pattern from above, which fortunately is fairly simple:

helpers.scss
1
2
3
4
5
6
7
8
9
10
11
12
@mixin generate-spacing-classes(
  $default-space-amounts-with-direction: (5 left l, 10 left l, 15 left l, 25 left l, 30 left l)
) {
  @each $space in $default-space-amounts-with-direction {
    .m#{nth($space, 3)}-#{nth($space, 1)} {
      margin-#{nth($space, 2)}: #{nth($space, 1)}px;
    }
  }
}

@include generate-spacing-classes();

This generates the exact same markup as before.

Boom. Now, I can add more variable array definitions and simply include a few lines to have it output for each of these loops:

helpers.scss
1
2
3
4
5
6
7
8
9
$right-space-vars: (5 right r, 10 right r, 15 right r, 25 right r, 30 right r);
$bottom-space-vars: (5 bottom b, 10 bottom b, 15 bottom b, 25 bottom b, 30 bottom b);
$top-space-vars: (5 top t, 10 top t, 15 top t, 25 top t, 30 top t);

@include generate-spacing-classes(); // left comes by default
@include generate-spacing-classes($right-space-vars);
@include generate-spacing-classes($bottom-space-vars);
@include generate-spacing-classes($top-space-vars);

Voila, we get this:

application.css
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
.ml-5 {
  margin-left: 5px; }

.ml-10 {
  margin-left: 10px; }

.ml-15 {
  margin-left: 15px; }

.ml-25 {
  margin-left: 25px; }

.ml-30 {
  margin-left: 30px; }

.mr-5 {
  margin-right: 5px; }

.mr-10 {
  margin-right: 10px; }

.mr-15 {
  margin-right: 15px; }

...
For those interested, I whipped up a little LESS version today.

It’s a little different, but loops work a little differently in LESS. You just set up an iterator, kick off the mixin itself from within the mixin, and loop through as many times as you want.

helpers.less
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.generate-margin(@n, @i: 1, @direction: bottom, @type: m, @iterator: 5) when (@i =< @n) {

  @suffix: @i*@iterator;
  .@{type}-@{direction}-@{suffix} when (@type = m) {
    margin-@{direction}: @suffix + 0px;
  }
  .@{type}-@{direction}-@{suffix} when (@type = p) {
    padding-@{direction}: @suffix + 0px;
  }
  .generate-margin(@n, (@i + 1), @direction, @type, @iterator);
}

.generate-margin(15, 1, top, m, 5);
.generate-margin(15, 1, bottom, m, 5);
.generate-margin(15, 1, bottom, p, 5);
.generate-margin(15, 1, top, p, 5);

Generates:

application.css
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
...
.m-top-40 {
  margin-top: 40px;
}
.m-top-45 {
  margin-top: 45px;
}
.m-top-50 {
  margin-top: 50px;
}
.p-bottom-5 {
  margin-bottom: 5px;
}
.p-bottom-10 {
  margin-bottom: 10px;
}
.p-bottom-15 {
  margin-bottom: 15px;
}
.p-bottom-20 {
  margin-bottom: 20px;
}
.p-bottom-25 {
  margin-bottom: 25px;
...

Bonus: Stylus

I ran into a challenge with Stylus and found it was even easier to do there:

_helpers.styl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
sizes = 5 10 15 20 25 30 35 40 45 50
for num in sizes
  .mb-{num}
    margin-bottom: unit(num, px)
  .mt-{num}
    margin-top: unit(num, px)
  .ml-{num}
    margin-left: unit(num, px)
  .mr-{num}
    margin-right: unit(num, px)
  .pb-{num}
    padding-bottom: unit(num, px)
  .pt-{num}
    padding-top: unit(num, px)
  .pl-{num}
    padding-left: unit(num, px)
  .pr-{num}
    padding-right: unit(num, px)

Boom, you can generate them all with only a few lines of code.

This entire approach follows the pattern and way I like to work is to build principles and a foundation so each project is a bit easier.

It’s kind of like climbing a mountain a little faster each time.

Hello World, I'm Using Hexo

After a long search, and coincidentally due to patience and timing, I’m finally making an effort to work on my blog. I’ve chosen a static site generator for the many other reasons out there, and so far, I have no regrets.

I chose Hexo for one thing: speed. There are a ton of options out there, no doubt, and I started working in Jekyll, which I may be regretting down the road, but I must say that the millisecond generation process and overall ease of templating using EJS tags is definitely in my arena.