Skip to content

Snap: a small reponsive design utility

November 22, 2011

So, I’ve been reading Ethan Marcotte’s excellent book on responsive design, and I’m liking it a lot. I’ve been a big fan of fluid grids for a long time. It’s a great book, and if you can only devote a limited amount of time to the subject, go read his List Apart article to get your feet wet.

The formula Marcotte suggests as the foundational basis for responsive design: target ÷ context = result, is largely something you do inside the CSS you build for your pages. However, I would imagine there would be a few small points where you would need to calculate this in Javascript.

Snap is a very small utility that provides this, along with a way to get the aspect ratio for elements, thanks to a great little function from Stack Overflow.

Snap doesn’t do much but provide a few convenience methods to do the division necessary. It stays as small as possible by providing no ‘training wheels’…it won’t calculate styles or do DOM lookups…it assumes you’re already using a library for that. It also won’t check that you’re passing integers…it will blow up if you don’t.

The whole library is below:

Snap: a small detection utility for responsive design 
Author: Jeff Wyonch
Version: 0.0.1
Date: Monday, November 21, 2011
-- The gcd and gar functions come from a Stack Overflow page:
-- Refer to Ethan Marcotte's ALA article for the target / context = result formula for responsive design.

var Snap = Snap || {};

Snap = ( function() {

	// private methods

	// get common divisor
	gcd = function( a, b ) {
		return ( b == 0 ) ? a : gcd( b, a % b );

	// public methods

	return {

		// get aspect ratio
		gar : function( w, h ) {
			var width = w || screen.width,
				 height = h || screen.height,
				 divisor = gcd( width, height ),
				 ratio = width / divisor + ":" + height / divisor;
				return ratio;

		// get type in ems
		gem : function( a, b ) {
			return a / b;

		// get width in percentage
		gpx : function( a, b ) {
			return a / b * 100;


// end module

And here’s the minified src:

/* Snap.js, by Jeff Wyonch. V 0.0.1 */
var Snap=Snap||{};Snap=(function(){gcd=function(a,b){return(b==0)?a:gcd(b,a%b)};return{gar:function(w,h){var a=w||screen.width,height=h||screen.height,divisor=gcd(a,height),ratio=a/divisor+":"+height/divisor;return ratio},gem:function(a,b){return a/b},gpx:function(a,b){return a/b*100},}}());

There are 3 public methods:

This is the get aspect ratio function. The arguments are the width and height in pixels you want calculated, and the return is a string in the “x:y” format. If no arguments are supplied, it calculates the screen dimensions.
Get ems. This is the division formula for calculating responsive type. It divides 2 integers and returns the result.
Get pixels, for calculating responsive layouts. It divides the 2 numbers and then multiplies by 100 to get a percentage value back. Both Snap.gem and Snap.gpx return integers, without the trailing ’em’ or ‘%’.

It comes in at about 300 bytes when minimized, which is as small as I can currently make it.

Integrating this into an existing library should be no work at all. The functions are very simple, and are decoupled with the exception of the Snap.gar function, which relies on Snap.gcd. Changing Snap to any other namespace only requires a quick search-and-replace.

Yeah. I know. There’s not much here. I started this thinking there would be some inspiration, and then the lib would really take off. But, there wasn’t. Maybe in the future, as more people work out problems with responsive design, this will be more than a few small functions.


I’ve found that when you use the browser to scale type the get aspect ratio function ceases to provide meaningful numbers for screen.width and screen.height, but if you access those values directly through the console they also seem to be screwed up. I’m not sure if there’s anything that can be done about it.

Obviously there is no error checking. If you pass a value with ‘px’ attached to the end, it will blow up.

There is currently no facility for rounding really large or recurring fractions, either. According to Ethan Marcotte, the defaults you get out of a standard calculator shouldn’t be messed with, anyway.

Let me know how it goes

I don’t really know what else to put in this little ditty right now. While it doesn’t seem complete, I’m not yet sure what else to do with it. It’s really meant as a handy extra to do calculations and provide numbers for others scripts, similar to a user-agent sniffer, but for widths, heights, aspect ratios and such.

If you see something else that should be there, let me know.

No comments yet

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: