<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

    <channel>
    
    <title><![CDATA[A List Apart: The Abridged Feed]]></title>
    <link>http://alistapart.com</link>
    <description>This feed delivers ALA articles, weekly columns, and other general messages.</description>
    <dc:language>en</dc:language>
    <dc:creator>The fine folks at A List Apart</dc:creator>
    <dc:rights>Copyright 2013</dc:rights>
    <dc:date>2013-05-21T12:00:20+00:00</dc:date>
    

		
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/alistapart/abridged" /><feedburner:info uri="alistapart/abridged" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
      <title><![CDATA[The Design of Code: Organizing JavaScript]]></title>
      <link>http://feedproxy.google.com/~r/alistapart/abridged/~3/x0nEW66nHaE/the-design-of-code-organizing-javascript</link>
      <guid isPermaLink="false">http://alistapart.com/article/the-design-of-code-organizing-javascript</guid>
      <description>&lt;p&gt;Great design is a product of care and attention applied to areas that matter, resulting in a useful, understandable, and hopefully beautiful user interface. But don’t be fooled into thinking that design is left only for designers.&lt;/p&gt;

&lt;p&gt;There is a lot of design in code, and I don’t mean code that builds the user interface—I mean the design &lt;em&gt;of&lt;/em&gt; code.&lt;/p&gt;

&lt;p&gt;Well-designed code is much easier to maintain, optimize, and extend, making for more efficient developers. That means more focus and energy can be spent on building great things, which makes everyone happy—users, developers, and stakeholders.&lt;/p&gt;

&lt;p&gt;There are three high-level, language-agnostic aspects to code design that are particularly important.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;System architecture—The basic layout of the codebase. Rules that govern how various components, such as models, views, and controllers, interact with each other.&lt;/li&gt;
&lt;li&gt;Maintainability—How well can the code be improved and extended?&lt;/li&gt;
&lt;li&gt;Reusability—How reusable are the application’s components? How easily can each implementation of a component be customized?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In looser languages, specifically JavaScript, it takes a bit of discipline to write well-designed code. The JavaScript environment is so forgiving that it’s easy to throw bits and pieces everywhere and still have things work. Establishing system architecture early (and sticking to it!) provides constraints to your codebase, ensuring consistency throughout.&lt;/p&gt;

&lt;p&gt;One approach I’m fond of consists of a tried-and-true software design pattern, the module pattern, whose extensible structure lends itself to a solid system architecture and a maintainable codebase. I like building modules within a jQuery plugin, which makes for beautiful reusability, provides robust options, and exposes a well-crafted API.&lt;/p&gt;

&lt;p&gt;Below, I’ll walk through how to craft your code into well-organized components that can be reused in projects to come.&lt;/p&gt;

&lt;h2&gt;The module pattern&lt;/h2&gt;

&lt;p&gt;There are a &lt;em&gt;lot&lt;/em&gt; of design patterns out there, and equally as many resources on them. &lt;a href="https://twitter.com/addyosmani"&gt;Addy Osmani&lt;/a&gt; wrote an &lt;a href="http://addyosmani.com/resources/essentialjsdesignpatterns/book/"&gt;amazing (free!) book&lt;/a&gt; on design patterns in JavaScript, which I highly recommend to developers of all levels.&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript"&gt;module pattern&lt;/a&gt; is a simple structural foundation that can help keep your code clean and organized. A “module” is just a standard object literal containing methods and properties, and that simplicity is the best thing about this pattern: even someone unfamiliar with traditional software design patterns would be able to look at the code and instantly understand how it works.&lt;/p&gt;

&lt;p&gt;In applications that use this pattern, each component gets its own distinct module. For example, to build autocomplete functionality, you’d create a module for the textfield and a module for the results list. These two modules would work together, but the textfield code wouldn’t touch the results list code, and vice versa.&lt;/p&gt;

&lt;p&gt;That decoupling of components is why the module pattern is great for building solid system architecture. Relationships within the application are well-defined; anything related to the textfield is managed by the textfield module, not strewn throughout the codebase—resulting in clear code.&lt;/p&gt;

&lt;p&gt;Another benefit of module-based organization is that it is inherently maintainable. Modules can be improved and optimized independently without affecting any other part of the application.&lt;/p&gt;

&lt;p&gt;I used the module pattern for the basic structure of &lt;a href="http://jpanelmenu.com/"&gt;jPanelMenu&lt;/a&gt;, the jQuery plugin I built for off-canvas menu systems. I’ll use that as an example to illustrate the process of building a module.
&lt;/p&gt;

&lt;h2&gt;Building a module&lt;/h2&gt;

