Help kids play like we used to play

A good friend of mine, , and a group of his friends are running a Kickstarter campaign to provide NYC kids with an open, free and creative playground environment, aptly called play:ground.

Please watch their video and consider contributing to their project.

I had an entire world around me like play:ground as a child, and I know that it had a lot to do with my enthusiasm for creating and willingness to explore new possibilities and options. Let’s try to give more kids that opportunity!

Thanks for any help you can offer Alex, his friends, and the kids that will benefit from play:ground. In the end, we all benefit from more creative, open-minded children becoming more creative, open-minded adults…

Happy playing to you all!

Atg

How to use dynamic variables in a Grunt config file

I had an issue the other day where I needed my Gruntfile.js to “know” what environment I was deploying to so it could use choose the correct parameter values.

Specifically, my Critical CSS Task needed to know whether it should use my Local, Dev, or Prod server to determine what CSS is critical.

TL;DR

Adding this to my Gruntfile.js…

grunt.config('environment', (function(){
    var env = grunt.option('env') || 'local',
        domain;
    if (grunt.option('env') === 'prod') {
        domain = 'http://www.netbiscuits.com/';
    } else if (grunt.option('env') === 'dev') {
        domain = 'http://dev.www.netbiscuits.com/';
    } else {
        domain = 'http://netbiscuits-com:1234/';
    }
    return domain;
})());

… allows me to pass the environment to Grunt via the command line, like this…

grunt --env=dev

… and then tell my Critical CSS Task which environment I am deploying to, like this…

