Upgrading junky IE8 code with current goodies

23 May 2016 · by David DeSandro

Man, it feels good to cut out all the old junky code and live in the modern day. With new versions of Isotope, Packery, Masonry, and imagesLoaded, I've been upgrading browser support, dropping IE8 & 9, and Android <4. I've been able to remove hundreds of lines of code.

If you're looking to bump up your browser support, here's a run-down of all the code you can upgrade.

Use standard browser properties

Use addEventListener for event binding, rather than a helper like eventie.

// IE8
eventie.bind( element, 'click', function() {...});
// modern browsers
element.addEventListener( 'click', function() {...});

Use classList for changing classes, rather than a helper like classie.

// IE8
classie.add( element, 'is-selected' );
// modern browsers
element.classList.add('is-selected');

Use event.preventDefault().

// IE8
function onClick( event ) {
  if ( event.preventDefault ) {
    event.preventDefault();
  } else {
    event.returnValue = false;
  }
}
// modern browsers
function onClick( event ) {
  event.preventDefault()
}

Use window.pageYOffset for scroll position.

// IE8
var isPageOffset = window.pageYOffset !== undefined;
var scrollX = isPageOffset ? window.pageXOffset : document.body.scrollLeft;
var scrollY = isPageOffset ? window.pageYOffset : document.body.scrollTop;
// modern browsers
window.pageXOffset;
window.pageYOffset;

Use standard textContent for setting text.

// IE8
var docElem = document.documentElement;
var textSetter = docElem.textContent !== undefined ? 'textContent' : 'innerText';

function setText( elem, value ) {
  elem[ textSetter ] = value;
}

setText( element, 'hello world' );
// modern browsers
element.textContent = 'hello world';

CSS support

All browsers now support transition and transform. So I no longer need get-style-property to check vendor properties.

// IE8
// get vendor property for transform
var transformProp = getStyleProperty('transform');
// set position
if ( transformProp ) {
  // supports transform, set transform
  element.style[ transformProp ] = 'translate(40px, 30px)';
} else {
  // does not support transform, set left, top
  element.style.left = '40px';
  element.style.top = '30px';
}

Modern browsers support transform or -webkit-transform, so you don't have to check every vendor prefix.

// modern browsers
// get vendor property for transform
var docElemStyle = document.documentElement.style;
// either transform or WebkitTransform
var transformProp = typeof docElemStyle.transform == 'string' ?
  'transform' : 'WebkitTransform';
// supports transform, set transform
element.style[ transformProp ] = 'translate(40px, 30px)';

New ES5 features

Dropping IE8 and Android 2.3 means you can natively use ES5 features. There are a bunch of new ES5 features, but here are the ones I have actually used.

Array.isArray to check if an object is an array.

// ES4
var objToString = Object.prototype.toString;
function isArray( obj ) {
  return objToString.call( obj ) == '[object Array]';
};

isArray( items );
// ES5
Array.isArray( items );

Array.prototype.indexOf to get the index of a value.

// ES4
function indexOf( ary, value ) {
  for ( var i=0; i < ary.length; i++ ) {
    if ( ary[i] === value ) {
      return i;
    }
  }
  return -1;
}

indexOf( items, value );
// ES5
items.indexOf( value );

Array.prototype.forEach to iterate over an array.

// ES4
for ( var i=0; i < items.length; i++ ) {
  var item = items[i];
  console.log( item );
}
// ES5
items.forEach( function( item ) {
  console.log( item );
});

Array.prototype.filter to create a new array by filtering values.

var numbers = [ 1, 2, 3, 4, 5, 6 ];

// ES4
var evens = [];
for ( var i=0; i < numbers.length; i++ ) {
  var number = numbers[i];
  if ( number % 2 === 0 ) {
    evens.push( number )
  }
}
// ES5
var evens = numbers.filter( function( number ){
  return number % 2 === 0;
});

Array.prototype.map to create a new array by changing values.

// ES4
var doubles = [];
for ( var i=0; i < numbers.length; i++ ) {
  var number = numbers[i];
  doubles.push( number * 2 );
}
// ES5
var doubles = numbers.map( function( number ) {
  return number * 2;
});