&lt;p&gt;To begin, I define three methods and a property that are used to manage the interactions of the menu system.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
var jpm = {
    animated: true,
    openMenu: function( ) {
        …
        this.setMenuStyle( );
    },
    closeMenu: function( ) {
        …
        this.setMenuStyle( );
    },
    setMenuStyle: function( ) { … }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The idea is to break down code into the smallest, most reusable bits possible. I could have written just one &lt;code&gt;toggleMenu( )&lt;/code&gt; method, but creating distinct &lt;code&gt;openMenu( )&lt;/code&gt; and &lt;code&gt;closeMenu( )&lt;/code&gt; methods provides more control and reusability within the module.&lt;/p&gt;

&lt;p&gt;Notice that calls to module methods and properties from &lt;em&gt;within&lt;/em&gt; the module itself (such as the calls to &lt;code&gt;setMenuStyle( )&lt;/code&gt;) are prefixed with the &lt;code&gt;this&lt;/code&gt; keyword—that’s how modules access their own members.&lt;/p&gt;

&lt;p&gt;That’s the basic structure of a module. You can continue to add methods and properties as needed, but it doesn’t get any more complex than that. After the structural foundations are in place, the reusability layer—options and an exposed API—can be built on top.&lt;/p&gt;

&lt;h2&gt;jQuery plugins&lt;/h2&gt;

&lt;p&gt;The third aspect of well-designed code is probably the most crucial: reusability. This section comes with a caveat. While there are obviously ways to build and implement reusable components in raw JavaScript (we’re about 90 percent of the way there with our module above), I prefer to build jQuery plugins for more complex things, for a few reasons.&lt;/p&gt;

&lt;p&gt;Most importantly, it’s a form of unobtrusive communication. If you used jQuery to build a component, you should make that obvious to those implementing it. Building the component as a jQuery plugin is a great way to say that jQuery is required.&lt;/p&gt;

&lt;p&gt;In addition, the implementation code will be consistent with the rest of the jQuery-based project code. That’s good for aesthetic reasons, but it also means (to an extent) that developers can predict how to interact with the plugin without too much research. Just one more way to build a better developer interface.&lt;/p&gt;

&lt;p&gt;Before you begin building a jQuery plugin, ensure that the plugin does not conflict with other JavaScript libraries using the &lt;code&gt;$&lt;/code&gt; notation. That’s a lot simpler than it sounds—just wrap your plugin code like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
(function($) {
    // jQuery plugin code here
})(jQuery);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next, we set up our plugin and drop our previously built module code inside. A plugin is just a method defined on the jQuery &lt;code&gt;($)&lt;/code&gt; object.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
(function($) {
    $.jPanelMenu = function( ) {
        var jpm = {
            animated: true,
            openMenu: function( ) {
                …
                this.setMenuStyle( );
            },
            closeMenu: function( ) {
                …
                this.setMenuStyle( );
            },
            setMenuStyle: function( ) { … }
        };
    };
})(jQuery);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;All it takes to use the plugin is a call to the function you just created.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
var jpm = $.jPanelMenu( );
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Options&lt;/h2&gt;

&lt;p&gt;Options are essential to any truly reusable plugin because they allow for customizations to each implementation. Every project brings with it a slew of design styles, interaction types, and content structures. Customizable options help ensure that you can adapt the plugin to fit within those project constraints.&lt;/p&gt;

&lt;p&gt;It’s best practice to provide good default values for your options. The easiest way to do that is to use jQuery’s &lt;code&gt;$.extend( )&lt;/code&gt; method, which accepts (at least) two arguments.&lt;/p&gt;

&lt;p&gt;As the first argument of &lt;code&gt;$.extend( )&lt;/code&gt;, define an object with all available options and their default values. As the second argument, pass through the passed-in options. This will merge the two objects, overriding the defaults with any passed-in options.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
(function($) {
    $.jPanelMenu = function(options) {
        var jpm = {
            options: $.extend({
                'animated': true,
                'duration': 500,
                'direction': 'left'
            }, options),
            openMenu: function( ) {
                …
                this.setMenuStyle( );
            },
            closeMenu: function( ) {
                …
                this.setMenuStyle( );
            },
            setMenuStyle: function( ) { … }
        };
    };
})(jQuery);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Beyond providing good defaults, options become almost self-documenting—someone can look at the code and see all of the available options immediately.&lt;/p&gt;

&lt;p&gt;Expose as many options as is feasible. The customization will help in future implementations, and flexibility never hurts.&lt;/p&gt;

&lt;h2&gt;API&lt;/h2&gt;

&lt;p&gt;Options are terrific ways to customize how a plugin works. An API, on the other hand, enables extensions to the plugin’s functionality by exposing methods and properties for the implementation code to take advantage of.&lt;/p&gt;

&lt;p&gt;While it’s great to expose as much as possible through an API, the outside world shouldn’t have access to all internal methods and properties. Ideally, you should expose only the elements that will be used.&lt;/p&gt;

&lt;p&gt;In our example, the exposed API should include calls to open and close the menu, but nothing else. The internal &lt;code&gt;setMenuStyle( )&lt;/code&gt; method runs when the menu opens and closes, but the public doesn’t need access to it.&lt;/p&gt;

&lt;p&gt;To expose an API, return an object with any desired methods and properties at the end of the plugin code. You can even map returned methods and properties to those within the module code—this is where the beautiful organization of the module pattern really shines.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
(function($) {
    $.jPanelMenu = function(options) {
        var jpm = {
            options: $.extend({
                'animated': true,
                'duration': 500,
                'direction': 'left'
            }, options),
            openMenu: function( ) {
                …
                this.setMenuStyle( );
            },
            closeMenu: function( ) {
                …
                this.setMenuStyle( );
            },
            setMenuStyle: function( ) { … }
        };

        return {
            open: jpm.openMenu,
            close: jpm.closeMenu,
            someComplexMethod: function( ) { … }
        };
    };
})(jQuery);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;API methods and properties will be available through the object returned from the plugin initialization.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
var jpm = $.jPanelMenu({
    duration: 1000,
    …
});
jpm.open( );
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Polishing developer interfaces&lt;/h2&gt;

&lt;p&gt;With just a few simple constructs and guidelines, we’ve built ourselves a reusable, extensible plugin that will help make our lives easier. Like any part of what we do, experiment with this structure to see if it works for you, your team, and your workflow.&lt;/p&gt;

&lt;p&gt;Whenever I find myself building something with a potential for reuse, I break it out into a module-based jQuery plugin. The best part about this approach is that it forces you to use—and test—the code you write. By using something as you build it, you’ll quickly identify strengths, discover shortcomings, and plan changes.&lt;/p&gt;

&lt;p&gt;This process leads to battle-tested code ready for open-source contributions, or to be sold and distributed. I’ve released my (mostly) polished plugins as open-source projects on &lt;a href="https://github.com/acolangelo"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Even if you aren’t building something to be released in the wild, it’s still important to think about the design of your code. Your future self will thank you.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/abridged/~4/x0nEW66nHaE" height="1" width="1"/&gt;</description>
      <dc:subject />
      <dc:date>2013-05-21T12:00:27+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/the-design-of-code-organizing-javascript</feedburner:origLink></item>
    
    <item>
      <title><![CDATA[Writing Testable JavaScript]]></title>
      <link>http://feedproxy.google.com/~r/alistapart/abridged/~3/EcxNHDRHkTM/writing-testable-javascript</link>
      <guid isPermaLink="false">http://alistapart.com/article/writing-testable-javascript</guid>
      <description>&lt;p&gt;We’ve all been there: that bit of JavaScript functionality that started out as just a handful of lines grows to a dozen, then two dozen, then more. Along the way, a function picks up a few more arguments; a conditional picks up a few more conditions. And then one day, the bug report comes in: something’s broken, and it’s up to us to untangle the mess.&lt;/p&gt;

&lt;p&gt;As we ask our client-side code to take on more and more responsibilities—indeed, whole applications are living largely in the browser these days—two things are becoming clear. One, we can’t just point and click our way through testing that things are working as we expect; automated tests are key to having confidence in our code. Two, we’re probably going to have to change how we write our code in order to make it possible to write tests.&lt;/p&gt;

&lt;p&gt;Really, we need to change how we code? Yes—because even if we know that automated tests are a good thing, most of us are probably only able to write integration tests right now. Integration tests are valuable because they focus on how the pieces of an application work together, but what they don’t do is tell us whether individual &lt;em&gt;units of functionality&lt;/em&gt; are behaving as expected.&lt;/p&gt;

&lt;p&gt;That’s where unit testing comes in. And we’ll have a very hard time &lt;em&gt;writing unit tests&lt;/em&gt; until we start &lt;em&gt;writing testable JavaScript&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;Unit vs. integration: what’s the difference?&lt;/h2&gt;

&lt;p&gt;Writing integration tests is usually fairly straightforward: we simply write code that describes how a user interacts with our app, and what the user should expect to see as she does. &lt;a href="http://docs.seleniumhq.org/"&gt;Selenium&lt;/a&gt; is a popular tool for automating browsers. &lt;a href="https://github.com/jnicklas/capybara"&gt;Capybara&lt;/a&gt; for Ruby makes it easy to talk to Selenium, and there are plenty of tools for other languages, too.&lt;/p&gt;

&lt;p&gt;Here’s an integration test for a portion of a search app:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;def test_search
  fill_in(&amp;#39;q&amp;#39;, :with =&amp;gt; &amp;#39;cat&amp;#39;)
  find(&amp;#39;.btn&amp;#39;).click
  assert( find(&amp;#39;#results li&amp;#39;).has_content?(&amp;#39;cat&amp;#39;), &amp;#39;Search results are shown&amp;#39; )
  assert( page.has_no_selector?(&amp;#39;#results li.no-results&amp;#39;), &amp;#39;No results is not shown&amp;#39; )
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Whereas an integration test is interested in a user’s interaction with an app, a unit test is narrowly focused on a small piece of code:&lt;/p&gt;

&lt;figure class="quote"&gt;
&lt;blockquote&gt;When I call a function with a certain input, do I receive the expected output? &lt;/blockquote&gt;
&lt;/figure&gt;

&lt;p&gt;Apps that are written in a traditional procedural style can be very difficult to unit test—and difficult to maintain, debug, and extend, too. But if we write our code with our future unit testing needs in mind, we will not only find that writing the tests becomes more straightforward than we might have expected, but also that we’ll simply &lt;em&gt;write better code&lt;/em&gt;, too.&lt;/p&gt;

&lt;p&gt;To see what I’m talking about, let’s take a look at a simple search app:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://d.alistapart.com/375/app.png" alt="Srchr"&gt;&lt;/p&gt;

&lt;p&gt;When a user enters a search term, the app sends an XHR to the server for the corresponding data. When the server responds with the data, formatted as JSON, the app takes that data and displays it on the page, using client-side templating. A user can click on a search result to indicate that he “likes” it; when this happens, the name of the person he liked is added to the “Liked” list on the right-hand side.&lt;/p&gt;

&lt;p&gt;A “traditional” JavaScript implementation of this app might look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;var tmplCache = {};

function loadTemplate (name) {
  if (!tmplCache[name]) {
    tmplCache[name] = $.get(&amp;#39;/templates/&amp;#39; + name);
  }
  return tmplCache[name];
}

$(function () {

  var resultsList = $(&amp;#39;#results&amp;#39;);
  var liked = $(&amp;#39;#liked&amp;#39;);
  var pending = false;

  $(&amp;#39;#searchForm&amp;#39;).on(&amp;#39;submit&amp;#39;, function (e) {
    e.preventDefault();

    if (pending) { return; }

    var form = $(this);
    var query = $.trim( form.find(&amp;#39;input[name=&amp;quot;q&amp;quot;]&amp;#39;).val() );

    if (!query) { return; }

    pending = true;

    $.ajax(&amp;#39;/data/search.json&amp;#39;, {
      data : { q: query },
      dataType : &amp;#39;json&amp;#39;,
      success : function (data) {
        loadTemplate(&amp;#39;people-detailed.tmpl&amp;#39;).then(function (t) {
          var tmpl = _.template(t);
          resultsList.html( tmpl({ people : data.results }) );
          pending = false;
        });
      }
    });

    $(&amp;#39;&amp;lt;li&amp;gt;&amp;#39;, {
      &amp;#39;class&amp;#39; : &amp;#39;pending&amp;#39;,
      html : &amp;#39;Searching &amp;amp;hellip;&amp;#39;
    }).appendTo( resultsList.empty() );
  });

  resultsList.on(&amp;#39;click&amp;#39;, &amp;#39;.like&amp;#39;, function (e) {
    e.preventDefault();
    var name = $(this).closest(&amp;#39;li&amp;#39;).find(&amp;#39;h2&amp;#39;).text();
    liked.find(&amp;#39;.no-results&amp;#39;).remove();
    $(&amp;#39;&amp;lt;li&amp;gt;&amp;#39;, { text: name }).appendTo(liked);
  });

});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;My friend &lt;a href="https://twitter.com/ajpiano"&gt;Adam Sontag&lt;/a&gt; calls this &lt;cite&gt;Choose Your Own Adventure&lt;/cite&gt; code—on any given line, we might be dealing with presentation, or data, or user interaction, or application state. Who knows! It’s easy enough to write integration tests for this kind of code, but it’s hard to test individual &lt;em&gt;units of functionality&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;What makes it hard? Four things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A general lack of structure; almost everything happens in a &lt;code&gt;$(document).ready()&lt;/code&gt; callback, and then in anonymous functions that can’t be tested because they aren’t exposed.&lt;/li&gt;
&lt;li&gt;Complex functions; if a function is more than 10 lines, like the submit handler, it’s highly likely that it’s doing too much.&lt;/li&gt;
&lt;li&gt;Hidden or shared state; for example, since &lt;code&gt;pending&lt;/code&gt; is in a closure, there’s no way to test whether the pending state is set correctly.&lt;/li&gt;
&lt;li&gt;Tight coupling; for example, a &lt;code&gt;$.ajax&lt;/code&gt; success handler shouldn’t need direct access to the DOM.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Organizing our code&lt;/h2&gt;

&lt;p&gt;The first step toward solving this is to take a less tangled approach to our code, breaking it up into a few different areas of responsibility:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Presentation and interaction&lt;/li&gt;
&lt;li&gt;Data management and persistence&lt;/li&gt;
&lt;li&gt;Overall application state&lt;/li&gt;
&lt;li&gt;Setup and glue code to make the pieces work together&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the “traditional” implementation shown above, these four categories are intermingled—on one line we’re dealing with presentation, and two lines later we might be communicating with the server.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://d.alistapart.com/375/code-lines.png" alt="Code Lines"&gt;&lt;/p&gt;

&lt;p&gt;While we can absolutely write integration tests for this code—and we should!—writing unit tests for it is pretty difficult. In our functional tests, we can make assertions such as “when a user searches for something, she should see the appropriate results,” but we can’t get much more specific. If something goes wrong, we’ll have to track down exactly where it went wrong, and our functional tests won’t help much with that.&lt;/p&gt;

&lt;p&gt;If we rethink how we write our code, though, we can write unit tests that will give us better insight into where things went wrong, and also help us end up with code that’s easier to reuse, maintain, and extend.&lt;/p&gt;

&lt;p&gt;Our new code will follow a few guiding principles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Represent each distinct piece of behavior as a separate object that falls into one of the four areas of responsibility and doesn’t need to know about other objects. This will help us avoid creating tangled code.&lt;/li&gt;
&lt;li&gt;Support configurability, rather than hard-coding things. This will prevent us from replicating our entire HTML environment in order to write our tests.&lt;/li&gt;
&lt;li&gt;Keep our objects’ methods simple and brief. This will help us keep our tests simple and our code easy to read.&lt;/li&gt;
&lt;li&gt;Use constructor functions to create instances of objects. This will make it possible to create “clean” copies of each piece of code for the sake of testing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To start with, we need to figure out how we’ll break our application into different pieces. We’ll have three pieces dedicated to presentation and interaction: the Search Form, the Search Results, and the Likes Box.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://d.alistapart.com/375/app-views.png" alt="Application Views"&gt;&lt;/p&gt;

&lt;p&gt;We’ll also have a piece dedicated to fetching data from the server and a piece dedicated to gluing everything together.&lt;/p&gt;

&lt;p&gt;Let’s start by looking at one of the simplest pieces of our application: the Likes Box. In the original version of the app, this code was responsible for updating the Likes Box:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;var liked = $(&amp;#39;#liked&amp;#39;); 
var resultsList = $(&amp;#39;#results&amp;#39;); 
 
// ...
  
resultsList.on(&amp;#39;click&amp;#39;, &amp;#39;.like&amp;#39;, function (e) {
  e.preventDefault(); 
  var name = $(this).closest(&amp;#39;li&amp;#39;).find(&amp;#39;h2&amp;#39;).text(); 
  liked.find( &amp;#39;.no-results&amp;#39; ).remove(); 
  $(&amp;#39;&amp;lt;li&amp;gt;&amp;#39;, { text: name }).appendTo(liked); 
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The Search Results piece is completely intertwined with the Likes Box piece and needs to know a lot about its markup. A much better and more testable approach would be to create a Likes Box object that’s responsible for manipulating the DOM related to the Likes Box:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;var Likes = function (el) {
  this.el = $(el);
  return this;
};

Likes.prototype.add = function (name) {
  this.el.find(&amp;#39;.no-results&amp;#39;).remove();
  $(&amp;#39;&amp;lt;li&amp;gt;&amp;#39;, { text: name }).appendTo(this.el);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This code provides a constructor function that creates a new instance of a Likes Box. The instance that’s created has an &lt;code&gt;.add()&lt;/code&gt; method, which we can use to add new results. We can write a couple of tests to prove that it works:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;var ul;

setup(function(){
  ul = $(&amp;#39;&amp;lt;ul&amp;gt;&amp;lt;li class=&amp;quot;no-results&amp;quot;&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&amp;#39;);
});

test(&amp;#39;constructor&amp;#39;, function () {
  var l = new Likes(ul);
  assert(l);
});

test(&amp;#39;adding a name&amp;#39;, function () {
  var l = new Likes(ul);
  l.add(&amp;#39;Brendan Eich&amp;#39;);

  assert.equal(ul.find(&amp;#39;li&amp;#39;).length, 1);
  assert.equal(ul.find(&amp;#39;li&amp;#39;).first().html(), &amp;#39;Brendan Eich&amp;#39;);
  assert.equal(ul.find(&amp;#39;li.no-results&amp;#39;).length, 0);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Not so hard, is it? Here we’re using &lt;a href="http://visionmedia.github.io/mocha/"&gt;Mocha&lt;/a&gt; as the test &lt;em&gt;framework&lt;/em&gt;, and &lt;a href="http://chaijs.com/"&gt;Chai&lt;/a&gt; as the &lt;em&gt;assertion library&lt;/em&gt;. Mocha provides the &lt;code&gt;test&lt;/code&gt; and &lt;code&gt;setup&lt;/code&gt; functions; Chai provides &lt;code&gt;assert&lt;/code&gt;. There are plenty of other test frameworks and assertion libraries to choose from, but for the sake of an introduction, I find these two work well. You should find the one that works best for you and your project—aside from Mocha, &lt;a href="http://qunitjs.com/"&gt;QUnit&lt;/a&gt; is popular, and &lt;a href="http://theintern.io/"&gt;Intern&lt;/a&gt; is a new framework that shows a lot of promise.&lt;/p&gt;

&lt;p&gt;Our test code starts out by creating an element that we’ll use as the container for our Likes Box. Then, it runs two tests: one is a sanity check to make sure we can make a Likes Box; the other is a test to ensure that our &lt;code&gt;.add()&lt;/code&gt; method has the desired effect. With these tests in place, we can safely refactor the code for our Likes Box, and be confident that we’ll know if we break anything.&lt;/p&gt;

&lt;p&gt;Our new application code can now look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;var liked = new Likes(&amp;#39;#liked&amp;#39;);
var resultsList = $(&amp;#39;#results&amp;#39;); 
 
// ...
  
resultsList.on(&amp;#39;click&amp;#39;, &amp;#39;.like&amp;#39;, function (e) {
  e.preventDefault(); 
  var name = $(this).closest(&amp;#39;li&amp;#39;).find(&amp;#39;h2&amp;#39;).text(); 
  liked.add(name);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The Search Results piece is more complex than the Likes Box, but let’s take a stab at refactoring that, too. Just as we created an &lt;code&gt;.add()&lt;/code&gt; method on the Likes Box, we also want to create methods for interacting with the Search Results. We’ll want a way to add new results, as well as a way to &amp;#8220;broadcast&amp;#8221; to the rest of the app when things happen within the Search Results—for example, when someone likes a result.&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;var SearchResults = function (el) {
  this.el = $(el);
  this.el.on( &amp;#39;click&amp;#39;, &amp;#39;.btn.like&amp;#39;, _.bind(this._handleClick, this) );
};

SearchResults.prototype.setResults = function (results) {
  var templateRequest = $.get(&amp;#39;people-detailed.tmpl&amp;#39;);
  templateRequest.then( _.bind(this._populate, this, results) );
};

SearchResults.prototype._handleClick = function (evt) {
  var name = $(evt.target).closest(&amp;#39;li.result&amp;#39;).attr(&amp;#39;data-name&amp;#39;);
  $(document).trigger(&amp;#39;like&amp;#39;, [ name ]);
};

SearchResults.prototype._populate = function (results, tmpl) {
  var html = _.template(tmpl, { people: results });
  this.el.html(html);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, our old app code for managing the interaction between Search Results and the Likes Box could look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;var liked = new Likes(&amp;#39;#liked&amp;#39;);
var resultsList = new SearchResults(&amp;#39;#results&amp;#39;); 
 
// ...
  
$(document).on(&amp;#39;like&amp;#39;, function (evt, name) {
  liked.add(name);
})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It’s much simpler and less entangled, because we’re using the &lt;code&gt;document&lt;/code&gt; as a global message bus, and passing messages through it so individual components don’t need to know about each other. (Note that in a real app, we’d use something like &lt;a href="http://backbonejs.org"&gt;Backbone&lt;/a&gt; or the &lt;a href="https://github.com/tildeio/rsvp.js"&gt;RSVP&lt;/a&gt; library to manage events. We’re just triggering on &lt;code&gt;document&lt;/code&gt; to keep things simple here.) We’re also hiding all the dirty work—such as finding the name of the person who was liked—inside the Search Results object, rather than having it muddy up our application code. The best part: we can now write tests to prove that our Search Results object works as we expect:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;var ul;
var data = [ /* fake data here */ ];

setup(function () {
  ul = $(&amp;#39;&amp;lt;ul&amp;gt;&amp;lt;li class=&amp;quot;no-results&amp;quot;&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&amp;#39;);
});

test(&amp;#39;constructor&amp;#39;, function () {
  var sr = new SearchResults(ul);
  assert(sr);
});

test(&amp;#39;display received results&amp;#39;, function () {
  var sr = new SearchResults(ul);
  sr.setResults(data);

  assert.equal(ul.find(&amp;#39;.no-results&amp;#39;).length, 0);
  assert.equal(ul.find(&amp;#39;li.result&amp;#39;).length, data.length);
  assert.equal(
    ul.find(&amp;#39;li.result&amp;#39;).first().attr(&amp;#39;data-name&amp;#39;),
    data[0].name
  );
});

test(&amp;#39;announce likes&amp;#39;, function() {
  var sr = new SearchResults(ul);
  var flag;
  var spy = function () {
    flag = [].slice.call(arguments);
  };

  sr.setResults(data);
  $(document).on(&amp;#39;like&amp;#39;, spy);

  ul.find(&amp;#39;li&amp;#39;).first().find(&amp;#39;.like.btn&amp;#39;).click();

  assert(flag, &amp;#39;event handler called&amp;#39;);
  assert.equal(flag[1], data[0].name, &amp;#39;event handler receives data&amp;#39; );
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The interaction with the server is another interesting piece to consider. The original code included a direct &lt;code&gt;$.ajax()&lt;/code&gt; request, and the callback interacted directly with the DOM:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;$.ajax(&amp;#39;/data/search.json&amp;#39;, {
  data : { q: query },
  dataType : &amp;#39;json&amp;#39;,
  success : function( data ) {
    loadTemplate(&amp;#39;people-detailed.tmpl&amp;#39;).then(function(t) {
      var tmpl = _.template( t );
      resultsList.html( tmpl({ people : data.results }) );
      pending = false;
    });
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Again, this is difficult to write a unit test for, because so many different things are happening in just a few lines of code. We can restructure the data portion of our application as an object of its own:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;var SearchData = function () { };

SearchData.prototype.fetch = function (query) {
  var dfd;

  if (!query) {
    dfd = $.Deferred();
    dfd.resolve([]);
    return dfd.promise();
  }

  return $.ajax( &amp;#39;/data/search.json&amp;#39;, {
    data : { q: query },
    dataType : &amp;#39;json&amp;#39;
  }).pipe(function( resp ) {
    return resp.results;
  });
};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, we can change our code for getting the results onto the page:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;var resultsList = new SearchResults(&amp;#39;#results&amp;#39;); 
var searchData = new SearchData();

// ...

searchData.fetch(query).then(resultsList.setResults);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Again, we’ve dramatically simplified our application code, and isolated the complexity within the Search Data object, rather than having it live in our main application code. We’ve also made our search interface testable, though there are a couple caveats to bear in mind when testing code that interacts with the server.&lt;/p&gt;

&lt;p&gt;The first is that we don’t want to &lt;em&gt;actually&lt;/em&gt; interact with the server—to do so would be to reenter the world of integration tests, and because we’re responsible developers, we already have tests that ensure the server does the right thing, right? Instead, we want to &amp;#8220;mock&amp;#8221; the interaction with the server, which we can do using the &lt;a href="http://sinonjs.org/"&gt;Sinon&lt;/a&gt; library. The second caveat is that we should also test non-ideal paths, such as an empty query.&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;test(&amp;#39;constructor&amp;#39;, function () {
  var sd = new SearchData();
  assert(sd);
});

suite(&amp;#39;fetch&amp;#39;, function () {
  var xhr, requests;

  setup(function () {
    requests = [];
    xhr = sinon.useFakeXMLHttpRequest();
    xhr.onCreate = function (req) {
      requests.push(req);
    };
  });

  teardown(function () {
    xhr.restore();
  });

  test(&amp;#39;fetches from correct URL&amp;#39;, function () {
    var sd = new SearchData();
    sd.fetch(&amp;#39;cat&amp;#39;);

    assert.equal(requests[0].url, &amp;#39;/data/search.json?q=cat&amp;#39;);
  });

  test(&amp;#39;returns a promise&amp;#39;, function () {
    var sd = new SearchData();
    var req = sd.fetch(&amp;#39;cat&amp;#39;);

    assert.isFunction(req.then);
  });

  test(&amp;#39;no request if no query&amp;#39;, function () {
    var sd = new SearchData();
    var req = sd.fetch();
    assert.equal(requests.length, 0);
  });

  test(&amp;#39;return a promise even if no query&amp;#39;, function () {
    var sd = new SearchData();
    var req = sd.fetch();

    assert.isFunction( req.then );
  });

  test(&amp;#39;no query promise resolves with empty array&amp;#39;, function () {
    var sd = new SearchData();
    var req = sd.fetch();
    var spy = sinon.spy();

    req.then(spy);

    assert.deepEqual(spy.args[0][0], []);
  });

  test(&amp;#39;returns contents of results property of the response&amp;#39;, function () {
    var sd = new SearchData();
    var req = sd.fetch(&amp;#39;cat&amp;#39;);
    var spy = sinon.spy();

    requests[0].respond(
      200, { &amp;#39;Content-type&amp;#39;: &amp;#39;text/json&amp;#39; },
      JSON.stringify({ results: [ 1, 2, 3 ] })
    );

    req.then(spy);

    assert.deepEqual(spy.args[0][0], [ 1, 2, 3 ]);
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For the sake of brevity, I’ve left out the refactoring of the Search Form, and also simplified some of the other refactorings and tests, but you can see a finished version of the app &lt;a href="https://github.com/rmurphey/testable-javascript"&gt;here&lt;/a&gt; if you’re interested.&lt;/p&gt;

&lt;p&gt;When we’re done rewriting our application using testable JavaScript patterns, we end up with something much cleaner than what we started with:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;$(function() {
  var pending = false;

  var searchForm = new SearchForm(&amp;#39;#searchForm&amp;#39;);
  var searchResults = new SearchResults(&amp;#39;#results&amp;#39;);
  var likes = new Likes(&amp;#39;#liked&amp;#39;);
  var searchData = new SearchData();

  $(document).on(&amp;#39;search&amp;#39;, function (event, query) {
    if (pending) { return; }

    pending = true;

    searchData.fetch(query).then(function (results) {
      searchResults.setResults(results);
      pending = false;
    });

    searchResults.pending();
  });

  $(document).on(&amp;#39;like&amp;#39;, function (evt, name) {
    likes.add(name);
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Even more important than our much cleaner application code, though, is the fact that we end up with a codebase that is thoroughly tested. That means we can safely refactor it and add to it without the fear of breaking things. We can even write new tests as we find new issues, and then write the code that makes those tests pass.&lt;/p&gt;

&lt;h2&gt;Testing makes life easier in the long run&lt;/h2&gt;

&lt;p&gt;It’s easy to look at all of this and say, &amp;#8220;Wait, you want me to write more code to do the same job?&amp;#8221;&lt;/p&gt;

&lt;p&gt;The thing is, there are a few inescapable facts of life about Making Things On The Internet. You will spend time designing an approach to a problem. You will test your solution, whether by clicking around in a browser, writing automated tests, or—&lt;em&gt;shudder&lt;/em&gt;—letting your users do your testing for you in production. You will make changes to your code, and other people will use your code. Finally: there will be bugs, no matter how many tests you write.&lt;/p&gt;

&lt;p&gt;The thing about testing is that while it might require a bit more time at the outset, it really does save time in the long run. You’ll be patting yourself on the back the first time a test you wrote catches a bug before it finds its way into production. You’ll be grateful, too, when you have a system in place that can prove that your bug fix really does fix a bug that slips through.&lt;/p&gt;

&lt;h2&gt;Additional resources&lt;/h2&gt;

&lt;p&gt;This article just scratches the surface of JavaScript testing, but if you’d like to learn more, check out:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="http://lanyrd.com/2012/full-frontal/sztqh/"&gt;My presentation&lt;/a&gt; from the 2012 Full Frontal conference in Brighton, UK.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://gruntjs.com/"&gt;Grunt&lt;/a&gt;, a tool that helps automate the testing process and lots of other things.&lt;/li&gt;
&lt;li&gt;&lt;cite&gt;&lt;a href="http://www.amazon.com/Test-Driven-JavaScript-Development-Developers-Library/dp/0321683919/ref=sr_1_1?ie=UTF8&amp;amp;qid=1366506174&amp;amp;sr=8-1&amp;amp;keywords=test+driven+javascript+development"&gt;Test-Driven JavaScript Development&lt;/a&gt;&lt;/cite&gt; by Christian Johansen, the creator of the Sinon library. It is a dense but informative examination of the practice of testing JavaScript.&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/abridged/~4/EcxNHDRHkTM" height="1" width="1"/&gt;</description>
      <dc:subject />
      <dc:date>2013-05-21T12:00:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/writing-testable-javascript</feedburner:origLink></item>
    
	
	    <item>
      <title><![CDATA[This week's sponsor: Igloo Software]]></title>
      <link>http://feedproxy.google.com/~r/alistapart/abridged/~3/mMOKelnXCko/alistapart</link>
      <guid isPermaLink="false">http://www.igloosoftware.com/campaigns/alistapart</guid>
      <description>&lt;p&gt;If SharePoint and Facebook had a baby, it would look a lot like &lt;a href="http://www.igloosoftware.com/campaigns/alistapart"&gt;Igloo&lt;/a&gt; (without the recessive balding or oversharing tendencies). Hosted, managed and with a major release every 90 days, Igloo is &lt;a href="http://www.igloosoftware.com/campaigns/alistapart"&gt;a whitelabel content platform&lt;/a&gt; built for today&amp;#8217;s needs. We also have Sandwich Video.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/abridged/~4/mMOKelnXCko" height="1" width="1"/&gt;</description>
      <dc:subject />
      <dc:date>2013-05-20T17:00:45+00:00</dc:date>
    <feedburner:origLink>http://www.igloosoftware.com/campaigns/alistapart</feedburner:origLink></item>
    
	    <item>
      <title><![CDATA[Rachel Andrew on the Business of Web Dev: You Can&#8217;t Do Everything]]></title>
      <link>http://feedproxy.google.com/~r/alistapart/abridged/~3/yiLQQ29l58s/you-cant-do-everything</link>
      <guid isPermaLink="false">http://alistapart.com/column/you-cant-do-everything</guid>
      <description>&lt;p&gt;In any given day I can find myself reading up on a new W3C proposal, fixing an issue with our tax return, coding an add-on for our product, writing a conference presentation, building a server, creating a video tutorial, and doing front end development for one of our sites. Without clients dictating my workload I’m in the enviable position of being able to choose where to focus my efforts. However, I can’t physically do everything.&lt;/p&gt;

&lt;p&gt;I’m one half of a two-person web development business—the team behind the little CMS, Perch. I’m also an author and speaker on subjects that range from CSS to technical support, and I enjoy all of it.&lt;/p&gt;

&lt;p&gt;When we were a service business, what I was actually working on was largely dictated by the requirements of our clients. Whether they wanted to pay me to build servers, manage projects, or write code didn’t really matter. I was exchanging my time for money, doing a range of things I enjoyed. Now that we’re a product company, my greatest challenge is working out where I am best spending my time, while avoiding falling down a rabbit hole of interesting things I have discovered while performing some other task.&lt;/p&gt;

&lt;p&gt;The quote that I opened this column with reflects the dilemma I seem to face daily. I can choose to place my attention anywhere. But if I dart around between tasks, none of them get my full attention. At the very least, progress on everything becomes painfuly slow as I spend an hour on one thing and two on another, inching them all forward. I can’t claim to have the perfect solution to managing this problem, but I have started to develop a process for deciding what needs to be done, and whether I am the best person to be doing it.&lt;/p&gt;

&lt;p&gt;First and foremost you need to identify what needs doing. I am a great fan of &lt;a href="http://en.wikipedia.org/wiki/Getting_Things_Done"&gt;Getting Things Done&lt;/a&gt; and regularly review our business and my personal goals, and the tasks that will go into meeting them. Once I have a list of tasks, I can assess them against the following criteria:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Am I the only person who can do this?&lt;/li&gt;
&lt;li&gt;Does the business or product benefit from me in particular doing this?&lt;/li&gt;
&lt;li&gt;Is this a task I really enjoy doing?&lt;/li&gt;
&lt;li&gt;Will I learn anything new by doing this?&lt;/li&gt;
&lt;li&gt;What am I not doing if I choose to do this?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Am I the only person who can do this?&lt;/h2&gt;

&lt;p&gt;Things that fall into group one, the things that only I can do, need investigating. It isn’t ideal for any business to have things that only one person can do. It might be that I need to deal with that task &lt;em&gt;today&lt;/em&gt;, but how can I make it so that in the future someone else could? Until the middle of last year, our accounts were a case in point. Although we had an accountant do our end of year tax returns, I was the only person who fully understood the complex processes developed to deal with the many incoming small payments for Perch licenses. Taking on a bookkeeper meant I had to formalize and document all of those processes. As a result I don’t have to do the day-to-day books, but perhaps more importantly the business isn’t reliant on knowledge that is only in my head.&lt;/p&gt;

&lt;h2&gt;Does the business or product benefit from me in particular doing this?&lt;/h2&gt;

&lt;p&gt;It can make sense to keep some tasks internal. I wouldn’t completely outsource our technical support, or our social media activity, or even our marketing. The public face of our product is very much about us being a small, friendly business. Our customers get to talk to us, the product developers; we share their frustrations and they help us decide on where to put time into new features. There may well be real reasons to keep certain tasks as a role of the core person or team, even if they would seem straightforward to outsource.&lt;/p&gt;

&lt;h2&gt;Is this a task I really enjoy doing?&lt;/h2&gt;

&lt;p&gt;Running a business can involve hard work and long hours. If you feel you have to outsource bits of your job that you love doing because it makes most sense as a business, you may end up pretty miserable. For those of us running small software companies, it’s likely we have ended up here because we like to code. So it’s important to me that I spend some of my time actually writing code—even if it might be more sensible from a business perspective for me to just manage other people who are writing code.&lt;/p&gt;

&lt;p&gt;I believe that our products and businesses are better when we love being involved with them. To have a successful business, it’s likely that you will always have important things to do that you find less enjoyable than designing or writing code, however I don’t think we should be beating ourselves over the head. Doing what we love is really what has been behind the success of our product. It is completely ok to hang onto some tasks because you simply enjoy doing them.&lt;/p&gt;

&lt;h2&gt;Will I learn anything new by doing this?&lt;/h2&gt;

&lt;p&gt;I might really enjoy a particular project, but I find a helpful way to decide if I should do something or contract it out is to see whether I will learn anything new by doing it myself. For example, I have just sent out a sizeable chunk of front-end development. It is a rebuild of an existing site, and I think there are lots of practical and performance gains to be had by rebuilding it. It would have been nice to have done that work myself, but I wouldn’t have learned anything by doing it. Therefore I made the decision that this would be a good piece of work to outsource to a contractor. I can manage that project and make sure that I’m happy with the end result, but I don’t need to actually write the code.&lt;/p&gt;

&lt;p&gt;Our business benefits by us having knowledge and understanding. I’m currently spending quite a lot of time learning about automation (using &lt;a href="https://puppetlabs.com/"&gt;Puppet&lt;/a&gt;) and modern ways of managing systems while rebuilding our infrastructure. I could have brought someone in to do this work for me, and may well do so in future. Yet by updating my systems administration skills, I’m ensuring that within the business we maintain a good level of knowledge about our infrastructure.&lt;/p&gt;

&lt;h2&gt;What am I not doing if I choose to do this?&lt;/h2&gt;

&lt;p&gt;As part of a tiny team of two, I’ll always have a number of tasks on the go. Ultimately, choosing to take on one task means not doing something else. It might be another task in the business that gets pushed back. It might be personal things like exercise, or spending time with family and friends. To be able to understand the implications of selecting one thing to work on over another, you need to have a really good overview of all the things that are trying to get your attention.&lt;/p&gt;

&lt;p&gt;Having clear business goals and objectives in the first place can make this decision-making so much easier. When you find yourself in the position of being able to do anything, it is so easy to run around picking up tasks and trying to do everything. The trick is to take that step back; to see where you can be more strategic with which tasks you tackle and which you delegate. This approach can help you be far more productive and give you space to enjoy the work you are doing while meeting your business goals.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/abridged/~4/yiLQQ29l58s" height="1" width="1"/&gt;</description>
      <dc:subject><![CDATA[<a href="/topic/business">Business</a>, <a href="/topic/project-management">Project Management</a>, <a href="/topic/workflow-tools">Workflow & Tools</a>]]></dc:subject>
      <dc:date>2013-05-09T12:30:53+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/column/you-cant-do-everything</feedburner:origLink></item>
	
	    <item>
      <title><![CDATA[Karen McGrane on Content: WYSIWTF]]></title>
      <link>http://feedproxy.google.com/~r/alistapart/abridged/~3/8MK6ULY0bLI/wysiwtf</link>
      <guid isPermaLink="false">http://alistapart.com/column/wysiwtf</guid>
      <description>&lt;p&gt;Arguing for “separation of content from presentation” implies a neat division between the two. The reality, of course, is that content and form, structure and style, can never be fully separated. Anyone who’s ever written a document and played around to see the impact of different fonts, heading weights, and whitespace on the way the writing flows knows this is true. Anyone who’s ever squinted at HTML code, trying to parse text from tags, knows it too.&lt;/p&gt;

&lt;p&gt;On one hand, the division of labor between writing and presentation can be seen at every point in our history. Ancient scribes chiseling stone tablets, medieval monks copying illuminated manuscripts, printers placing movable type—we’ve never assumed that the person who produces the document and the person who comes up with the ideas must be one and the same.&lt;/p&gt;

&lt;p&gt;And yet, we know that medium and message are intertwined so tightly, they can’t be easily split apart. Graphic designers rail against the notion that “look and feel” can be painted on at the end of the process, because design influences meaning. The more skilled we are as communicators, the more we realize that the separation of content from presentation is an industrial-age feint, an attempt to standardize and segment tasks that are deeply connected.&lt;/p&gt;

&lt;p&gt;Today, we try to enforce the separation of content and form because it’s good for the web. It’s what makes web standards possible. It enables social sharing and flexible reuse of content. It supports accessibility. It’s what will keep us sane as we try to get content onto hundreds of new devices and form factors.&lt;/p&gt;

&lt;p&gt;When talking about how best to separate content from presentation, designers and developers tend to focus on front-end code—which makes sense, because that’s what we have the most control over. But, as with so many challenges we have with content on the web, the real issue lies in the tools we give content creators to help them structure, manage, and publish their content. The form that content takes depends as much on CMS as it does on CSS.&lt;/p&gt;

&lt;p&gt;How should content management tools guide content creators to focus on meaning and structure? What’s the right amount of control over presentation and styling in the CMS? And how should these tools evolve as we break out of the web page metaphor and publish content flexibly to multiple platforms? Let’s look at three tools that sit at the intersection of content and form.&lt;/p&gt;

&lt;h2&gt;Preview button&lt;/h2&gt;

&lt;p&gt;Even the most die-hard structured content editors still like seeing what their work is going to look like. Writers print out documents for editing to give them a different view from what they see on the screen. Bloggers instinctively hit the preview button to look at their work the way a user will see it.&lt;/p&gt;

&lt;p&gt;Whoops. Decades of work refining the emulators between desktop publishing programs and laser printers means that writers can feel confident that their document will look virtually identical, regardless of where it’s printed. We’ve carried that assumption over to the web, where it’s categorically untrue. Different browsers render content in their own vexingly special way. Users can change the font size—even add their own custom style sheet. Today, the same document will render differently on desktops, tablets, and mobile devices. The preview button is a lie.&lt;/p&gt;

&lt;p&gt;Yet we can’t just throw the baby out with the bathwater. In fact, seeing content in context becomes even &lt;em&gt;more&lt;/em&gt; important as our content now lives across devices and platforms. Instead of throwing up our hands and saying “preview is broken,” it’s time to invent a better preview button.&lt;/p&gt;

&lt;p&gt;One publishing company I know of has built its own custom preview rendering interface, which shows content producers an example of how each story will appear on the desktop web, the mobile web, and an app. Is it perfect? Far from it. Content will appear in many more contexts than just those three. Is it better than nothing? Absolutely.&lt;/p&gt;

&lt;h2&gt;WYSIWYG&lt;/h2&gt;

&lt;p&gt;The desktop publishing revolution ushered in by the Macintosh allowed the user to see a document on screen in a form that closely mirrored the printed version. The toolbar at the top of the screen enabled the user to add formatting—change the font, insert an image, add typographic effects like headings and bullets, and much more.&lt;/p&gt;

&lt;p&gt;In an effort to carry over this ease of use to the web, we allow content creators to embed layout and styling information directly into their content. Unfortunately, the code added by content creators can be at odds with the style sheet, and it’s difficult for developers to parse what’s style and what’s substance. When it comes time to put that content on other platforms, we wind up with a muddled mess.&lt;/p&gt;

&lt;p&gt;What is the right amount of formatting control to give content creators? That’s a difficult question to answer, because it pierces right to the heart of what’s stylistic and what’s semantic. Even something as simple as adding bold and italic text forces us to ask if we’re really just styling the text, or adding semantic meaning (say, a book title or a warning message.)&lt;/p&gt;

&lt;p&gt;Better content modeling can solve some of these problems, encouraging content creators to appropriately “chunk” their text. By banishing blobs of text with formatting embedded and replacing them with chunks of clean, presentation-independent content, we’re building in the distinction between content and form right from the start.&lt;/p&gt;

&lt;p&gt;But imagining that each “chunk” of content is a field in the database (with its own input field) rapidly devolves into the absurd. That way lies madness. The real solution isn’t necessarily to “banish blobs,” but to replace the WYSIWYG toolbar with semantic markup. Rather than entering all text into discrete fields, content authors wrap text that describes what it is. Our book title doesn’t need to be a separate field if we can wrap it in the proper tags.&lt;/p&gt;

&lt;p&gt;Defining what goes in a field and what goes in a tag requires a tighter collaboration between content authors, CMS architects, and front-end developers. It’s time we started having these conversations.&lt;/p&gt;

&lt;h2&gt;Inline editing&lt;/h2&gt;

&lt;p&gt;We’re evolving. Not satisfied to rely just on tools that are vestiges of the desktop publishing era, we’re developing new and innovative ways to mix up content and formatting that are unique to the way the web works. There’s no better example of this than inline editing.&lt;/p&gt;

&lt;p&gt;Inline editing allows content creators to directly manipulate content in the interface, with no separation between the editing screen and the display. Medium offers an editing interface that’s &lt;a href="https://medium.com/about/df8eac9f4a5e"&gt;identical to the desktop display&lt;/a&gt; and in-place editing is being &lt;a href="http://drupal.org/project/spark"&gt;added to Drupal 8 core&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One of the questions I get asked most frequently is “how can I get my content creators to understand why it’s so important to add structure and metadata to their content?” This, I believe, is one of the fundamental challenges we’re facing on the web, particularly as we adapt to a multi-channel future. Inline editing encourages content creators to focus on the visual presentation of the desktop interface. Just at the moment when we need content creators to think about the underlying structure, we’re investing in tools that obscure the “connective tissue.”&lt;/p&gt;

&lt;p&gt;Jeff Eaton sums up this problem nicely in a post called &lt;a href="https://www.lullabot.com/articles/inline-editing-and-cost-leaky-abstractions"&gt;Inline Editing and the Cost of Leaky Abstractions&lt;/a&gt;:&lt;/p&gt;

&lt;figure class="quote"&gt;&lt;blockquote&gt;&lt;p&gt;The editing interfaces we offer to users send them important messages, whether we intend it or not. They are affordances, like knobs on doors and buttons on telephones. If the primary editing interface we present is also the visual design seen by site visitors, we are saying: “This page is what you manage! The things you see on it are the true form of your content.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/figure&gt;

&lt;p&gt;The best solution isn’t to build tools that hide that complexity from the user, that make them think that the styling they’re adding to the desktop site is the “real” version of the content. Instead, our goal should be to communicate the appropriate complexity of the interface, and help guide users to add the right structure and styling.&lt;/p&gt;

&lt;p&gt;The era of “desktop publishing” is over. Same goes for the era where we privilege the desktop web interface above all others. The tools we create to manage our content are vestiges of the desktop publishing revolution, where we tried to enable as much direct manipulation of content as possible. In a world where we have infinite possible outputs for our content, it’s time to move beyond tools that rely on visual styling to convey semantic meaning. If we want true separation of content from form, it has to start in the CMS.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/abridged/~4/8MK6ULY0bLI" height="1" width="1"/&gt;</description>
      <dc:subject><![CDATA[<a href="/topic/content">Content</a>, <a href="/topic/html">HTML</a>]]></dc:subject>
      <dc:date>2013-05-02T11:43:20+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/column/wysiwtf</feedburner:origLink></item>
	
		
    <item>
      <title><![CDATA[Even Better In-Browser Mockups with Node.js]]></title>
      <link>http://feedproxy.google.com/~r/alistapart/abridged/~3/JIuRksQbUN4/even-better-in-browser-mockups-with-node.js</link>
      <guid isPermaLink="false">http://alistapart.com/article/even-better-in-browser-mockups-with-node.js</guid>
      <description>&lt;p&gt;Designing in the browser has all sorts of benefits, like producing more accurate, comprehensive results and removing the extra step of converting from image file to markup and CSS. But even sites designed in a browser still require pasting in content, faking interactions with the server, and creating placeholder JavaScript that isn’t usable on the live site.&lt;/p&gt;

&lt;p&gt;Wouldn’t it be nice if we could go from just designing layouts and interactions to designing the whole client side of the application during the same process?&lt;/p&gt;

&lt;p&gt;This is where Node comes in.&lt;/p&gt;

&lt;p&gt;Node.js is a server-side JavaScript platform. It isn’t a web server, but it allows you to easily create one. It also lets you create utilities that run on web servers, like setup and minification utilities and general-purpose command line tools.&lt;/p&gt;

&lt;p&gt;Node started in 2009 and generated considerable interest, probably because it gave JavaScript developers an opportunity to write server-side code even if they lacked a server-side background. It didn’t hurt that Chrome had established a reputation for being solid and fast, and Node used its V8 engine.&lt;/p&gt;

&lt;p&gt;Today, it’s possible to run production servers on Node, and many people are doing so successfully. Taking it that far, however, is an investment. The Node project, and all the community-created modules that make it so awesome, is still a moving target. But even if you’re not ready to write and launch entire sites with Node, it’s plenty stable enough to use as a development tool.&lt;/p&gt;

&lt;p&gt;It’s JavaScript, so if you can wire up a jQuery event handler, you can write a web server. It’s lightweight, so you can run it on your laptop and keep streaming music in the background. It’s dead simple to download, set up, and build in, so you don’t need the esoteric knowledge of an IT support person to get going with it. And the payoff is that instead of mockups and hard-coded data, you can design a set of client-side assets, page templates, and data schemas that are ready to launch to production.&lt;/p&gt;

&lt;h2&gt;Getting started&lt;/h2&gt;

&lt;p&gt;Installing Node locally for the most common environments is a piece of cake. You can download &lt;a href="http://nodejs.org/download/"&gt;installers&lt;/a&gt; that include Node as well as npm, its package manager, from the project’s site. Installing it on a remote server is not quite that easy, but &lt;a href="https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager"&gt;good documentation&lt;/a&gt; is available to help you out. After running through the installation process, you should be able to go to your terminal or command line and test it out.&lt;/p&gt;

&lt;p&gt;If you don’t tell Node to run a specific file, you get a Read-Eval-Print Loop, or REPL. If you type &lt;code&gt;node&lt;/code&gt; in your terminal or command prompt, you can begin to execute arbitrary JavaScript. For example, after starting the REPL, type &lt;code&gt;var a = 9;&lt;/code&gt;. The REPL will respond with undefined. Now type &lt;code&gt;a * 3&lt;/code&gt; (or any other number) and it will respond with the correct result. You can make things more interesting by defining a function and then calling it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&gt; function sayHello( name ) { return “Hello, “ + name; }
undefined
&gt; sayHello( “A List Apart” );
‘Hello, A List Apart’&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To break out of the REPL, or end any other Node execution (like a running web server), press Ctrl+C. In the case of the REPL, you’ll need to press it twice to confirm.&lt;/p&gt;

&lt;p&gt;While it’s nice to know Node can perform basic arithmetic and string concatenation, its value to us as developers is in running programs. You can see an example of one such program, a basic web server, on the project’s homepage. They suggest creating a file called &lt;code&gt;example.js&lt;/code&gt; with this code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var http = require(’http’);
http.createServer(function (req, res) {
  res.writeHead(200, {’Content-Type’: ‘text/plain’});
  res.end(’Hello World\n’);
}).listen(1337, ‘127.0.0.1’);
console.log(’Server running at http://127.0.0.1:1337/’);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This makes use of only one module, the core module &lt;code&gt;http&lt;/code&gt;. As you can probably guess, the &lt;code&gt;http&lt;/code&gt; module contains all the basic stuff you need to serve a site over HTTP. Node contains a tightly edited collection of &lt;a href="http://nodejs.org/api/"&gt;core modules&lt;/a&gt; that provide things like event handlers, file system access, and abstractions for various network protocols. But just as you probably use a JavaScript library or framework to speed up and bulletproof development on the client side, for Node development beyond a simple &amp;quot;Hello World&amp;quot; you generally add other non-core modules using npm.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;http&lt;/code&gt; module does contain a &lt;code&gt;createServer&lt;/code&gt; function, though, which is all you need to create a bare-bones web server. In the code above, once the server has been created, it listens to port 1337 on your local machine. When it receives a request, it sends back a text response.&lt;/p&gt;

&lt;p&gt;One thing to note is that the work here is done in event handlers, as are most things in Node. The callback in &lt;code&gt;createServer()&lt;/code&gt; handles a connection event, which occurs every time a new client contacts the server. To start this server, type &lt;code&gt;node example.js&lt;/code&gt; in your terminal, and then open a browser to http://127.0.0.1:1337. This triggers the connection event, and you should see the message in the callback.&lt;/p&gt;

&lt;p&gt;To obtain any serious value from a Node server—even one not intended to ever go to production—it’s best to get familiar with the modules in npm. There are thousands available, but those you’d need to create a basic web application are some of the oldest and most stable, so don’t feel obligated to research them all before getting started. One that definitely comes in handy for designing an application is &lt;a href="http://expressjs.com/"&gt;Express&lt;/a&gt;, an uncomplicated web application framework.&lt;/p&gt;

&lt;p&gt;If you’re accustomed to installing open source projects by cloning a GitHub repository or downloading a zip file, you’ll probably enjoy npm. To install Express with npm, for example, go to your terminal or command line and type &lt;code&gt;npm install express&lt;/code&gt;. As long as you’re online and have permission to write to your machine, this fetches all the code and assets Express needs to run, as well as any modules it has as dependencies. The first time you run npm from your working directory, all these elements will end up in a new &lt;code&gt;node_modules&lt;/code&gt; subdirectory. Now the module is ready to be used in Node programs the same way we used &lt;code&gt;http&lt;/code&gt;, via the &lt;code&gt;require&lt;/code&gt; function.&lt;/p&gt;

&lt;h2&gt;Designing applications&lt;/h2&gt;

&lt;p&gt;The ideal use case for designing your application with Node is a single-page application in which the server mostly provides data, but Node is still useful for a more traditional site. Of course, you want to begin development with requirements defined as precisely as possible, but implementation tends to expose requirements you hadn’t considered, and some of those can have a considerable impact on your timeline. Even in a server-driven application where it may not be possible to reuse data structures and templates as-is, creating client-only versions helps test your assumptions about the data you need and how you’ll use it.&lt;/p&gt;

&lt;p&gt;If you’re developing a single-page app, the justification is much easier. You’ll need to think about optimizing your communication with the server to require as few requests as possible, which means knowing how data should be packaged up by each server endpoint and how you’ll cache the data on receipt (if at all).&lt;/p&gt;

&lt;p&gt;An advantage of having JavaScript on the server is that templates can be rendered by the same template engine on either the client or server side. This allows you to experiment on both sides and optimize for your situation. It’s also a timesaver to render the templates with JavaScript objects and consider only the way data must eventually be grouped (not how it&amp;#8217;s stored in a database). Designing these groupings of data is the bulk of the work we can do with Node toward the end of what we traditionally consider application design.&lt;/p&gt;

&lt;p&gt;Piecing together each page from disparate parts from all over the server is messy for an application in any language. Instead, whatever renders a page should have clear dependencies, and the result of each page or data request should combine those dependencies into a cohesive and sensibly organized unit.&lt;/p&gt;

&lt;p&gt;If you’ve worked in a server-side framework in which a page or view is tied to a single object or model, and where additional data is imported and exposed in a different way, you probably understand how the alternative gets to be a nuisance. You’re probably also aware that the solution is a good view-model whose data is defined by each view, not the models that feed it. With this exercise, we aim to map out what goes in those view-models.&lt;/p&gt;

&lt;h2&gt;Using templates&lt;/h2&gt;

&lt;p&gt;There’s a strong likelihood that your production server does not run JavaScript, so you may end up converting templates you produce in this design phase. You could attempt to mitigate this by choosing a template engine like &lt;a href="http://mustache.github.io/"&gt;Mustache&lt;/a&gt; with existing parsers for a huge list of languages. Or you might choose one with minimal logic available (I find that the only things I want for a truly flexible template are conditionals, loops, and partials) and the option of changing the delimiters around the template tags to agree with your server template language. I’d argue that the process of getting all the data correctly placed in your HTML is a lot more difficult than doing a find and replace on the end result, so creating a template in JavaScript that you can use easily is time well spent even if it can’t be parsed by your production server.&lt;/p&gt;

&lt;p&gt;You could choose to design the UI of your pages using hard-coded mockup data first and add the template tags afterward, or you could start with a template and some mockup data ready to go in your Node server. Even though it’s an extra step, I find the former easier, because the latter tends to require extra shifting of the mockup data. Starting with hard-coded data lets me examine the finished mockup and see what kinds of &amp;quot;objects&amp;quot; are present (e.g., a user, an item for sale, or a status update). That helps me create a flexible object hierarchy in my data more easily. But you may be naturally amazing at creating object hierarchies, so, by all means, do what you feel.&lt;/p&gt;

&lt;p&gt;Wherever you begin, hammering out your templates should give you an indication of which parts of each page are dynamic and which data each requires. If subsections of your pages are rendered separately because they’re reused on different parent pages or because they’re also rendered by the client, converting your markup to templates also allows you to find the right balance between never repeating code and having absurdly tiny templates.&lt;/p&gt;

&lt;h2&gt;Real fake server interactions&lt;/h2&gt;

&lt;p&gt;If you’ve created high-fidelity wireframes that run in a browser, you know the annoyance of having only parts of a page be interactive, since every click means having to create a new view (even if you have a series of items that share the same behavior when clicked). You also know about copying and pasting the same data into multiple places, and updating each of them separately if the manner of presenting data should change. Designing your app with a server behind it removes those frustrations.&lt;/p&gt;

&lt;p&gt;With the support of a server, it’s not a problem if the same data shows up in different displays all over the workflow you’re designing. Since the data lives on your Node server, you can write it once and reuse it as many ways as you like. You still have to consider how you’ll move it from server to client, though. When a user clicks on one of many items in a list, will she be taken to a new page, or will more data appear inline? Is the former the non-JavaScript fallback for the latter? Working that out for your app will tell you which endpoints the server needs, and which parameters need to be sent to it in query strings, form posts, or URLs. It’ll also help define the API for those requests, telling anyone who might work on your production server which keys you expect to correspond to which pieces of data.&lt;/p&gt;

&lt;p&gt;Having a server to work with is especially nice if you’re in the business of making asynchronous requests. Obviously, you can get your mockup data, which is excellent, but you can also lazy-load assets like templates or stylesheets to consume that data. Testing the process of getting data and assets to the client validates your assumptions about not only the way you’re packaging them, but how you’re storing and structuring them. And, of course, it means a lot less wasted client-side JavaScript.&lt;/p&gt;

&lt;h2&gt;A mockup you can use&lt;/h2&gt;

&lt;p&gt;The end result of all this should be that you’ve moved all the mockup pieces out of your client-side JavaScript and HTML. You have a Node server that might not match your production framework, but does have clear definitions of everything the client side expects to exist—possibly even all viewable in a single file. You have templates and client-side requests that may require substitutions, but also separate your data from everything else and are at minimum easily convertible to whatever format is needed for production.&lt;/p&gt;

&lt;p&gt;Could you do the same with any other server under the sun? Absolutely. But if you already know JavaScript and aren’t aiming to become a server-side developer, it makes sense to use the skills you already have. Node makes that pretty easy, while also letting you dig as deeply as you want into more complex servers, should your ambitions change. It’s simple to get going and flexible to extend, making Node an awesome tool for designing applications.&lt;/p&gt;

&lt;p&gt;Ready to take your new Node skills for a spin? In &amp;ldquo;&lt;a href="http://alistapart.com/article/node-at-work-a-walkthrough/"&gt;Node at Work: A Walkthrough&lt;/a&gt;,&amp;rdquo; I’ll take you through a live demo, and get specific about how to refine your own mockups.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/abridged/~4/JIuRksQbUN4" height="1" width="1"/&gt;</description>
      <dc:subject />
      <dc:date>2013-04-30T12:00:42+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/even-better-in-browser-mockups-with-node.js</feedburner:origLink></item>
    
    <item>
      <title><![CDATA[Node at Work: A Walkthrough]]></title>
      <link>http://feedproxy.google.com/~r/alistapart/abridged/~3/1XsqLkwaSO8/node-at-work-a-walkthrough</link>
      <guid isPermaLink="false">http://alistapart.com/article/node-at-work-a-walkthrough</guid>
      <description>&lt;p&gt;In my first article, “&lt;a href="http://alistapart.com/article/even-better-in-browser-mockups-with-node.js"&gt;Even Better In-Browser Mockups with Node.js&lt;/a&gt;,” I explained why Node.js makes designing applications easier and more efficient, and how to get started. Now it’s time to see your new design process in action.&lt;/p&gt;

&lt;p&gt;Rather than figuring out all your requirements and API schemas just to design your comps with mockup content hard-coded and server interactions faked—only to throw it all away when you go back and implement things “for real”—you can use Node.js to skip the hard-coding and produce client-side code that’s ready for beta at the end of the design stage.&lt;/p&gt;

&lt;p&gt;The process looks a lot like good ol’ &lt;a href="/article/responsive-comping-obtaining-signoff-with-mockups"&gt;designing in the browser&lt;/a&gt;, but with more JavaScript and an additional layer:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Design the layout and styling&lt;/li&gt;
&lt;li&gt;Convert the markup to a JavaScript template&lt;/li&gt;
&lt;li&gt;Create an initialization function&lt;/li&gt;
&lt;li&gt;Create a simple Node.js server&lt;/li&gt;
&lt;li&gt;Add a mockup data object to the server&lt;/li&gt;
&lt;li&gt;Add server functions to serve static pages and JSON&lt;/li&gt;
&lt;li&gt;Request and consume the JSON on the client&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sound daunting? Don’t worry. The first step takes approximately a zillion times longer than any of the others. So if you’ve already mastered the design, you’ll find the rest of these steps more than manageable.&lt;/p&gt;

&lt;p&gt;In this walkthrough, we’ll build a feature for a mock art store. If you want to follow along at home, you can clone my &lt;a href="https://github.com/garann/coolartstore"&gt;GitHub repository&lt;/a&gt;. (If you need help installing, see the &lt;a href="https://github.com/garann/coolartstore/blob/master/README.md"&gt;README&lt;/a&gt;, or just take a peek at the &lt;a href="http://coolartstore.rs.af.cm/"&gt;live demo&lt;/a&gt;—I’ll cover all the steps and code below.)&lt;/p&gt;

&lt;h2&gt;Creating templates&lt;/h2&gt;

&lt;p&gt;Once you have a solid design and the markup to accompany it, converting it to a template you can use for all examples is more efficient than creating duplicate markup for each one. The hard part’s over; you already thought about where data points would be used in the design when you created it. With those choices fresh in your mind, go back and mark up your HTML with data in whatever template language you prefer.&lt;/p&gt;

&lt;p&gt;For my example, I’m using a store selling art prints. Here’s a snippet of my initial markup:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;h2&amp;gt;Two Acrobats with a Dog&amp;lt;/h2&amp;gt;
&amp;lt;h3&amp;gt;Pablo Picasso&amp;lt;/h3&amp;gt;
&amp;lt;img src=&amp;quot;img/102.jpg&amp;quot; alt=&amp;quot;Two Acrobats with a Dog&amp;quot; class=&amp;quot;active&amp;quot; /&amp;gt;
&amp;lt;ul class=&amp;quot;info&amp;quot;&amp;gt;
	&amp;lt;li&amp;gt;8&amp;quot; x 11&amp;quot;&amp;lt;/li&amp;gt;
	&amp;lt;li&amp;gt;acid-free paper&amp;lt;/li&amp;gt;
	&amp;lt;li&amp;gt;suitable for matting&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;span class=&amp;quot;price&amp;quot;&amp;gt;$49.99&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Think of your templates as places to define your requirements for both data and its formatting on the client side. If you can also reuse it for client-side rendering, that’s awesome—but that may not be relevant to your application. As long as you have good data, converting from one template language to another is trivial, so don’t agonize over which template engine to use.&lt;/p&gt;

&lt;p&gt;You do need a template engine that will work in both the browser and Node.js, however. If you’re unsure, search for your template engine on &lt;a href="https://github.com/"&gt;GitHub&lt;/a&gt; and verify that there’s a guide to installing it via &lt;a href="https://npmjs.org/"&gt;npm&lt;/a&gt; in the manual, as well as a minified script for use on the client. I prefer &lt;a href="http://olado.github.io/doT/index.html"&gt;doT.js&lt;/a&gt;, so here’s that snippet again marked up to add data using doT:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;h2&amp;gt;{{=it.title}}&amp;lt;/h2&amp;gt;
&amp;lt;h3&amp;gt;{{=it.artist.name}}&amp;lt;/h3&amp;gt;
&amp;lt;img src=&amp;quot;img/{{=it.id}}.jpg&amp;quot; alt=&amp;quot;{{=it.title}}&amp;quot; class=&amp;quot;active&amp;quot; /&amp;gt;
&amp;lt;ul class=&amp;quot;info&amp;quot;&amp;gt;
	{{~it.info :info_item}}
	&amp;lt;li&amp;gt;{{=info_item}}&amp;lt;/li&amp;gt;
	{{~}}
&amp;lt;/ul&amp;gt;
&amp;lt;span class=&amp;quot;price&amp;quot;&amp;gt;{{=it.price}}&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I like to save my templates in their own directory at the same level as my JavaScript directory, so now I store that as &lt;code&gt;tmpl/detail.dot&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Initializing the client&lt;/h2&gt;

&lt;p&gt;Since we want to be able to use our templates in both Node and the browser, they need to be stored outside of the HTML and loaded and compiled when we open the page. To start, save the minified version of your template engine and add a script tag to your page to include it. Once that’s done, you can fetch the template, compile it, and then continue on with any other initialization work in your main JavaScript file. I’m using jQuery in my example, so my code looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var detailTmpl;

$.when( 
	$.get( &amp;quot;tmpl/detail.dot&amp;quot;, function( tmpl ) {
		detailTmpl = doT.template( tmpl );
	}, &amp;quot;text&amp;quot; ) 
).then( init );&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That mysterious &lt;code&gt;init&lt;/code&gt; function? That’s where I’ll put any interactivity I want to add to my currently static mockup. For the moment I’m only creating one interaction, so my &lt;code&gt;init&lt;/code&gt; function is pretty simple:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function init() {
	$( &amp;quot;div.content&amp;quot; ).on( &amp;quot;click&amp;quot;, &amp;quot;div.result&amp;quot;, showDetail );
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This code can be made much more elegant using &lt;a href="http://requirejs.org/"&gt;Require.js&lt;/a&gt; with its text plugin. That’s beyond the scope of this demo, but I highly encourage it for production.&lt;/p&gt;

&lt;p&gt;We’ll handle template rendering in &lt;code&gt;showDetail()&lt;/code&gt;, but we have to add a server and data store before writing that function, since right now we lack any data &lt;em&gt;to&lt;/em&gt; render.&lt;/p&gt;

&lt;h2&gt;Creating a server&lt;/h2&gt;

&lt;p&gt;If I reload my page now and open the browser console, I get a JavaScript error. That’s because I’m trying to load my template via an XMLHttpRequest (XHR) on a page being served from the file system, in violation of the &lt;a href="http://en.wikipedia.org/wiki/Same_origin_policy"&gt;same origin policy&lt;/a&gt;. I can’t even check that my template works until the page is served properly (i.e., from a server).&lt;/p&gt;

&lt;p&gt;To whip up a simple Node server that allows me to run my XHRs, I do a few things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Move all my existing assets into a new subdirectory called &lt;code&gt;public&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Open my terminal or command line to my working directory and run &lt;code&gt;npm install express&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add a server.js file to the working directory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We could write everything from scratch, of course, but it’s more work than is necessary for a basic server. The &lt;a href="http://expressjs.com/"&gt;Express&lt;/a&gt; framework provides a number of abstractions of server and application concepts. For the initial version of the server, the only one we’ll need is its ability to serve static resources. We can use it by adding four lines of code to &lt;code&gt;server.js&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var express = require( &amp;quot;express&amp;quot; ),
	app = express();

app.use( express.static( __dirname + &amp;quot;/public&amp;quot; ) );

app.listen( 3000 );&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once you start your server by typing &lt;code&gt;node server.js&lt;/code&gt; in your open terminal or command line, you can view your page at http://localhost:3000 (adding a filename if necessary), and the error related to loading the template ought to disappear.&lt;/p&gt;

&lt;h2&gt;Adding server-side data&lt;/h2&gt;

&lt;p&gt;While it’s certainly nice to be able to use XHRs, we&amp;#8217;re creating the Node server to use it as a representation of the real server—and real servers store data. Though it’s not hard to create a data store that works with a Node server, it’s even less difficult to create one big &lt;a href="https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Values,_variables,_and_literals?redirectlocale=en-US&amp;amp;redirectslug=Core_JavaScript_1.5_Guide/Values,_Variables,_and_Literals%23Object_literals"&gt;object literal&lt;/a&gt;. For a mockup, that’s all we really need. One of the goals here is to define the data objects we need to support in our new design, so the format of this object can be determined by the template we just added. For my example, I need an object structured something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var products = {
	&amp;quot;102&amp;quot;: {
		id: 102,
		title: &amp;quot;Two Acrobats with a Dog&amp;quot;,
		artist: {
			name: &amp;quot;Pablo Picasso&amp;quot;
		},
		price: &amp;quot;$49.99&amp;quot;,
		info: [
			&amp;quot;8\&amp;quot; x 11\&amp;quot;&amp;quot;,
			&amp;quot;acid-free paper&amp;quot;,
			&amp;quot;suitable for matting&amp;quot;
		]
	}
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that &lt;code&gt;products&lt;/code&gt; could just as easily be an array, but I want to be able to quickly find my products—once I have more than one in my fake data store—by ID. Aside from that little twist, the data look exactly like the content hard-coded in my original HTML. If I want to add more data, including things that might break the layout in unpredictable ways, I can just copy this structure and make substitutions. Well, almost.&lt;/p&gt;

&lt;h2&gt;Returning data from the server&lt;/h2&gt;

&lt;p&gt;If you’ve dealt with other server-side frameworks, creating endpoints for XHRs might seem intimidating, but Express makes it really easy. We don’t need any special setup to define a server endpoint as a target for asynchronous requests. All we have to do is define the path on the server where we want to accept requests and a callback. The callback receives a request object (for doing things like getting passed-in data) and a response object (for defining what we return to the client). To return the data in my products object, I add a few lines of code at the bottom of server.js:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;app.get( &amp;quot;/detail/:id&amp;quot;, function( req, res ) {
	res.send( products[ req.params.id ] );
});

app.listen( 3000 );&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;See? Easy. If I restart my server and go to http://localhost:3000/detail/102, I should see my object data. To break down what’s going on with the ID in the path, we’ve named the data at that position in the path &amp;quot;id&amp;quot; with the &lt;code&gt;:id&lt;/code&gt; bit, and it then becomes available as a property of &lt;code&gt;req.params&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The names and positions of parameters are up to us, and if our path were super complex, we could also use regular expressions to split out multiple pieces of data. Express also gives us the option of accepting data from the query string or from a POST. Of all the pieces we’re creating, however, the paths are the most likely to change in production, so it’s to our advantage to keep them as readable as possible.&lt;/p&gt;

&lt;p&gt;Besides sending pure data to the client, we also want to be able to send rendered HTML, in case a user is linked directly to a product detail or doesn’t have JavaScript available. We might also want HTML for our own consumption via XHR, if we find that client-side rendering is slowing us down. So we add a second endpoint below the one we just created to do that:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;app.get( &amp;quot;/product/:id&amp;quot;, function( req, res ) {
	res.render( &amp;quot;detail&amp;quot;, products[ req.params.id ] );
});&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For simplicity’s sake, and because the first path served JSON for an overlay while this provides a full page, I’ve used a different pathname, but kept the same pattern. This time, instead of the response’s send function, I use &lt;code&gt;render()&lt;/code&gt;. Express provides some magic to make template rendering work out of the box, but since I’m using doT instead of Jade (the default template engine of Express), I have to do some additional setup.&lt;/p&gt;

&lt;p&gt;First I have to go back to the terminal or command line, stop my Node server, and install my template engine using &lt;code&gt;npm install doT&lt;/code&gt; and the consolidate module (which provides Express compatibility for a number of popular template engines) using &lt;code&gt;npm install consolidate&lt;/code&gt;. Now I’ve got both of those in my &lt;code&gt;node_modules&lt;/code&gt; directory and can use them in &lt;code&gt;server.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Since doT (and probably your template engine of choice, as well) is accessed through consolidate, consolidate is the only additional module I need to require at the top of &lt;code&gt;server.js&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var express = require( &amp;quot;express&amp;quot; ),
	app = express(),
	cons = require( &amp;quot;consolidate&amp;quot; );&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I want to continue serving some of my other pages statically, so I add my template configuration stuff below the existing &lt;code&gt;app.use&lt;/code&gt; line in my code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;app.use( express.static( _dirname + &amp;quot;/public&amp;quot; ) );
app.engine( &amp;quot;dot&amp;quot;, cons.dot );
app.set( &amp;quot;view engine&amp;quot;, &amp;quot;dot&amp;quot; );
app.set( &amp;quot;views&amp;quot;, _dirname + &amp;quot;/public/tmpl&amp;quot; );&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Those three new lines set doT (as exposed by consolidate) as the view engine, register files ending in &lt;code&gt;.dot&lt;/code&gt; as templates, and tell Express to look in &lt;code&gt;/public/tmpl&lt;/code&gt; for templates to use. So when Node sees &lt;code&gt;res.render( &amp;quot;detail&amp;quot;, { ... } )&lt;/code&gt;, it knows to expand &lt;code&gt;&amp;quot;detail&amp;quot;&lt;/code&gt; to &lt;code&gt;/public/tmpl/detail.dot&lt;/code&gt; and render it as a doT template. Now I can restart my server, go to http://localhost:3000/product/102, and see my template rendered statically, without creating a separate server-side file.&lt;/p&gt;

&lt;h2&gt;Fetching dynamic data&lt;/h2&gt;

&lt;p&gt;Our template now works as a static page, but there’s still one more step to get our mockup populated with the data from the server. Remember the &lt;code&gt;showDetail&lt;/code&gt; function from our main client-side script? It’s time to flesh that out.&lt;/p&gt;

&lt;p&gt;In my simple example, the overlay my template will populate already exists as a hidden &lt;code&gt;div&lt;/code&gt; on the main page, and it appears when the user clicks a &lt;code&gt;div&lt;/code&gt; containing a summary of the content. This div has a data attribute storing the ID of the product that corresponds to the key and id property in my server-side data object. Once that click event happens and &lt;code&gt;showDetail()&lt;/code&gt; is called, I just need to do this: &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function showDetail( e ) {
	var id = $( this ).data( &amp;quot;id&amp;quot; );
	$.get( &amp;quot;detail/&amp;quot; + id, function( info ) {
		$( &amp;quot;div.detail&amp;quot; ).html( detailTmpl( info ) );
		$( &amp;quot;div.detail&amp;quot; ).show();
	}
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The path above is the same one I defined in &lt;code&gt;server.js&lt;/code&gt;. If you chose a different name for yours, use that name here on the client. When I receive the data object from the server, I pass it to &lt;code&gt;detailTmpl()&lt;/code&gt;, the compiled version of my template. The result of the &lt;code&gt;detailTmpl&lt;/code&gt; function is the HTML to populate my overlay.&lt;/p&gt;

&lt;h2&gt;Onward&lt;/h2&gt;

&lt;p&gt;So there you have it! A mockup that mimics the interactions it will have with its production server precisely on the client, without the need for hard-coded data or temporary workarounds. Despite the simple exercise, the process I’ve outlined accomplishes a good deal of the setup necessary to create other workflows that require server interactions. For instance, I can fill my fake data store with more products and use that to render the initial page that triggers my overlay without having to revisit my mockup data, and my application will show the correct values in any view I add to it.&lt;/p&gt;

&lt;p&gt;If you’d like to explore beyond just serving HTML and JSON, consider adding in &lt;a href="http://socket.io"&gt;Socket.io&lt;/a&gt; to allow real-time interaction for multiple clients or Require.js to manage your assets on the client. You could also move your CSS into templates and serve different builds of your site for different browsers or devices. Your mockup can be as sophisticated and reflect as many of its production requirements as you choose. At the end, the lion’s share of your client-side code is done and ready to use.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/abridged/~4/1XsqLkwaSO8" height="1" width="1"/&gt;</description>
      <dc:subject />
      <dc:date>2013-04-30T12:00:51+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/node-at-work-a-walkthrough</feedburner:origLink></item>
    
	
	    <item>
      <title><![CDATA[The W3C on Web Standards: Digital Publishing and the Web]]></title>
      <link>http://feedproxy.google.com/~r/alistapart/abridged/~3/9z7R6z4TcQk/digital-publishing-and-the-web</link>
      <guid isPermaLink="false">http://alistapart.com/column/digital-publishing-and-the-web</guid>
      <description>&lt;p&gt;Electronic books are on the rise everywhere. For some this threatens centuries-old traditions; for others it opens up new possibilities in the way we think about information exchange in general, and about books in particular. Hate it or love it: electronic books are with us to stay.&lt;/p&gt;

&lt;p&gt;A &lt;a href="http://libraries.pewinternet.org/2012/12/27/e-book-reading-jumps-print-book-reading-declines/"&gt;press release&lt;/a&gt; issued by the &lt;a href="http://www.pewinternet.org/"&gt;Pew Research Center’s Internet &amp;amp; American Life Project&lt;/a&gt; in December 2012 describes an upward trend in the consumption of electronic books. The trends are similar in the UK, China, Brazil, Japan, and other countries.&lt;/p&gt;&lt;figure class="quote"&gt;
&lt;blockquote&gt;
“…the number of Americans over age 16 reading eBooks rose in 2012 from 16 to 23 percent, while those reading printed books fell from 72 percent to 67. …the number of owners of either a tablet computer or e-book reading device such as a Kindle or Nook grew from 18% in late 2011 to 33% in late 2012. …in late 2012 19% of Americans ages 16 and older own e-book reading devices such as Kindles and Nooks, compared with 10% who owned such devices at the same time last year.” 
&lt;/blockquote&gt;
&lt;/figure&gt;
&lt;p&gt;What does this mean for web professionals? Electronic books represent a market that&amp;#8217;s powered by  core web technologies such as HTML, CSS, and SVG. When you use EPUB, one of the primary standards for electronic books, you are creating a packaged website or application. &lt;a href="http://www.idpf.org/epub/30/spec/epub30-overview.html"&gt;EPUB3&lt;/a&gt; is at the bleeding edge of current web standards: it is based on HTML5, CSS2.1 with some CSS3 modules, SVG, OpenType, and WOFF. EPUB3’s embrace of scripting is sure to encourage the development of more interactivity, which is sought after in education materials and children’s books.&lt;/p&gt;

&lt;p&gt;Recently W3C has been &lt;a href="http://www.w3.org/2012/08/electronic-books/"&gt;working more closely&lt;/a&gt; with digital publishers to find out what else the Open Web Platform must do to meet that industry’s needs.&lt;/p&gt;

&lt;p&gt;One comment we’ve heard loud and clear is that people care deeply about centuries-old print traditions. For example, Japanese and Korean users have accepted that many websites display text horizontally, from left to right. While that may be ok for the web, when these users read a novel, they expect traditional layout: characters rendered vertically and from right to left. Japanese readers often find it more tiring to read a long text in any other way. To address these requirements, W3C is looking at the challenges that vertical layout poses for HTML, CSS, and other technologies; see for example &lt;a href="http://www.w3.org/TR/css3-writing-modes/"&gt;CSS Writing Modes Module Level 3&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.w3.org/TR/jlreq/"&gt;Requirement of Japanese Text Layout&lt;/a&gt; summarizes the typesetting traditions and resulting requirements for Japanese. These traditions should eventually be reproduced on the web as well as in electronic books. In June, W3C will hold a digital publishing workshop in Tokyo on the specific issues surrounding &lt;a href="https://www.w3.org/2013/06/ebooks/"&gt;internationalization and electronic books&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We have also heard that the “page” paradigm—including notions of headers, footnotes, indexes, glossaries, and detailed tables of contents—is important when people read books of hundreds or thousands of pages. Web technology will need to reintegrate these UI elements smoothly; see for example the &lt;a href="http://www.w3.org/TR/css3-page/"&gt;CSS Paged Media Module Level 3&lt;/a&gt; (Joe Clark talked about &lt;a href="http://alistapart.com/article/ebookstandards"&gt;paged media and the production of ebooks&lt;/a&gt; in 2010, and Nellie McKesson &lt;a href="http://alistapart.com/article/building-books-with-css3"&gt;gave us an update&lt;/a&gt; in 2012). In September in Paris, W3C will hold a workshop on the &lt;a href="http://www.w3.org/2012/12/global-publisher/"&gt;&lt;i&gt;creation&lt;/i&gt; of electronic books&lt;/a&gt; using web technologies. Note that both this and the Writing Modes Module are still drafts and need further work. That means now is the right time for the digital publishing community to have its voice heard!&lt;/p&gt;

&lt;p&gt;In the realm of metadata, important to publishers, librarians, and archivists, the challenge is to agree on vocabulary (and there are many: Harvard&amp;#8217;s &lt;a href="http://hul.harvard.edu/ois/digproj/metadata-standards.html"&gt;reference to metadata standards&lt;/a&gt; is only the tip of the iceberg). Pearson Publishing recently launched the &lt;a href="http://www.w3.org/community/opened/"&gt;Open Linked Education Community Group&lt;/a&gt; to examine creating a curated subset of Wikipedia data that can be used for tagging educational content.&lt;/p&gt;

&lt;p&gt;Here are a few other places to look for activity and convergence:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;People take notes in books and highlight text. Most ebook readers these days have built-in support for these features, but they are not widely deployed on the web.&lt;/li&gt;
&lt;li&gt;Today search engines tend to ignore electronic books; I expect that will not remain the case for long.&lt;/li&gt;
&lt;li&gt;“Offline mode” in web technology is still difficult to use if you try to access more than a single page of a site. Since an ebook is quite often a packaged website, ebook offline mode will need to improve to support browsing.&lt;/li&gt;
&lt;li&gt;ebooks business models are likely to drive new approaches to monetization, some of which may be found in native mobile environments but not yet on the web.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Although publishing has some specific requirements not common to the web generally, I think that the distinction between a website (or app) and an ebook will disappear with time. As I have &lt;a href="http://ivan-herman.name/2013/02/22/browsers-and-ebook-readers/"&gt;written before&lt;/a&gt;, both will demand high-quality typography and layout, interactivity, linking, multimedia, offline access, annotations, metadata, and so on. Digital publishers’ interest in the Open Web Platform is a natural progression of their embrace of the early web.&lt;br /&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/abridged/~4/9z7R6z4TcQk" height="1" width="1"/&gt;</description>
      <dc:subject />
      <dc:date>2013-04-25T12:29:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/column/digital-publishing-and-the-web</feedburner:origLink></item>
	
	    <item>
      <title><![CDATA[David Sleight on New-School Publishing: Passing On Our Rights]]></title>
      <link>http://feedproxy.google.com/~r/alistapart/abridged/~3/zFA4cDzzVJY/passing-on-our-rights</link>
      <guid isPermaLink="false">http://alistapart.com/column/passing-on-our-rights</guid>
      <description>&lt;p&gt;Last month, a U.S. District Court handed down a decision that’s pretty awful if you care about consumer rights and digital content.&lt;/p&gt;

&lt;p&gt;It all started in 2011, when a company called ReDigi launched a service to let folks resell their unwanted iTunes purchases—the digital equivalent of unloading your old vinyl at a swap meet. This annoyed the legal department at Capitol Records enough that they sued ReDigi in federal court to stop it. Unfortunately for consumers, Capitol Records succeeded. This isn’t just bad news for ReDigi though. What’s really troubling is the court’s take on current copyright protections.&lt;/p&gt;

&lt;h2&gt;The ReDigi case&lt;/h2&gt;

&lt;p&gt;When it comes to the CDs, DVDs, and paper books you own, U.S. law is clear. A legal concept called the &lt;a href="http://en.wikipedia.org/wiki/First-sale_doctrine"&gt;first-sale doctrine&lt;/a&gt; establishes your right to sell them to another person, provided you&amp;#8217;re handing over the item you originally bought, and that you didn’t make any copies. That&amp;#8217;s the idea behind garage sales, swap meets, and Craigslist. As repeated by &lt;a href="http://www.scribd.com/doc/133450332/Capitol-Records-v-ReDigi-Judgment"&gt;the court’s own decision&lt;/a&gt; in the ReDigi case, first-sale doctrine states:&lt;/p&gt;

&lt;figure class="quote"&gt;&lt;blockquote&gt;&lt;p&gt;“The owner of a particular copy or phonorecord lawfully made&amp;#x2026;, or any person authorized by such owner, is entitled, without the authority of the copyright owner, to sell or otherwise dispose of the possession of that copy or phonorecord.”&lt;/p&gt;
&lt;/blockquote&gt;&lt;/figure&gt;

&lt;p&gt;That “owner” is you. The “copyright owner” is the record label, movie studio, or publisher. They make it. You buy it. You can sell it to somebody else if you don’t want it anymore. Simple. But according to this court, you don’t have that right if you send that movie, song, or book over an electronic network when you resell it.&lt;/p&gt;

&lt;p&gt;Wait a minute. How’d that happen?&lt;/p&gt;

&lt;p&gt;In the district court’s view, any transfer that takes place via the internet creates a reproduction of the work on the receiving machine, a new physical object that is “embodied” on the buyer’s hard drive. And that constitutes an illegal copy. In the judge’s own words:&amp;nbsp; &lt;br /&gt;
&lt;!-- CMOS 13.16 In some legal writing, textual commentary, and other contexts, it is considered obligatory to indicate any change in capitalization by brackets. This is the reason David used brackets; no doubt it's not obligatory for ALA, but... --&gt;&lt;/p&gt;&lt;figure class="quote"&gt;&lt;blockquote&gt;&lt;p&gt;[W]hen a user downloads a digital music file or “digital sequence” to his “hard disk,” the file is “reproduce[d]” on a new phonorecord within the meaning of the Copyright Act. Id.&lt;/p&gt;

&lt;p&gt;This understanding is, of course, confirmed by the laws of physics. It is simply impossible that the same “material object” can be transferred over the Internet. Thus, logically,&amp;#x2026; the Internet transfer of a file results in a material object being “created elsewhere at its finish.”&lt;/p&gt;
&lt;/blockquote&gt;&lt;/figure&gt;&lt;!-- Escaped ellipsis because I wasn't sure if the key combo I knew (opt-semicolon) was creating a French suspension point or an ellipsis. --&gt;

&lt;p&gt;Yeah, you read that right. According to this decision, electronic transfers generate a new “material object” on the receiving device. In legal terms, that’s a copy, and a violation of copyright law.&lt;/p&gt;

&lt;p&gt;Even when products like ReDigi’s take reasonable measures to remove the file from the seller’s hard drive as it’s transferred, the court says it doesn’t count. Because I can’t physically hand you the original item over an electronic network, they say all bets are off.&lt;/p&gt;

&lt;h2&gt;The implications&lt;/h2&gt;

&lt;p&gt;This creates a world where we’re barred from ever transferring digital goods we own to another person if we use an electronic network. Insert internet, lose first-sale rights. The &lt;a href="http://www.techdirt.com/articles/20080508/1119441065.shtml"&gt;jury is still out&lt;/a&gt; on whether this interpretation really works from a legal standpoint. The scope of court decisions on copyright are typically papercut-narrow and excruciatingly literal. But the U.S. District Court for the Southern District of New York isn’t really the one causing all the trouble here. The main culprit is the law itself.&lt;/p&gt;

&lt;p&gt;The copyright law at play in &lt;i&gt;Capitol Records v ReDigi&lt;/i&gt; &lt;!-- Should it be a cite? --&gt; predates the digital world by decades, and still talks about usage rights strictly in terms of “material objects.” It doesn’t recognize a difference between photocopying a printed book and reconstructing one from a set of bit-flipping instructions. The letter of the law hasn’t caught up with the reality we live in. Right now it’s Zoolander smashing a tangerine iMac, hoping a bunch of paper files spill out.&lt;/p&gt;

&lt;p&gt;That might not seem like a big deal now. But outdated laws aren’t just discordant with the times, they’re minefields filled with unintended consequences. Just think about your web browser. Anyone want to chat with the district court about the “material objects” a typical browser cache leaves on your hard drive? Unless you feel like upending some of the basic mechanics of the internet, I’d rather you didn&amp;#8217;t.&lt;/p&gt;

&lt;p&gt;And what happens as we shift to a future where the majority of our access to content is digital? Will we see the shuttering of all secondary resale markets? Who gains and who loses from that? If I can’t transfer the digital goods I own over the network, what happens when I die? Will my executor have to ship my hard drive to my next of kin because she couldn’t transmit its contents to them without risking legal action?&lt;/p&gt;

&lt;h2&gt;Fixing this mess&lt;/h2&gt;

&lt;p&gt;So far we’ve largely ducked these questions by letting content companies push us toward rental/lease models online, where we constantly pay and repay for content without enjoying full rights of ownership. That’s okay for some things. But by ignoring the bigger picture on ownership, we leave ourselves open to even further reductions in the consumer rights we’ve enjoyed for decades on movies, music, and books. We need to avoid a world where the only right we have left is the right of refusal.&lt;/p&gt;

&lt;p&gt;Fixing the language of creaky old laws takes legislators, not courts. But we can do better than just petition Congress to drag copyright into the current century. We can set the standard ourselves. As entrepreneurs, developers, and technologists building products around digital content, we can incorporate progressive terms into our services. We can choose to grant users better rights than current law permits by default. We don’t have to sit around waiting for the next ReDigi case to tell us how to treat our customers. We can, and should, do better than that.&lt;/p&gt;

&lt;p&gt;The first-sale doctrine needs to be defended in the digital space. We need acceptable, liveable standards for ownership of digital goods, and we can start building them now.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/abridged/~4/zFA4cDzzVJY" height="1" width="1"/&gt;</description>
      <dc:subject><![CDATA[<a href="/topic/content">Content</a>, <a href="/topic/industry-business">Industry & Business</a>]]></dc:subject>
      <dc:date>2013-04-18T12:30:02+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/column/passing-on-our-rights</feedburner:origLink></item>
	
	    <item>
      <title><![CDATA[Cennydd Bowles on UX & Design: Hellish Other People]]></title>
      <link>http://feedproxy.google.com/~r/alistapart/abridged/~3/pen0wN5d1JA/hellish-other-people</link>
      <guid isPermaLink="false">http://alistapart.com/column/hellish-other-people</guid>
      <description>&lt;p&gt;Childish, inaccurate, bizarre, and condescending? Perhaps—but you can’t just ignore articles like that. Tomas Chamorro-Premuzic’s &lt;a href="http://blogs.hbr.org/cs/2013/04/seven_rules_for_managing_creat.html"&gt;Seven Rules for Managing Creative People&lt;/a&gt;&lt;sup data-footnote&gt;1&lt;/sup&gt; has caused some serious ripples. The article sets lofty standards for missing the point, misrepresenting creative industries to the point of infantilization. At its nadir—“Creatives enjoy making simple things complex, rather than vice versa”—it ranks among the most baffling things ever written about creativity.&lt;/p&gt;

&lt;p&gt;Commenters have heaped scorn on poor Chamorro-Premuzic, to the extent that I must almost apologize for adding to the criticism. But I’m intrigued by the views that prop up articles like this. Why do these misconceptions about creative work persist in an era of supposed innovative enlightenment?&lt;/p&gt;

&lt;p&gt;The premise that underpins this and many similar articles is that creativity is a binary property: some people are blessed (or cursed) with it, others aren’t. This establishes a subtle, unwelcome construct. Creative types are “The Other”: fundamentally irregular people who don’t quite gel with the rest of society (“The Same”). Indeed, what it means to be Same is usually defined in part by not being Other.&lt;/p&gt;

&lt;p&gt;While the language of Otherness is sometimes a deliberate tool of oppression, more often it reflects the unthinking bias of the speaker and era. Chamorro-Premuzic’s framing of creative people as The Other is no doubt unintentional. But the archetype is clear nonetheless.&lt;/p&gt;

&lt;figure class="tweet"&gt;
&lt;blockquote class="twitter-tweet" data-partner="tweetdeck"&gt;&lt;p&gt;Never, ever, ever let them call you a “creative”. It’s a way to be disenfranchised. You are a designer. It’s not magic, it’s a trade.&lt;/p&gt;&amp;mdash; Mike Monteiro (@Mike_FTW) &lt;a href="https://twitter.com/Mike_FTW/status/320929309273493505"&gt;April 7, 2013&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src="//platform.twitter.com/widgets.js" charset="utf-8"&gt;&lt;/script&gt;
&lt;/figure&gt;

&lt;p&gt;On this stage, Chamorro-Premuzic plays the role of ethnographer. Having observed creative people in their natural environments, he uses the article to MBAsplain their aberrant behavior. Rather than recognizing the diverse individuality of creative workers, the author describes them as a homogenous group primarily defined by weakness—a motif that echoes throughout the history of Otherness.&lt;/p&gt;

&lt;p&gt;Chamorro-Premuzic’s creative Other is self-centered and unable to play well with peers. He is “moody, erratic, eccentric, and arrogant.” He is unable to properly explain his process. His motivations are bizarre: money doesn’t matter to him, which at least gives you an opportunity to stiff him on pay. His neuroticism and narcissism make him a poor leader: that&amp;#8217;s best left to the Sames.&lt;/p&gt;

&lt;p&gt;Thankfully, the premise is flawed. Creativity is not a binary ability but a muscle that needs exercise. There is no Same and Other, no us and them; everyone has creative capacity. Personality, environment, and other pressures of life mean that some people do have less creative experience, but with simple tools—a pencil, a guitar, a hobby—it’s not hard to reverse the atrophy.&lt;/p&gt;

&lt;p&gt;Modern creative work demands diverse perspectives. To suggest instead that it emanates from the abracadabras of an eccentric elite does a disservice to all parties. The article argues that companies should pass “trivial or meaningless work” to the clock-watchers who lack intrinsic motivation. In other words, some people are best handling the drudgery, while the unmanageables get the rewarding work to keep them quiet.&lt;/p&gt;

&lt;p&gt;This situation, dare I say, could use some creative thinking. It can’t be healthy to encourage a cycle of disinterested employees and futile effort. Better to look closely at user needs, explore ideas that address them, and build a team that is inspired by those goals. Then no work should be meaningless.&lt;/p&gt;

&lt;p&gt;So how can we counter the assertion that creative workers think and behave the same? By highlighting the diversity of our personalities and methods.&lt;/p&gt;

&lt;p&gt;Both &lt;a href="http://www.markboulton.co.uk/journal/quietlyworking"&gt;Mark Boulton&lt;/a&gt; and &lt;a href="http://the-pastry-box-project.net/chris-coyier/2013-april-3/"&gt;Chris Coyier&lt;/a&gt; have recently written about their introversion and how it affects their creative approaches. These are important, refreshing viewpoints, and no doubt many readers will identify with them. I too have noticed the subtle assumptions some people make about creative workers. Extraversion and arrogance are often presupposed.&lt;/p&gt;

&lt;p&gt;Earlier in my career, bosses and peers encouraged me to use collaborative, extravert-friendly tools like design games. I never felt particularly comfortable with them, but persisted, believing them to be techniques that designers were meant to enjoy.&lt;/p&gt;

&lt;p&gt;I’ve since realized these aren’t the right tools for me, at least for today. I’m more comfortable working with trusted teammates in managed environments, delving into people’s expectations, and exploring initial concepts alone. It was a relief to free myself from the process expectations of others, and I believe my results testify for my new approach.&lt;/p&gt;

&lt;p&gt;After the lashing the article received in the comments, perhaps Chamorro-Premuzic will pause to reflect on his opinions. Perhaps the &lt;cite&gt;Harvard Business Review&lt;/cite&gt; will also look more closely at its editorial policy, and consider whether it fell a little out of step with its audience. But there will be plenty more articles that treat creativity like a disorder, and more executives who brand creative workers as vain and immature.&lt;/p&gt;

&lt;p&gt;With diversity issues rightly making headlines in our industry, we should also rejoice in the multitude of personalities and approaches that make up our disciplines. We are, of course, the best placed people of all to counter harmful stereotypes. Only variety can break us out of the Otherness box.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/abridged/~4/pen0wN5d1JA" height="1" width="1"/&gt;</description>
      <dc:subject><![CDATA[<a href="/topic/industry">Industry</a>, <a href="/topic/creativity">Creativity</a>]]></dc:subject>
      <dc:date>2013-04-11T11:30:39+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/column/hellish-other-people</feedburner:origLink></item>
	
		
    <item>
      <title><![CDATA[Growing Your Design Business]]></title>
      <link>http://feedproxy.google.com/~r/alistapart/abridged/~3/msjRGo00BH4/growing-your-design-business</link>
      <guid isPermaLink="false">http://alistapart.com/article/growing-your-design-business</guid>
      <description>&lt;p&gt;So you’ve launched your own creative business, and you’re starting to grow. That’s great! But good growth won’t just &lt;em&gt;happen&lt;/em&gt;. Just like a junior designer starts with small projects and slowly builds her skills, a new business needs time to mature, test new ideas, and prepare itself, too.&lt;/p&gt;

&lt;p&gt;How did you gain the design chops that got you where you are today? With study, practice, and testing, I imagine. Business owners learn their trade the same way: by taking general business wisdom, applying it to their specific niche, and working diligently until they get it right. &lt;/p&gt;

&lt;p&gt;If you want to grow in a sustainable, satisfying way, then you need to pay attention to how you’re growing, not just how much. After all, a bigger company isn’t necessarily a better one. Let’s look at four common pitfalls of growth in the design industry, and how to avoid them.&lt;/p&gt;

&lt;h2&gt;The wrong clients&lt;/h2&gt;

&lt;p&gt;As a business owner, you might assume you should serve everyone you can. Busy is good, right? In reality, taking on every client who’ll hire you is actually detrimental to your growth, and not strategic at all.&lt;/p&gt;

&lt;p&gt;The more bad clients you try to serve, the less time you have to look for good clients. This is dangerous. It’s like feng shui: You have to move the bad ones out so the good ones can come in. &lt;/p&gt;

&lt;p&gt;But what makes a good client? Your goals and expertise might give you more specific criteria, but all good clients share three traits: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;They understand your value and let you remain in control of the design process as the professional.&lt;/li&gt;
&lt;li&gt;They are enjoyable to work with.&lt;/li&gt; 
&lt;li&gt;They are profitable.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Firing clients (further, keeping the wrong clients out of your company in the first place) is one thing that sets strategic business owners apart from those who struggle through growth. This is a little scary to implement, but letting the bad clients move on to another home will be one of the most important things you can do to grow your company—and not just because they take up time. &lt;/p&gt;

&lt;p&gt;Whether your clients are good or bad, you can bet that they will send you more clients just like themselves. If you give discounts to one client, then new clients could show up at your door looking for discounts. On the flip side, if you are treating clients well, doing good work, and getting paid well for it, then new clients will show up expecting to pay for the privilege of working with you. &lt;/p&gt;

&lt;p&gt;Growing with the wrong clients is unintentional growth, and it actually hurts your good clients, too. When you are loaded down with clients you can never please, you can’t give enough attention to the very clients that will appreciate your excellent service. And when a good client doesn’t understand why you can’t find time to return their calls, they will leave.&lt;/p&gt;

&lt;h2&gt;Hiring for hiring’s sake&lt;/h2&gt;

&lt;p&gt;You might think that staff growth is good, but size alone is no strategy. Hire employees to serve great clients, rather than taking clients in order to pay employees.&lt;/p&gt;

&lt;p&gt;Growing to simply reach a size often puts you in the poor position of having to farm out busywork to unchallenged employees. Busywork blunts an employee’s passion and makes her wonder if she is doing anything of value—beyond bringing another dollar into your business, that is. It’s hard to get excited about work like that. &lt;/p&gt;

&lt;p&gt;Bad clients and busywork lead to high employee turnover—because your best employees know they don’t have to put up with your poor decisions. And employee instability can, in turn, atrophy your client list. Give the employees some control over whom your company serves. For example, if you have a method of tracking all incoming new client requests, go over these with your team in a weekly meeting to flesh out who would be good for your company. Or, share your “good client” criteria with your team, ask for their input, and discuss whether everyone currently on your client roster fits the bill.&lt;/p&gt;

&lt;p&gt;Including your team in these intimate parts of your company will make talented employees more passionate and happier. Happy clients will be the result! &lt;/p&gt;

&lt;p&gt;Employees long for a business owner who manages growth strategically. One way to bless your employees and feed their passion for their work is to focus on a niche. This will in turn mean you must hire the right team to work on that niche. Niche work, as opposed to serving anyone anywhere, lets you hire the best designers, who expect better work conditions, higher pay, and more creative freedoms—passionate professionals who want to work with only the best clients.&lt;/p&gt;

&lt;h2&gt;Growing too fast&lt;/h2&gt;

&lt;p&gt;Newer design companies often struggle to manage their tacit, undocumented knowledge—like where files are stored or how project handoffs happen.&amp;nbsp; When your company is new, it’s challenging to maintain developed systems that can handle large amounts of growth in small periods of time. Along with nurturing great designers, take time to develop internal systems like mature project management systems and wise account managers. &lt;/p&gt;

&lt;p&gt;Every time you onboard a new customer, you will add to your tacit knowledge about your pricing and your customer experience processes. You need to be able to apply that knowledge to the next client you bring in. This is hard to do when you are growing too fast. If you are a new owner, fight to keep your growth slow. Once you have more mature systems, you can pick up your pace. &lt;/p&gt;

&lt;p&gt;Once you reach a certain level of size, you also need more help to grow. This can be a surprise to many business owners. More specifically, once you reach somewhere around five to ten employees, non-owner leaders need to be identified to help you continue managing the work and the growth. Now your company needs to continue its growth, often without the owner controlling the full process. Your internal processes will be tested during this phase. As an owner, you must transition out of technical work so you can be available to move into a role of leading and coaching your team as they take on new roles in helping the company grow.&lt;/p&gt;

&lt;p&gt;Since you need to hire the best employees and can’t afford to let customer service slip while you do it, you’ll also find you need to hire new people just &lt;em&gt;before&lt;/em&gt; you need them. But in order to hire early, you’ll need precious cash on hand to buy enough time to find the right clients to match your new hires. If you don’t have the cash reserves to get through this adjustment period, then you could be overburdened with a huge payroll and not enough of the right clients to pay it.&lt;/p&gt;

&lt;h2&gt;Low margins&lt;/h2&gt;

&lt;p&gt;High-margin work frees you from stressing over the basic needs of the business—like worrying about making payroll, or paying contractors and vendors on time. A profit margin is the total amount your client paid you, less the specific salaries or contractors needed to produce the work, less the products or additional services you had to purchase to serve the client. Profit margin is different from gross revenue. Profit margin is a minimalistic view of how profitable each job is. Gross revenue, on the other hand, is the total income your company is making, before accounting for costs.&lt;/p&gt;

&lt;p&gt;In the profit margin calculation, ignore insurance, rent, taxes, and all of the stuff you can’t do anything about. These expenses do not factor into the calculation of a profit margin, because you can’t control them. Just focus on the few controllable costs needed to perform that specific job for that specific client. Low-margin work means you are pricing your services too close to the costs you’ll have to bear in order to serve that client.&lt;/p&gt;

&lt;p&gt;For example, if you price your services at $100,000, and your salaries and contractors cost you $80,000 and your miscellaneous costs (fonts, hosting, and stuff like that) are $5,000, then you are dealing with a small profit margin of $15,000. This is a 15 percent profit margin. Is that enough? That is something you must decide, but I can tell you from experience that the smart design businesses my accounting firm works with are experiencing between 70 and 90 percent profit margins, and I would expect at least a 50 percent margin from our clients.&lt;/p&gt;

&lt;p&gt;Margins matter. Low-margin work could have unintended consequences, like leaving you in debt to cover living costs and the owners’ salaries. This is very dangerous. Though it is a fearful thing to do at first, pricing your services high enough to fund profitable growth, and being committed to high-margin growth, will help your design company prosper. &lt;/p&gt;

&lt;p&gt;Committing to only taking high-profit work also lets you offer attractive salaries, provide good workspaces and tools, and invest in employee education. In essence, you can’t build the world-class team you need without high profit margins. &lt;/p&gt;

&lt;h2&gt;Good growth can be yours&lt;/h2&gt;

&lt;p&gt;So maybe you’ve grown, but have you prospered? Not if you’ve allowed your company to be sidelined by the four growth pitfalls above. Growth doesn’t happen by default. It can only happen by design. It takes a lot of work, and demands keeping your growth patterns in check every step of the way. Be watchful for the pitfalls and run the other way. Your clients, your team, and your profitability will thank you.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/abridged/~4/msjRGo00BH4" height="1" width="1"/&gt;</description>
      <dc:subject />
      <dc:date>2013-04-09T12:00:26+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/growing-your-design-business</feedburner:origLink></item>
    
    <item>
      <title><![CDATA[Hack Your Maps]]></title>
      <link>http://feedproxy.google.com/~r/alistapart/abridged/~3/_uJXTg6Bqzs/hack-your-maps</link>
      <guid isPermaLink="false">http://alistapart.com/article/hack-your-maps</guid>
      <description>&lt;p&gt;Web maps have come a long way. Improved data, cleaner design, better performance, and more intuitive controls have made web maps a ubiquitous and critical component of many apps. They&amp;#8217;ve also become one of the mobile space&amp;#8217;s most successful transplants as more and more apps are powered by location-aware devices. The core web map UI paradigm itself—a continuous, pannable, zoomable surface—has even spread beyond mapping to interfaces everywhere.&lt;/p&gt;

&lt;p&gt;Despite all this, we&amp;#8217;ve barely begun to work web maps into our design practice. We create icon fonts, responsive grids, CSS frameworks, progressive enhancement strategies, and even new design processes. We tear down old solutions and build new ones, and even take an extra second to share battle stories in prose and in person. Yet nearly five years since Paul Smith&amp;#8217;s article, &amp;#8220;&lt;a href="/article/takecontrolofyourmaps"&gt;Take Control of Your Maps&lt;/a&gt;,&amp;#8221; web maps are still a blind spot for most designers.&lt;/p&gt;

&lt;p&gt;Have you ever taken apart a map? Worked with a map as a critical part of your design? Developed tricks, hacks, workarounds, or progressive enhancements for maps?&lt;/p&gt;

&lt;p&gt;This article is a long overdue companion to Paul&amp;#8217;s piece. Where he goes on a whirlwind survey of the web mapping stack at 10,000 feet, we&amp;#8217;re going to walk through a single design process and implement a modern-day web map. By walking this path, I hope to begin making maps part of the collective conversation we have as designers.&lt;/p&gt;

&lt;h2&gt;Opinionated about open&lt;/h2&gt;

&lt;p&gt;Paul makes a strong case for why you might want to use open mapping tools instead of the established incumbent. I won&amp;#8217;t retread his reasons here, but I would like to expand on his last: Open tools are the ones we hack best.&lt;/p&gt;

&lt;p&gt;There is nothing mysterious about web maps. Take any spatial plane, split it up into discrete tiles, position them in the DOM, and add event handlers for panning and zooming. The basic formula can be applied to Portland, Mars, or Super Mario Land. It works for displaying large street maps, but nothing stops us from tinkering with it to explore galleries of art, create fictional game worlds, learn human anatomy, or simply navigate a web page. Open tools bare the guts of this mechanism to us, allowing us to see a wider range of possibilities.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="http://d.alistapart.com/373/examples.png" alt="The variety of web maps: character navigation, Mars, and Super Mario Land."&gt;
&lt;figcaption&gt;The mechanics of web maps are not limited to street maps.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;We should know the conditions under which map images are loaded and destroyed; we should argue whether map tiles are best positioned with CSS transforms or not; and we should care whether vector elements are drawn with SVG or Canvas. Open tools let us know and experiment with these working details of our maps. If you wouldn&amp;#8217;t have it any other way with your HTML5, CSS, or JavaScript libraries, then you shouldn&amp;#8217;t settle for less when it comes to maps.&lt;/p&gt;

&lt;p&gt;In short, we&amp;#8217;ll be working with a fully open mapping stack. &lt;a href="http://mapbox.com/"&gt;MapBox&lt;/a&gt;, where I work, has pulled together several open source libraries into a single API that we publish under &lt;a href="http://github.com/mapbox/mapbox.js"&gt;mapbox.js&lt;/a&gt;. Other open mapping libraries that are worth your time include &lt;a href="http://leafletjs.com/"&gt;Leaflet&lt;/a&gt; and &lt;a href="http://d3js.org/"&gt;D3.js&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Starting out&lt;/h2&gt;

&lt;p&gt;I&amp;#8217;m a big fan of Sherlock Holmes. Between the recent Hollywood movies starring Robert Downey Jr. and the BBC&amp;#8217;s contemporary series, I&amp;#8217;m hooked. But as someone who has never been to London, I know I&amp;#8217;m missing the richness of place and setting that Sir Arthur Conan Doyle meant to be read into his short stories.&lt;/p&gt;

&lt;p&gt;A typical approach would be to embed a web map with pins of various locations alongside one of the Sherlock stories. With this approach the map becomes an appendix—a dispensable element that plays little part in Doyle&amp;#8217;s storytelling. Instead, we&amp;#8217;re going to expand the role of our map, integrating it fully into the narrative. It will set the stage, provide pace, and affect the mood of our story.&lt;/p&gt;

&lt;figure&gt;&lt;img src="http://d.alistapart.com/373/fig1-appendix.png" alt="Comparing a map used as embedded media versus one used as a critical design element."&gt;
&lt;/figure&gt;

&lt;h2&gt;A tale of places&lt;/h2&gt;

&lt;p&gt;To establish a baseline for our tale, I restructured &lt;cite&gt;The Adventure of the Bruce-Partington Plans&lt;/cite&gt; to be told around places. I picked eight key locations from the &lt;a href="http://www.gutenberg.org/files/2346/2346-h/2346-h.htm"&gt;original text&lt;/a&gt;, pulled out the essential details of the mystery, and framed them out with HTML, CSS, and JavaScript.&lt;/p&gt;

&lt;figure&gt;
&lt;a href="http://mapbox.com/tutorial-sherlock/step1-story.html"&gt;&lt;img src="http://d.alistapart.com/373/step1-story.png" alt="Text only demo."&gt;&lt;/a&gt;
&lt;figcaption&gt;A Sherlock Holmes story in text only. View &lt;a href="http://mapbox.com/tutorial-sherlock/step1-story.html"&gt;Demo 1&lt;/a&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;ul&gt;
&lt;li&gt;The story is broken up into &lt;code&gt;section&lt;/code&gt; elements for each key location. A small amount of JavaScript implements a scrolling flow that highlights a single section at a time.&lt;/li&gt;
&lt;li&gt;Our page is not responsive yet, but it contains scaffolding to guard against bad choices that could thwart us. The main text column is fluid at &lt;code&gt;33.33%&lt;/code&gt; and pins to a &lt;code&gt;min-width: 320px&lt;/code&gt;. If our content and design flow reasonably within these constraints, we&amp;#8217;re in good shape.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, we&amp;#8217;ll get started mapping. Initially we&amp;#8217;ll work on our map separately from our story page to focus on learning key elements of a new technology.&lt;/p&gt;

&lt;h2&gt;Maps are data&lt;/h2&gt;

&lt;p&gt;The mapping equivalent of our abridged Sherlock story is a dataset of eight geographic points. GeoJSON, a format for describing geographic data in JSON, is the perfect starting point for capturing this data:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
    &amp;quot;geometry&amp;quot;: { &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;, &amp;quot;coordinates&amp;quot;: [-0.15591514, 51.51830379] },
    &amp;quot;properties&amp;quot;: { &amp;quot;title&amp;quot;: &amp;quot;Baker St.&amp;quot; }
}, {
    &amp;quot;geometry&amp;quot;: { &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;, &amp;quot;coordinates&amp;quot;: [-0.07571203, 51.51424049] },
    &amp;quot;properties&amp;quot;: { &amp;quot;title&amp;quot;: &amp;quot;Aldgate Station&amp;quot; }
}, {
    &amp;quot;geometry&amp;quot;: { &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;, &amp;quot;coordinates&amp;quot;: [-0.08533793, 51.50438536] },
    &amp;quot;properties&amp;quot;: { &amp;quot;title&amp;quot;: &amp;quot;London Bridge Station&amp;quot; }
}, {
    &amp;quot;geometry&amp;quot;: { &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;, &amp;quot;coordinates&amp;quot;: [0.05991101, 51.48752939] },
    &amp;quot;properties&amp;quot;: { &amp;quot;title&amp;quot;: &amp;quot;Woolwich Arsenal&amp;quot; }
}, {
    &amp;quot;geometry&amp;quot;: { &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;, &amp;quot;coordinates&amp;quot;: [-0.18335806, 51.49439521] },
    &amp;quot;properties&amp;quot;: { &amp;quot;title&amp;quot;: &amp;quot;Gloucester Station&amp;quot; }
}, {
    &amp;quot;geometry&amp;quot;: { &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;, &amp;quot;coordinates&amp;quot;: [-0.19684993, 51.5033856] },
    &amp;quot;properties&amp;quot;: { &amp;quot;title&amp;quot;: &amp;quot;Caulfield Gardens&amp;quot; }
}, {
    &amp;quot;geometry&amp;quot;: { &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;, &amp;quot;coordinates&amp;quot;: [-0.10669358, 51.51433123] },
    &amp;quot;properties&amp;quot;: { &amp;quot;title&amp;quot;: &amp;quot;The Daily Telegraph&amp;quot; }
}, {
    &amp;quot;geometry&amp;quot;: { &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;, &amp;quot;coordinates&amp;quot;: [-0.12416858, 51.50779757] },
    &amp;quot;properties&amp;quot;: { &amp;quot;title&amp;quot;: &amp;quot;Charing Cross Station&amp;quot; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Each object in our JSON array has a &lt;code&gt;geometry&lt;/code&gt;—data that describe where this object is in space—and &lt;code&gt;properties&lt;/code&gt;—freeform data of our own choosing to describe what this object is. Now that we have this data, we can create a very basic map.&lt;/p&gt;

&lt;figure&gt;
&lt;a href="http://mapbox.com/tutorial-sherlock/step2-map.html"&gt;&lt;img src="http://d.alistapart.com/373/step2-map.png" alt="Basic web mapping demo."&gt;&lt;/a&gt;
&lt;figcaption&gt;The basics of web mapping. View &lt;a href="http://mapbox.com/tutorial-sherlock/step2-map.html"&gt;Demo 2&lt;/a&gt;. &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;ul&gt;
&lt;li&gt;Note that the coordinates are a pair of latitude and longitude degrees. In the year 2013, it is still not possible to find a consistent order for these values across mapping APIs. Some use &lt;code&gt;lat,lon&lt;/code&gt; to meet our expectations from grade-school geography. Others use &lt;code&gt;lon,lat&lt;/code&gt; to match x,y coordinate order: horizontal, then vertical.&lt;/li&gt;
&lt;li&gt;We&amp;#8217;re using &lt;a href="http://github.com/mapbox/mapbox.js"&gt;mapbox.js&lt;/a&gt; as our core open source mapping library. Each map is best understood as the key parameters passed into &lt;code&gt;mapbox.map()&lt;/code&gt;:

&lt;ol&gt;
&lt;li&gt;A DOM element container&lt;/li&gt;
&lt;li&gt;One or more Photoshop-like &lt;em&gt;layers&lt;/em&gt; that position tiles or markers&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Event handlers&lt;/em&gt; that bind user input to actions, like dragging to panning&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;Our map has two layers. Our tile layer is made up of 256x256 square images generated from a custom map on MapBox. Our spots layer is made up of pin markers generated from the GeoJSON data above.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a good start for our code, but nowhere near our initial goal of using a map to tell our Sherlock Holmes story.&lt;/p&gt;

&lt;h2&gt;Beyond location&lt;/h2&gt;

&lt;p&gt;According to our first map, the eight items in our GeoJSON dataset are just places, not settings in a story full of intrigue and mystery. From a visual standpoint, pins anonymize our places and express them as nothing more than locations.&lt;/p&gt;

&lt;p&gt;To overcome this, we can use illustrations for each location—some showing settings, others showing key plot elements. Now our audience can see right away that there is more to each location than its position in space. As a canvas for these, I&amp;#8217;ve created another map with a custom style that blends seamlessly with the images.&lt;/p&gt;

&lt;figure&gt;
&lt;a href="http://mapbox.com/tutorial-sherlock/step3-markers.html"&gt;&lt;img src="http://d.alistapart.com/373/step3-markers.png" alt="Web map with illustrations."&gt;&lt;/a&gt;
&lt;figcaption&gt;Illustrations and a custom style help our map become part of the storytelling. View &lt;a href="http://mapbox.com/tutorial-sherlock/step3-markers.html"&gt;Demo 3&lt;/a&gt;, and then read the &lt;a href="https://github.com/mapbox/tutorial-sherlock/compare/step2-map&amp;#8230;step3-markers"&gt;diff&lt;/a&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;ul&gt;
&lt;li&gt;The main change here is that we define a custom &lt;em&gt;factory function&lt;/em&gt; for our markers layer. The job of the factory function is to take each GeoJSON object and convert it to a DOM element—an &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;div&lt;/code&gt;, &lt;code&gt;img&lt;/code&gt;, or whatever—that the layer will then position on the map.&lt;/li&gt;
&lt;li&gt;Here we generate &lt;code&gt;div&lt;/code&gt;s and switch from using a &lt;code&gt;title&lt;/code&gt; attribute in our GeoJSON to an &lt;code&gt;id&lt;/code&gt;. This provides us with useful CSS classes for displaying illustrations with our custom markers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Bringing it all together&lt;/h2&gt;

&lt;p&gt;Now it&amp;#8217;s time to combine our story with our map. By using the scroll events from before, we can coordinate sections of the story with places on the map, crafting a unified experience.&lt;/p&gt;

&lt;figure&gt;
&lt;a href="http://mapbox.com/tutorial-sherlock/step4-combined.html"&gt;&lt;img src="http://d.alistapart.com/373/step4-combined.png" alt="Web map coordinated to story text by a scroll handler."&gt;&lt;/a&gt;
&lt;figcaption&gt;As the user reads each section, the map pans to a new location. View &lt;a href="http://mapbox.com/tutorial-sherlock/step4-combined.html"&gt;Demo 4&lt;/a&gt;, then read the &lt;a href="https://github.com/mapbox/tutorial-sherlock/compare/step3-markers&amp;#8230;step4-combined"&gt;diff&lt;/a&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;ul&gt;
&lt;li&gt;The bridge between the story and the map is a revamped &lt;code&gt;setActive()&lt;/code&gt; function. Previously it only set an active class on a particular &lt;code&gt;section&lt;/code&gt; based on scrolling position. Now it also finds the active marker, sets an active class, and &lt;em&gt;eases&lt;/em&gt; the map to the marker&amp;#8217;s location.&lt;/li&gt;
&lt;li&gt;Map animation uses the &lt;em&gt;easey&lt;/em&gt; library in the &lt;code&gt;mapbox.js&lt;/code&gt; API, which implements animations and tweening between geographic locations. The API is dead simple—we pass it the &lt;code&gt;lon,lat&lt;/code&gt; of the marker we want to animate to, and it handles the rest.&lt;/li&gt;
&lt;li&gt;We disable all event handlers on our map by passing an empty array into &lt;code&gt;mapbox.map()&lt;/code&gt;. Now the map can only be affected by the scrolling position. If users wanted to deviate from the storyline or explore London freeform, we could reintroduce event handlers—but in this case, less is more.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Displaying our fullscreen map together with text presents an interesting challenge: our map viewport should be offset to the right to account for our story on the left. The solution I&amp;#8217;m using here is to expand our map viewport off canvas purely using CSS. You could use JavaScript, but as we&amp;#8217;ll see later, a CSS-only approach gives us elegant ways to reapply and adjust this technique on mobile devices.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="http://d.alistapart.com/373/fig2-offset.png" alt="Using an off-canvas map width to offset the viewport center."&gt;
&lt;/figure&gt;

&lt;p&gt;At this stage, our map and story complement each other nicely. Our map adds spatial context, visual intrigue, and an interesting temporal element as it eases between long and short distances.&lt;/p&gt;

&lt;h2&gt;Maps in responsive design&lt;/h2&gt;

&lt;p&gt;The tiled, continuous spatial plane represented by web maps is naturally well-suited to responsive design. Web maps handle different viewport sizes easily by showing a bit more or a bit less map. For our site, we adjust the layout of other elements slightly to fit smaller viewports.&lt;/p&gt;

&lt;figure&gt;
&lt;a href="http://mapbox.com/tutorial-sherlock/step5-responsive.html"&gt;&lt;img src="http://d.alistapart.com/373/step5-responsive.png" alt="Adding a responsive layout."&gt;&lt;/a&gt;
&lt;figcaption&gt;Tweaking layout with web maps. View &lt;a href="http://mapbox.com/tutorial-sherlock/step5-responsive.html"&gt;Demo 5&lt;/a&gt;, then read the &lt;a href="https://github.com/mapbox/tutorial-sherlock/compare/step4-combined&amp;#8230;step5-responsive"&gt;diff&lt;/a&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;ul&gt;
&lt;li&gt;With less screen real estate, we hide non-active text sections and pin the active text to the top of the screen.&lt;/li&gt;
&lt;li&gt;We use the bottom half of the screen for our map and use media queries to adjust the map&amp;#8217;s center point to be three-fourths the height of the screen, using another version of our trick from Demo 4.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With a modest amount of planning and minimal adjustments, our Sherlock story is ready to be read on the go.&lt;/p&gt;

&lt;h2&gt;Solve your own case&lt;/h2&gt;

&lt;p&gt;If you&amp;#8217;ve been following the code between these steps, you&amp;#8217;ve probably noticed at least one or two things I haven&amp;#8217;t covered, like the parameters of &lt;code&gt;ease.optimal()&lt;/code&gt;, or how tooltips picked up on the &lt;code&gt;title&lt;/code&gt; attribute of our GeoJSON data. The devil&amp;#8217;s in the details, so post to this &lt;a href="https://github.com/mapbox/tutorial-sherlock"&gt;GitHub repository&lt;/a&gt;, where you will find the code and the design.&lt;/p&gt;

&lt;p&gt;You should also check out:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;The MapBox site, which includes &lt;a href="http://mapbox.com/developers/guide/"&gt;an overview&lt;/a&gt; of tiling and basic web map concepts, and &lt;a href="http://mapbox.com/mapbox.js/"&gt;MapBox.js&lt;/a&gt; docs and code examples.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://leaflet.cloudmade.com/"&gt;Leaflet&lt;/a&gt;, another powerful open source mapping library.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://d3js.org/"&gt;D3.js&lt;/a&gt;, a library for powering data-driven documents that has a broad range of applications, including mapping.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This example shows just one path to integrating web maps into your designs. Don&amp;#8217;t stick to it. Break it apart. Make it your own. Do things that might be completely genius or utterly stupid. Even if they don&amp;#8217;t work out, you&amp;#8217;ll be taking ownership of maps as a designer—and owning something is the only way we&amp;#8217;ll improve on it.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/abridged/~4/_uJXTg6Bqzs" height="1" width="1"/&gt;</description>
      <dc:subject />
      <dc:date>2013-04-09T12:00:10+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/hack-your-maps</feedburner:origLink></item>
    
	
	    <item>
      <title><![CDATA[Nick Sherman on Typography: Responsive Typography is a Physical Discipline, But Your Computer Doesn’t Know It (Yet)]]></title>
      <link>http://feedproxy.google.com/~r/alistapart/abridged/~3/OQ5b7MXWe4o/responsive-typography-is-a-physical-discipline</link>
      <guid isPermaLink="false">http://alistapart.com/column/responsive-typography-is-a-physical-discipline</guid>
      <description>&lt;p&gt;For ideal typography, web designers need to know as much as possible about each user’s reading environment. That may seem obvious, but the act of specifying web typography is currently like ordering slices of pizza without knowing how large the slices are or what toppings they are covered with.&lt;/p&gt;

&lt;p&gt;If someone asked me how many slices of pizza I wanted for lunch, I would probably say it depends on how large the slices are. Then—even if they told me that each slice was one eighth of a whole pie, or that they themselves were ordering two slices, or even that the slices were coming from Joe’s Pizza—any answer I might give would still be based on relative knowledge and inexact assumptions.&lt;/p&gt;

&lt;p&gt;Such is the current situation with the physical presentation of responsive typography on the web. The information at a designer’s disposal for responsive design is virtually nonexistent outside the realm of software. Very little knowledge about the physical presentation of content is available to inform the design. The media query features of today can only relay a very fragmented view of the content’s actual presentation, and related terms from &lt;abbr&gt;CSS&lt;/abbr&gt; are confusing if not downright misleading.&lt;/p&gt;

&lt;h2&gt;The immeasurable pachyderm&lt;/h2&gt;

&lt;p&gt;Among all the physical qualities of web typography, the elephant in the room is the issue of &lt;em&gt;size&lt;/em&gt;. I’m not talking about &lt;code&gt;em&lt;/code&gt; or &lt;code&gt;rem&lt;/code&gt; or “reference pixels”&lt;sup id="ref1"&gt; &lt;a href="#note1"&gt;¹&lt;/a&gt;&lt;/sup&gt; or even device pixels. I’m talking about real, actual, physical, bona fide, measurable, &lt;strong&gt;size!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s ridiculous that we can send robots to Mars yet it’s still virtually impossible to render a glyph on a web page and say with confidence: “If you measure this glyph on your screen with a ruler, it will be exactly 10 millimeters wide.” Although actual physical size isn’t always the most important factor in web design, in some cases it is critical. For example, consider content for partially-sighted or low-vision readers: the ability to tweak designs according to physical sizes would enable designers to make conscious design decisions with much more sensitivity to how the type is actually being seen. And even where physical sizing is secondary to relative sizing, why shouldn’t we nevertheless be able to factor in physical size when establishing the relationships between different elements?&lt;/p&gt;

&lt;h2&gt;Physical considerations ≠ print design&lt;/h2&gt;

&lt;p&gt;I don’t believe web typography should be a screen-based imitation of print typography. One of the greatest benefits of web typography, and web design in general, is that it is flexible, adaptable, fluidly adjustable, without being locked into any one specific configuration. However(!), that doesn’t mean web designers should be forced to design without any means to address the issues of physical presentation. On the contrary, responsive design will not reach its full potential until it allows the ability to respond to the very important physical variables of digital media.&lt;/p&gt;

&lt;p&gt;Please pardon the cliché, but when it comes to typography, on screens or otherwise, &lt;em&gt;size matters&lt;/em&gt;. Physical size affects optical issues that change how the eye and brain process typographic images. Not surprisingly, typographers and typeface designers have been &lt;a href="http://alistapart.com/column/font-hinting-and-the-future-of-responsive-typography/#figure2"&gt;compensating for optical size-related issues&lt;/a&gt; as far back as Gutenberg.&lt;/p&gt;

&lt;p&gt;You can’t expect a paragraph of type with the same relative line-height, column width, letter-spacing, and glyph proportions to function just as well on two different displays that have the same number of pixels but completely different physical sizes. It’s great that designers can adjust proportions between typographic elements if the canvas varies in &lt;em&gt;relative&lt;/em&gt; size, but any such compensation is still based on guesswork and assumptions about the &lt;em&gt;physical&lt;/em&gt; size of that canvas. When people disagree about the size or spacing of type on a website, there’s a very good chance that their opinions are based on completely different physical manifestations of the same content, even if their software and settings are identical.&lt;/p&gt;

&lt;h2&gt;Resolute resolution, absolute absolution&lt;/h2&gt;

&lt;p&gt;One of the most crucial factors in the size equation is &lt;em&gt;resolution&lt;/em&gt;. And when I say resolution, I don’t just mean “how many pixels is this?”, or even “how many &lt;em&gt;device&lt;/em&gt; pixels is this?”, but also “how large are these pixels?”&lt;/p&gt;

&lt;p&gt;This is very different from the &lt;abbr&gt;W3C&lt;/abbr&gt;’s “&lt;a href="http://dev.w3.org/csswg/mediaqueries4/#resolution"&gt;resolution&lt;/a&gt;” media feature in the current draft of the &lt;cite&gt;Media Queries Level 4&lt;/cite&gt; spec. You will note that the spec refers to resolution in terms of “&lt;abbr&gt;CSS&lt;/abbr&gt; ‘inches’”—the quotes around “inches” are theirs, implying that they are not actually inches at all.&lt;/p&gt;

&lt;p&gt;For an example of why physical resolution matters, imagine you are rendering text on a digital billboard with a physical resolution of one pixel per inch (1 &lt;abbr title="pixel per inch"&gt;PPI&lt;/abbr&gt;). Now imagine you are rendering the same text on a 200 &lt;abbr title="pixels per inch"&gt;PPI&lt;/abbr&gt; mobile device display. Even if you knew the actual number of device pixels that would be used to render your type (which itself is difficult to do with confidence these days), you would want to treat the two compositions very differently, both in terms of the typeface as well as typographic layout. The billboard type would likely require less space between letters. The letterforms themselves would benefit from narrower proportions, and could endure a higher ratio between thick and thin strokes. The type might even require different colors to optimize contrast at that size. These are all basics of typography and typeface design.&lt;/p&gt;

&lt;p&gt;Unfortunately, in the current landscape of media query features, there is no way to know the difference between 16 device pixels on a crude &lt;abbr title="light emitting diode"&gt;LED&lt;/abbr&gt; billboard and 16 device pixels on a high-density mobile display. Heck, there isn’t even a reliable way to know if your type is 16 device pixels at all, regardless of how large the pixels are!&lt;/p&gt;

&lt;h2&gt;Pixels still rule, for better or worse&lt;/h2&gt;

&lt;p&gt;I know what some &lt;code&gt;em&lt;/code&gt;-based enthusiasts might be thinking: “But you shouldn’t be specifying type sizes in pixel units to start with! All type sizes should be spec’d abstractly in relation to each other or a base font size!” However, in the current world of web typography, no matter what unit of measure you use to spec your onscreen type sizes—&lt;code&gt;em&lt;/code&gt;, &lt;code&gt;rem&lt;/code&gt;, &lt;code&gt;px&lt;/code&gt;, &lt;code&gt;pt&lt;/code&gt;, &lt;code&gt;in&lt;/code&gt;, &lt;code&gt;%&lt;/code&gt;, &lt;code&gt;vh&lt;/code&gt;, or whatever else—at the end of the line, your specification is being mapped to pixels. Even if you &lt;a href="http://filamentgroup.com/lab/how_we_learned_to_leave_body_font_size_alone/"&gt;leave the base size of your document to the defaults&lt;/a&gt; and specify everything else with &lt;code&gt;em&lt;/code&gt;, there is still a base size which all other sizes will ultimately refer to, and it is defined in pixels.&lt;/p&gt;

&lt;p&gt;This is because, currently, the only unit of measure that can be rendered onscreen by any operating system with absolute confidence is the lowly pixel. Until we have media query features that allow us to spec for situations like:&lt;/p&gt;

&lt;pre&gt;@media (physical-resolution: 1device-pixels-per-physical-inch) { … }&lt;/pre&gt;

&lt;p&gt;or:&lt;/p&gt;

&lt;pre&gt;@media (device-width: 10physical-centimeters) { … }&lt;/pre&gt;

&lt;p&gt;… any compensation for physical size is based entirely on rough guesses about the devices our content will be presented on.&lt;sup id="ref2"&gt;&lt;a href="#note2"&gt;²&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;It’s a complete fallacy that the official &lt;abbr&gt;CSS&lt;/abbr&gt; spec allows so-called “&lt;a href="http://www.w3.org/TR/css3-values/#absolute-lengths"&gt;absolute&lt;/a&gt;” units of measure like inches, points, and centimeters to be mapped to anything but actual physical units. Ironically, previous versions of &lt;abbr&gt;CSS&lt;/abbr&gt; treated these things as you would hope and expect, but a change was made “because too much existing content relies on the assumption of 96dpi, and breaking that assumption breaks the content.” Call me idealistic if you will, but I am more of the mind that a spec should be written based on what is best for the future, not to cater to things that were made in the past.&lt;sup id="ref3"&gt;&lt;a href="#note3"&gt;³&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;h2&gt;Getting physical&lt;/h2&gt;

&lt;p&gt;Any ability to leverage physical variables for web design will require a joint effort by several groups:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Device manufacturers&lt;/strong&gt; will need to provide &lt;abbr title="application programming interface"&gt;API&lt;/abbr&gt;s that can inform the operating system—and, by extension, web browsers and web designers—of the actual physical properties of the hardware being used to present content to the user. &lt;a href="http://alistapart.com/article/environmental-design-with-the-device-api"&gt;Some device &lt;abbr title="application programming interface"&gt;API&lt;/abbr&gt;s&lt;/a&gt; are already beginning to show up in the world, but there is a long way to go before functionality and adoption are anywhere near dependable.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Standards organizations&lt;/strong&gt;—the &lt;abbr&gt;W3C&lt;/abbr&gt; in particular—will need to establish specifications for how to reference physical properties when formatting content. They will need to update (or at least augment) their existing “absolute” units of measure to be more meaningful, so they are more than just multipliers of sizeless pixels.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Software manufacturers&lt;/strong&gt; will need to implement support for new specs relating to physical media features. Browsers are the most obvious software that will need to implement support, but the biggest challenge might be in getting native support for device APIs in operating system software.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Type manufacturers&lt;/strong&gt; and type services will need to provide more diverse ranges of typefaces that have been optimized for a variety of physical properties. Ideally, many of the needed variations could even be provided on the fly using a &lt;a href="http://alistapart.com/column/font-hinting-and-the-future-of-responsive-typography"&gt;broader approach to the ideas of font hinting&lt;/a&gt;.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Web designers and developers&lt;/strong&gt;, last but not least, will need to build their sites to respond to physical properties, leveraging all variables to the benefit of their users.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Size and resolution are just the tip of the iceberg of physical variables that could be considered when improving web typography. Things like viewing distance, ambient light, display luminance, contrast ratio, black levels, etc., etc., could all be factored in to improve the reading experience. Even the ability to know some variables within the realm of software, like the user’s rendering engine or the presence of subpixel positioning, would go a long way toward helping web typographers design a better reading experience.&lt;/p&gt;

&lt;p&gt;In the meantime, I’d love to see more of the players mentioned above start to at least experiment with what&amp;#8217;s possible when physical features can be specified, detected, and factored into responsive designs in structured, meaningful, and predictable ways. Until we can do that, we’re all just ordering pizza without knowing exactly what will end up on our plate.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/abridged/~4/OQ5b7MXWe4o" height="1" width="1"/&gt;</description>
      <dc:subject><![CDATA[<a href="/topic/typography-web-fonts">Typography & Web Fonts</a>]]></dc:subject>
      <dc:date>2013-04-04T11:30:41+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/column/responsive-typography-is-a-physical-discipline</feedburner:origLink></item>
	
    
    </channel>
</rss>