criticalcss : {
    'home' : {
        options:  {
            outputfile : 'css/critical/home.css',
            filename : 'css/style.min.css',
            url : grunt.config('environment')
        }
    },

Say What?

Okay, let’s break that down a bit…

Starting at the Start

Starting with the second block of code above, because that’s how the code actually flows:

grunt --env=dev

This is how you tell Grunt to get off its lazy butt and get to work. This can happen via command line, or, in the case of this project, via command line locally, but via DeployBot for Dev and Prod.

Typically you would start Grunt by simply typing grunt and hitting Enter. You might also be familiar with something like grunt svgmin which will start Grunt, but only run the svgmin Task. But in our case we’re adding this --env=dev at the end…

What’s happening here is we are essentially passing a variable called env and setting a value to that variable, and in the above case that value is dev.

Retrieving the Option

Next, we jump to the first code block from above:

grunt.config('environment', (function(){
    var env = grunt.option('env') || 'local',
        domain;
    if (grunt.option('env') === 'prod') {
        domain = 'http://www.example.com/';
    } else if (grunt.option('env') === 'dev') {
        domain = 'http://dev.example.com/';
    } else {
        domain = 'http://www.example.local/';
    }
    return domain;
})());

This gets inserted just after the opening:

module.exports = function (grunt) { ...

So what’s happening?

  1. The first line creates a new Grunt config variable, called environment, and sets, as the value of that variable, a SIAF.
  2. The SIAF checks to see if any command line options were passed along with the grunt command, specifically if there was one called env (grunt.option('env')).
  3. If the env option was passed, it’s value is set as a local variable (also called env); if not, it’s value is set as local (thus giving us a default, so I don’t have to pass the option when working locally!).
  4. The function then checks a couple possible values of the env variable, specifically prod and dev, setting the appropriate value for the domain variable, and again, defaulting to local.
  5. And finally returns the value of domain, thus setting the value of the Grunt config variable environment.

Putting it into Play

Finally, we make use of the env variable by sending it to the Critical CSS Task:

criticalcss : {
    'home' : {
        options:  {
            outputfile : 'css/critical/home.css',
            filename : 'css/style.min.css',
            url : grunt.config('environment')
        }
    },

This is pretty standard Critical CSS stuff here, except for the url parameter value, which is set using grunt.config('environment').

This grabs whatever value we set in that environment config variable and passes it to the Critical CSS Task.

All the Options

So, for my three environments, I use one of these Grunt commands to get the correct Critical CSS for my site:

  1. Local: grunt
  2. Dev: grunt --env=dev
  3. Prod: grunt --env=prod

Again, local is the default, so no options need to be passed there, making local development, where I manually start Grunt, the easiest. And Dev and Prod are both DeployBot-driven, so I just paste that command into the configuration page and save it.

Summation

This kind of dynamic variable passing could be really useful for all kinds of situations, including testing new methods or trying any different parameter values really easily, without having to keep editing and saving your Gruntfile.js.

Happy Grunting,
Atg

Today’s Readings

The other day a co-worker shared the link for okayNav, and I have to agree: although dependent on jQuery, it certainly is one of the “okayest responsive navigation” menus I have seen…

walks us through properly using ARIA roles and writing more accessible markup.

And takes us on a nuts-to-bolts tour of HTTP/2, from an explanation and brief history, through the pros and cons, to how to make the switch.

created some very slick-looking CSS borders. This is what happens when you need more box-shadow

A few quick tips on adding, styling, and protecting the appearance of telephone links on your sites.

Gutenberg – A Meaningful Web Typography Starter Kit

Looks pretty well thought-out…

But if you’d prefer the DIY approach, A Responsive Guide to Type Sizing may be more your speed…

react-native-nw-react-calculator let’s you use one code source to create apps that work as an iOS app, Android app, desktop app, and in a browser. Wow.

If you too have reservations over Google’s AMP Project, maybe CPP will look a little better?

And finally, whether you like AMP or not, you have to like Google’s proposed HTTP header, save-data, which developers can look for to send “lighter”, and thus faster, experiences to users that have activated the Save Data feature…

Happy reading,
Atg

Today’s Readings

Great (albeit simple, which is actually part of what makes it great!) example of sort-order progressive enhancement from , starting with select elements and enhancing with nifty drag-and-drop functionality, while still using the update process from the non-drag-and-drop version…

You may already be familiar with appendChild and insertBefore, but wants to help you also get familiar with insertAdjacentHTML. Thank you Dudley, quite handy!

Not sure how many Vim users there are out there, but hopefully these 10 Time-Saving Tips for UNIX Vim Beginners will help you, even if you are not a beginner anymore…

Don’t know about you, but one of my biggest gripes with Bootstrap is all the damned floats… Yeah, I know they are a really solid way to create layouts, but they feel so old to me… I mean, Flexbox has some pretty amazing support now-days… So Bulma, the CSS framework based on Flexbox looks very enticing to me.

And speaking of Flexbox frameworks, Flexo is a 100% CSS, Flexbox grid system! (Hopefully 12 columns is enough for you and your projects…)

Okay, here is just a bunch more Flexbox stuff from Smashing Magazine, you go read… ;-)

The future of loading CSS by demonstrates a progressive approach to page rendering, allowing for improved perceived page load speeds, and pretty ideally designed for modular design & development…

Then here is an interesting follow-up from Jake. As Jake says, not practical, and probably shouldn’t even be done, but it’s always interesting to push envelopes and see how various options affect things.

Service Worker Precache is a module for generating a service worker that precaches resources. The module is designed for use with gulp or grunt build scripts, though it also provides a command-line interface. The module’s API provides methods for creating a service worker and saving the resulting code to a file.

Very powerful!

Gotta do HTML emails? Sorry sod… But maybe this Responsive HTML email framework will help! Great-looking boilerplate.

Or this Responsive Emails without Media Queries article!

Boy did this site performance article send me down a rabbit hole… Into Ilya’s presentation, into my repo, onto my dev server, and finally this site makes fair use of rel-prefetch. :-) My Analytics, at least for now, says that preconnect, prefetch, and prerender don’t make much sense for me, but it is something I will keep an eye on!

And finally, beyond the wonderful lampooning of such an aggressively arrogant buffoon, trumpdonald.org is a wonderful technical achievement!

Happy reading,
Atg

Today’s Readings

For better or worse, Google’s AMP project is out there now, and as long as it is a thing, then hearing the news that WordPress is AMP-ready, is for the better…

And since we’re already drinking the WordPress Kool-Aid, let’s take a run through “just a few” WPMU DEV posts on how to set-up, tighten, and customize, a WordPress project:

And since we’re already drinking the Build Tool Kool-Aid, let’s have a look at 6 PostCSS plugins for Developers.

And once you’ve got your CSS all nicely modernized, make sure it is as lean as it can be by running it through TestMyCSS. Does a nice job of picking up long selectors, duplicate statements, duplicate selectors, and more! Does not do such a nice job of fetching CSS files from HTTPS, and I don’t see an “upload” option. Bummer, but still a great tool!

And if you’d like, here are a few more CSS tips and tricks, via a very cute delivery method…

Several great options for implementing automatic art-directed cropping for responsive images.

Three more death-blows to Flash…

  1. as the New York Times switches from Flash to HTML5 video players,
  2. media-delivery powerhouse Brightcove switches from Flash to HTML5, and
  3. some company called Google promises to stop running Flash display ads in 2017!

And with the continuing demise of Flash, let us remember that another aging comrade-in-arms is also soon dying: IE. And with that death will come much suddenly-superfluous code… But how to even start that clean-up? Fret not, as SitePoint is here to help with a few post-IE spring cleaning tips!

From The Paciello Group, comes a short note on the use of alt="" and the title attribute on img elements. TL;DR: Use alt, who cares about title?

One more from The Paciello Group, and one more regarding accessibility, here are a few basic screen reader commands for accessibility testing. You know, like we all do, right?

Okay, one more accessibility item, though really more of a browser/testing/support item, is this page of HTML5 elements, all with minimal styling, meant to help with cross-device support testing, as well as a single document to test your new CSS on.

If you’re looking at add a CSP security header to a project, getting the options just right can be a bit of a task, leaving you with either security holes or content/functionality breaking. So let walk you through fine-tuning your CSP header.

And finally, I think someone (read: Not it!) should convert this list of untranslatable words into a Lorem Ipsum-style content generator… :-)

Happy reading,
Atg