Object.create for prototypal inheritance.

function Animal() {
  console.log('I am an animal!')
}

// ES4
Dog.prototype = new Animal();
// constructor function is triggered
// logs 'I am an animal!'
// also, weird syntax
// ES5
Dog.prototype = Object.create( Animal.prototype )
// constructor function not triggered, no console log

And there's more to play with. I've experimented with custom Object getters and setters. These are powerful concepts, but may take some getting used to.


You may have looked twice. ES Five? Isn't ES6 the new hotness?

Metafizzy's libraries are designed to have a wide, diverse user-base. While forward-leaning developers may be itching to use ES6, they still have to step through scaffolding if they want to use it widespread in production. All the above code can be used right now in every browser worth using. No build processes. No transpilers. Straight up vanilla.

Isotope v3 released: stagger in, IE8 out

5 May 2016 · by David DeSandro

Isotope v3 is Metafizzy's flagship product — the best JavaScript library for filtering and sorting dynamic layouts. It just got a whole lot better with new version 3. We dropped support for IE8 & 9, and Android 2.3. In doing so, we were able to shed 800 lines of code to make Isotope's filesize 20% smaller. We added a new option to stagger item transitions (finally).

Isotope stagger transition

Staggered transitions are a small change to animation behavior, but the result is subtly compelling. The reveal and hide animations appear more natural.

See the Pen Isotope - stagger by David DeSandro (@desandro) on CodePen.

We simplified using Isotope with Webpack. Now your webpack.config.js only requires two aliases.

module.exports = {
  resolve: {
    alias: {
      'masonry': 'masonry-layout',
      'isotope': 'isotope-layout'
    }
  }
};

Best part: Isotope v3 is backward compatible with Isotope v2. Upgrade worry free. All your previous code will continue to work: jQuery plugin, events, methods, etc.

Open-source projects rarely get to version 2. I'm proud that Isotope has made it all the way to version 3.

We've been pushing out a bunch major version upgrades to our projects in 2016: Masonry v4, imagesLoaded v3, Packery v2, now Isotope v3. Next up: Flickity v2.

Netflix Atlas logo

6 Apr 2016 · by David DeSandro

Netflix Atlas

Netflix Atlas colors

From the Netflix Atlas team:

When Netflix doesn't work, teams go to their Atlas Dashboards to find out why. Atlas supports a robust alerting system, which allows Netflix to notice problems around the world before our users do.

The logo design process started by identifying its key qualities. For Atlas, we landed on reliable, scalable, and powerful.

I took a look at other "Atlas" logo concepts on Dribbble to see how other designers approached this idea.

Dribbble Atlas logos

It was time to start sketching. 100 concepts to need to die in order for one to live :P

Netflix Atlas logo initial sketches

From all those sketches, I put together four concepts to decide which were worth pursuing.

Atlas myth logo concept

The Atlas of Greek myth directly speaks to the core qualities: reliable, powerful, and considering he has the world in his hands, scalable. Using a human figure personifies the brand, and makes it more relatable.

Rockefeller Center Atlas statue

But it's a hard to concept to pull off. It look like a shrug ¯\_(ツ)_/¯, or it could look like Christ the Redeemer. Other Atlas logo concepts on Dribbble had similar issues.

Atlas circle A concept

Just an A in a circle. But the forms can also be viewed as a figure with his/her hands upward. Like this:

So it’s one of those clever logos. The A is clear, but it has another image. I admit, it was a bit of a stretch, but I think once you see it, it’s easy to spot.

Atlas triangle starburst logo concept

Moving away from figures, this logo is the most abstract. The triangle (trapezoid, actually) represents an “A”, the starburst represents Atlas’s power and capability, as well as appearing like a cardinal coordinate legend on a map — alluding the atlases of maps and way-finding.

Atlas 3D logo A concept

Finally, something more technical and detailed. Netflix Atlas is software after all. This treatment shows Atlas a multifaceted conduit.

We settled on pursuing the myth and Circle-A concepts. I went back to the pencil and paper to iterate and pump out more sketches with these ideas.

Netflix Atlas logo sketches

The figure’s body position is tricky. It has to appear that it's lifting up a big object, but shouldn’t look overwhelmed. The globe is large, but the figure should be more prominent.

I tried variations of realistic figures versus geometric shapes. Realistic figures may be easier to see at a glance, but geometric shapes feel stronger and more iconic.

I selected a two ideas and brought them into Illustrator.

Netflix Atlas logo process

I produced these two concepts. The figure shapes are simplified, so they feel solid. The globes are large, but they don't overpower the figure. I mocked-up these logos on t-shirts and in websites to better see them in context.

Netflix Atlas logo mock-ups

The Netflix team decided on the globe-on-shoulders treatment. With that, I finalized the logo in Illustrator. Look at these beautiful vectors. Not a stray node to spare.

Netflix Atlas logo vector

$(window).load() is a last resort

25 Mar 2016 · by David DeSandro

I continue to see develpers rely on the window load event in their code. Typically it's used to run code after all images have been loaded. For example, when used with Masonry, Packery, or Isotope:

$(window).load( function() {
  $('.grid').isotope({
    // isotope options...
  });
});

Let me be clear: Don't do this.

$(window).load() should only be used as a last resort. That's because load has to wait for everything else to load. From on GlobalEventHandlers.onload MDN

The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images, scripts, links and sub-frames have finished loading.

load waits for every asset on the page to load: every image, JS file, CSS file, and iframe — plus media like audio, video, or fonts.

Rather than waiting for everything, use a smaller scoped event so you only wait for specific assets. imagesLoaded is perfect for this as it allows you to target a set of images. Your code runs as soon as the necessary images are loaded, rather than after all assets. From Isotope - imagesLoaded:

var $grid = $('.grid').imagesLoaded( function() {
  // init Isotope when grid's images have loaded
  $grid.isotope({
    // options...
  });
});

Or initialize isotope, then trigger layout as images load:

// init Isotope
var $grid = $('.grid').isotope({
  // options...
});
// layout Isotope after each image loads
$grid.imagesLoaded().progress( function() {
  $grid.isotope('layout');
});

Chances are, there's a faster way to detect what you're loading, rather than using $(window).load(). Web fonts have a loader API. <video> and <audio> have load events.

Only use load if you absolutely have to. By avoiding it, you'll be making your sites faster and me happier :)

Packery v2 released

18 Feb 2016 · by David DeSandro

Packery is our fantastic bin-packing layout library, first released 3 years ago. Packery can do something no other library can: draggable grid layouts. But Packery's dragging behavior had plenty of quirks: random movement, potential gaps. It worked, but it wasn't pretty.

So we fixed it. Dragging with Packery version 2 has been completely re-tooled.

It feels much more intuitive. Now dragged items fit to their drop position. No more random movement. Packery v2 is perfect for draggable Masonry layouts and draggable dashboards. We put together a fun drag & drop puzzle to show it off (with a prize!).

See the Pen Packery v2 puzzle by David DeSandro (@desandro) on CodePen.

What else is new? We dropped IE8 & 9 support for 25% smaller filesize, new shiftLayout method, simplified Webpack integration, and more. Plus completely refreshed docs with individualized demos and CodePens for every feature.

Already have a Packery v1 license? Keep an eye out for another email from us for a big discount to upgrade to v2.

Packery v2 is an awesome upgrade. Just one of several that will be happening in 2016. Up next: Isotope v3 and Flickity v2.

Choose Metafizzy's next project

2 Feb 2016 · by David DeSandro

Help decide what Metafizzy’s next project will be. We've opened a GitHub issue tracker where you can +1 proposals or submit your own. We've got several good ideas, but, like choosing sunglasses at the mall, we need help picking out the one.

Metafizzy's next project

Current proposals include:

Have another idea? Submit a new proposal.

Each of these projects is a worthy cause. That's why your feedback is so valuable. Your input informs how we can best spend out time on what's to come.