Luxagraf
http://longhandpixels.net/
Latest posts on the LongHandPixels Press Blogen-usCopyright 2012-2014 Scott GilbertsonThu, 27 Feb 2014 12:06:00 GMTThu, 27 Feb 2014 12:06:00 GMThttp://cyber.law.harvard.edu/rss/rss.htmlIPpub v2.0[email protected][email protected]Scaling Responsive Images in CSS
http://longhandpixels.net//blog/2014/02/scaling-responsive-images-css
http://longhandpixels.net//blog/2014/02/scaling-responsive-images-css
<p>It’s pretty easy to handle images responsively with <span class="caps">CSS</span>. Just use <code>@media</code> queries to swap images at various breakpoints in your design.</p>
<p>It’s slightly trickier to get those images to be fluid and scale in between breakpoints. Or rather, it’s not hard to get them to scale horizontally, but what about vertical scaling?</p>
<p>Imagine this scenario. You have a div with a paragraph inside it and you want to add a background using the <code>:before</code> pseudo element — just a decorative image behind some text. You can set the max-width to 100% to get the image to fluidly scale in width, but what about scaling the height?</p>
<p>That’s a bit trickier, or at least it tripped me up for a minute the other day. I started with this:</p>
<pre><code class="language-css">.wrapper--image:before {
content: "";
display: block;
max-width: 100%;
height: 443px;
background-color: #f3f;
background-image: url('bg.jpg');
background-repeat: no-repeat;
background-size: 100%;
}
</code></pre>
<p>Do that and you’ll see… nothing. Okay, I expected that. Setting height to auto doesn’t work because the pseudo element has no real content, which means its default height is zero. Okay, how do I fix that?</p>
<p>You might try setting the height to the height of your background image. That works whenever the div is the size of, or larger than, the image. But the minute your image scales down at all you’ll have blank space at the bottom of your div, because the div has a fixed height with an image inside that’s shorter than that fixed height. Try re-sizing <a href="/demos/css-bg-image-scaling/no-vertical-scaling.html">this demo</a> to see what I’m talking about, make the window less than 800px and you’ll see the box no longer scales with the image.</p>
<p>To get around this we can borrow a trick from Thierry Koblentz’s technique for <a href="http://alistapart.com/article/creating-intrinsic-ratios-for-video/">creating intrinsic ratios for video</a> to create a box that maintains the ratio of our background image. </p>
<p>We’ll leave everything the way it is, but add one line:</p>
<pre><code class="language-css">.wrapper--image:before {
content: "";
display: block;
max-width: 100%;
background-color: #f3f;
background-image: url('bg.jpg');
background-repeat: no-repeat;
background-size: 100%;
padding-top: 55.375%;
}
</code></pre>
<p>We’ve added padding to the top of the element, which forces the element to have a height (at least visually). But where did I get that number? That’s the ratio of the dimensions of the background image. I simply divided the height of the image by the width of the image. In this case my image was 443px tall and 800px wide, which gives us 53.375%.</p>
<p>Here’s a <a href="/demos/css-bg-image-scaling/vertical-scaling.html">working demo</a>.</p>
<p>And there you have it, properly scaling <span class="caps">CSS</span> background images on <code>:before</code> or other “empty” elements, pseudo or otherwise.</p>
<p>The only real problem with this technique is that requires you to know the dimensions of your image ahead of time. That won’t be possible in every scenario, but if it is, this will work.</p>
Thu, 27 Feb 2014 11:56:00 ESTLive Editing Sass in Firefox with Vim Keybindings
http://longhandpixels.net//blog/2014/02/live-editing-sass-firefox-vim-keybindings
http://longhandpixels.net//blog/2014/02/live-editing-sass-firefox-vim-keybindings
<nav class="toc"><h4 class="toc-title">Table of Contents</h4><ul><li><a href="#set-up-sass-editing-in-firefox">Set Up Sass Editing in Firefox.</a><ul><li><a href="#firefox">Firefox</a></li><li><a href="#sass-and-compass">Sass and Compass</a></li><li><a href="#putting-it-all-together">Putting it All Together</a></li></ul></li><li><a href="#vim-or-emacs-keybindings">Vim or Emacs Keybindings</a></li><li><a href="#shortcomings-compared-to-chrome">Shortcomings Compared to Chrome</a></li><li><a href="#further-reading">Further Reading</a></li></ul></nav>
<p>The Firefox developer tools now support <a href="https://hacks.mozilla.org/2014/02/live-editing-sass-and-less-in-the-firefox-developer-tools/">live editing Sass files right in the browser</a>.</p>
<p>This is, like a lot of what Mozilla has been doing lately, a case of Firefox playing catch-up with the competition — Chrome has had similar features for quite some time. </p>
<p>On the other hand, Firefox is ahead of Chrome in another area: <a href="https://developer.mozilla.org/en-US/docs/Tools/Using_the_Source_Editor#Alternative_key_mappings">Vim and Emacs keybindings</a> (which I believe is because the editor in Firefox is based on <a href="http://codemirror.net/">CodeMirror</a>).</p>
<p>If that means nothing to you then stick with Chrome. If, however, you’re loath to abandon the power of Vim or Emacs for editing files in the browser, this means you can have the best of both worlds — live editing Sass files in the browser <em>and</em> Vim or Emacs keybindings.</p>
<p>Because live editing <a href="http://sass-lang.com/">Sass files</a> in the browser with Vim keybindings? That’s some awesome sauce right there.</p>
<p>If you prefer, here’s a screencast walking you through the process. Other wise, read on.</p>
<div class="embed-container-960">
<div class='embed-container'>
<iframe src='https://player.vimeo.com/video/87289985' frameborder='0' webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
</div>
</div>
<h2 id="set-up-sass-editing-in-firefox">Set Up Sass Editing in Firefox.</h2>
<p>The Mozilla Hacks blog posted a <a href="https://hacks.mozilla.org/2014/02/live-editing-sass-and-less-in-the-firefox-developer-tools/">quick overview</a> on how to set things up, but it assumes you’ve already got Sass set up to compile sourcemaps. In case you don’t, here’s some more complete instructions on how to set up Sass and Firefox<sup id="fnref-1"><a class="footnote-ref" href="#fn-1">1</a></sup>.</p>
<h3 id="firefox">Firefox</h3>
<p>First off you need a pre-release version of Firefox. Both the Sass sourcemaps support and the Vim/Emacs keybindings are available starting with Firefox 29. I use the <a href="http://nightly.mozilla.org/">Nightly channel</a> (currently Firefox 30a1), but the <a href="http://www.mozilla.org/en-US/firefox/aurora/">Aurora channel</a> (currently Firefox 29a2) will work as well. </p>
<h3 id="sass-and-compass">Sass and Compass</h3>
<p>The next step is to set up Sass such that it will output a sourcemap file in addition to your <span class="caps">CSS</span>.</p>
<p>What in the world is a sourcemap? Simply put, sourcemaps are a way to map compiled code back to its pre-compiled source. The reason any of this is possible at all is because Sass recently added support for <span class="caps">CSS</span> sourcemaps. That means that when it turns your Sass code into <span class="caps">CSS</span>, Sass also outputs a map of what it did. Firefox can then look at the map and connect the rendered <span class="caps">CSS</span> back to your source Sass. The sourcemap support is brand new and currently only found in the pre-release versions of Sass.</p>
<p>I happen to like the Sass offshoot <a href="http://compass-style.org/">Compass</a> better than vanilla Sass as Compass provides some very handy extras like <span class="caps">CSS</span> 3 prefixing tools. As with Sass, only the pre-release versions of Compass support sourcemaps (and even those are <a href="https://github.com/chriseppstein/compass/issues/1108">not quite there</a>). </p>
<p>Fortunately we can get the pre-release versions of both Sass and Compass with a single command. </p>
<pre><code class="language-bash">$ sudo gem install compass --pre
</code></pre>
<p>This command tells the Ruby gem system that we want the pre-release version of Compass (that’s what the —pre flag is for). In the process we’ll also get the latest version of Sass that works with Compass. </p>
<p>You’re probably used to starting Compass with something like <code>compass watch</code>. Eventually you’ll be able to do that, but for now the only way I’ve been able to get Sass, Compass and sourcemaps working together is by invoking <code>sass</code> directly like so:</p>
<pre><code class="language-bash">`sass --compass --poll --sourcemap --watch sass/screen.scss:screen.css`
</code></pre>
<p>To break that down:</p>
<ol>
<li><code>sass --compass</code> — this bit starts Sass and includes Compass so that we have access to all our extras.</li>
<li><code>--poll</code> — this gets around a super annoying permissions error. This shouldn’t be necessary, but currently it gets around a bug. Alternately you can start <code>sass</code> with <code>sudo</code>.</li>
<li><code>--watch</code> — watch tells sass to watch for changes rather than just compiling once.</li>
<li><code>--sourcemap sass/screen.scss:screen.css</code> — This is the important part. We tell Sass that we want to use sourcemaps and then we create a mapping. In this case I’ve told Sass to make a map explaining how the file screen.scss inside the <code>sass</code> folder turns into the <code>screen.css</code> output file. This is what Firefox will use to map <span class="caps">CSS</span> rules to Sass rules.</li>
</ol>
<p>Sass is now running, watching our files for changes. Now we just need a local server of some kind. I typically use my <a href="http://longhandpixels.net/blog/2013/11/easiest-way-get-started-designing-browser">my python server trick</a> for quick prototyping, but anything will work — local Apache, Nginx, Django development server, whatever development server RoR offers — anything will work.</p>
<h3 id="putting-it-all-together">Putting it All Together</h3>
<p>Now let’s go back to Firefox and let it know about our sourcemap. </p>
<p>Here’s where things are significantly different than Chrome. I’m not sure which is “better” but if you’re used to the Chrome approach, the Firefox approach may seem strange. </p>
<p><img alt="Right click in the CSS field to show original source" class="img-right" src="http://longhandpixels.net/media/images/2014/show_original_sources.jpg">First load your localhost url. Now open the developer tools and inspect some element you want to change. Now all you need to do is right click in the <span class="caps">CSS</span> section of the Inspector tab and choose “Show original sources”. Now click the little link next to the style rules and Firefox will open your Sass file in the Style editor.</p>
<p>Now just hit save, either the link next to the file list or hit <span class="caps">CMD</span>-S (<span class="caps">CTRL</span>-S). The first time you save a file you have to tell Firefox where the file is on your disk — navigate to the folder with your Sass files and hit save, overwriting the original. You’ll need to do this once for each Sass partial that you have, which is annoying if you’ve got a lot. I happen to prefer the Chrome method, which maps the local folder to a local <span class="caps">URL</span>. It’s a bit more work to set up, but you only have to do it once.</p>
<p>Either way though that’s it, you’re done. Edit Sass live in the browser, see your changes update almost instantly with no refresh.</p>
<p>Here’s what it looks like:</p>
<figure aria-labelledby="cap-1" role="group"><a href="http://longhandpixels.net/media/images/2014/smaller-ff-tools.gif" title="View Image"><img alt="Animated gif showing live Sass editing in Firefox" src="http://longhandpixels.net/media/images/2014/smaller-ff-tools.gif"></a><figcaption id="cap-1">
<p>Just right click to change the view from compiled <span class="caps">CSS</span> to <span class="caps">SCSS</span>. Pretty Cool. Note that I’ve already saved the file once so Firefox knows where it is.</p>
</figcaption>
</figure>
<h2 id="vim-or-emacs-keybindings">Vim or Emacs Keybindings</h2>
<p>I know, I know you were only in it for the keybindings, how the heck do you get those?</p>
<p>Pretty simple. Open <code>about:config</code> and search for <code>devtools.editor.keymap</code>. Right click the “value” field and enter either “vim” or “emacs”. I had to restart Firefox for the changes to take effect.</p>
<p>Now you have a way to edit Sass right in the browser and still get the benefit of all the keyboard shortcuts you’ve commited to muscle memory over the years.</p>
<p>There’s one annoying bug (at least I think it’s a bug) for Vim users, <code>:w</code> (the Vim save command) does not work like <span class="caps">CMD</span>-S (<span class="caps">CTRL</span>-S); it will always open the file save dialog box rather than just writing to disk. It’s annoying, but I haven’t found a workaround yet.</p>
<h2 id="shortcomings-compared-to-chrome">Shortcomings Compared to Chrome</h2>
<p>While Firefox’s combo of live editing Sass and Vim keybindings is awesome, there a couple things that I think could be improved.</p>
<p>In Chrome if you <span class="caps">CMD</span>-click (or <span class="caps">CTRL</span>-click) on an individual <span class="caps">CSS</span> rule in the styles tab Chrome jumps you to the relevant file and moves your cursor right to that rule. It even highlights the line in yellow for a second or two so you know where the cursor is in the file. It’s very slick and very useful. <span class="caps">CMD</span>-click a rule in Firefox and nothing special will happen. Bummer. </p>
<p>The other thing that’s troubling me with Firefox is the need to “Save As” the first time you edit a Sass file. It feels janky to me and frankly it’s a pain when your project has dozens and dozens of Sass partials. I much prefer Chrome’s (admittedly perhaps more confusing at first) approach of associating a folder with a <span class="caps">URL</span>.</p>
<p>Still, the Vim keybindings makes me more productive than I can be in Chrome without them so I’m back to Firefox.</p>
<h2 id="further-reading">Further Reading</h2>
<ul>
<li>Mozilla Hack Blog: <a href="https://hacks.mozilla.org/2014/02/live-editing-sass-and-less-in-the-firefox-developer-tools/">Live Editing Sass and Less in the Firefox Developer Tools</a></li>
<li>Tutsplus: <a href="http://code.tutsplus.com/tutorials/developing-with-sass-and-chrome-devtools--net-32805">Developing With Sass and Chrome DevTools</a></li>
<li>Ben Frain: <a href="http://benfrain.com/add-sass-compass-debug-info-for-chrome-web-developer-tools/">Faster Sass debugging and style iteration with source maps, Chrome Web Developer Tools and Grunt</a></li>
<li>Google Developer Docs: <a href="https://developers.google.com/chrome-developer-tools/docs/css-preprocessors">Working with <span class="caps">CSS</span> Preprocessors</a></li>
<li>HTML5Rocks: <a href="http://www.html5rocks.com/en/tutorials/developertools/revolutions2013/#toc-key-performance">Sass/<span class="caps">CSS</span> Source Map debugging</a></li>
</ul>
<div class="footnote">
<hr>
<ol>
<li id="fn-1">
<p>At least here’s how you make it happen for Sass; I know nothing about Less, much less Less with Grunt. If you prefer Less, head over to the <a href="https://hacks.mozilla.org/2014/02/live-editing-sass-and-less-in-the-firefox-developer-tools/">Mozilla Hack blog post</a> and check out their instructions. <a class="footnote-backref" href="#fnref-1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>
Thu, 20 Feb 2014 10:08:00 ESTA Complete Guide to the `<Picture>` Element
http://longhandpixels.net//blog/2014/02/complete-guide-picture-element
http://longhandpixels.net//blog/2014/02/complete-guide-picture-element
<p><em>If you’ve ever struggled building responsive websites, this post is for you. It’s part of a series on responsive design, in particular responsive images, pulled from my book, <a href="http://longhandpixels.net/store/responsive-web-design">Responsive Web Design</a>. If you find this excerpt useful, and want even more ideas on how responsive design can help you create amazing websites, pick up a copy today.</em></p>
<nav class="toc"><h4 class="toc-title">Table of Contents</h4><ul><li><a href="#the-picture-element">The <picture> Element</a></li><li><a href="#awesome-sauce-gimme-some-picture">Awesome Sauce! Gimme Some <picture></a></li><li><a href="#using-the-picture-element-for-high-resolution-images">Using the <picture> Element for High Resolution Images</a></li><li><a href="#different-image-sizes-based-on-viewport-width">Different Image Sizes Based on Viewport Width</a></li><li><a href="#different-image-size-and-resolution-based-on-viewport-width">Different Image Size and Resolution Based on Viewport Width</a></li><li><a href="#solving-the-art-direction-conundrum">Solving the Art Direction Conundrum</a></li><li><a href="#handling-more-complex-scenarios">Handling More Complex Scenarios</a></li><li><a href="#super-awesome-sauce-gimme-some">Super Awesome Sauce! Gimme Some.</a></li></ul></nav>
<p>Most people who’ve never heard the phrase before think that “responsive design” refers to building websites that are, well, responsive. That is, fast pages that respond to user input with no lag or discernable load times.</p>
<p>Of course that’s not exactly what the phrase “responsive design” refers to in most web development contexts, but I think the web might be better off if it were. I don’t think we need to throw out Ethan Marcotte’s original definition of responsive design — fluid grids, flexible images and @media queries — but perhaps we could add another criteria to our definition: responsive websites should, above all else, be <strong>really, really fast</strong>.</p>
<p>There are many, many ways to speed up websites, responsive or otherwise, but few things will lighten the load like reducing image size. If you’ve done nothing yet to optimize the front-end portion of your site, images are almost always the best place to start.</p>
<p>Unfortunately there really is no Platonic ideal for serving up responsive images. My favorite “works today” solution is Matt Wilcox’s <a href="http://adaptive-images.com">Adaptive Images</a> but it doesn’t work in every scenario, nor does it handle <a href="http://usecases.responsiveimages.org">all the possible use cases for responsive images</a>.</p>
<p>A real responsive images solution is going to take more than clever coding. It’s going to have to involve web browsers, web standards bodies <em>and</em> web developers. </p>
<p>Luckily for developers like you and me, browser makers, the <span class="caps">W3C</span> and some very smart web developers have been working on the problem of how to serve the right images to the right device for several years now. So far there have been three big proposals, one of which I’ve covered before in <a href="http://longhandpixels.net/blog/2013/09/responsive-images-srcset">Responsive Images <span class="amp">&</span> srcset</a> (it appears that <code>srcset</code> may <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content-1.html#attr-img-srcset">still become part of <code><img></code></a>). </p>
<p>The other two major proposals have since merged to become what will likely be the best responsive images solution in the future: the proposed <code><picture></code> element.</p>
<h2 id="the-picture-element">The <code><picture></code> Element</h2>
<p>Following the development of <code><picture></code> has been like listening to <a href="https://en.wikipedia.org/wiki/Statler_and_Waldorf">Statler and Waldorf</a> in the <a href="http://www.youtube.com/watch?v=NpYEJx7PkWE">balcony of the Muppet’s theatre</a>: “I love it!” “It’s terrible!” “It’s brilliant!” “It’s okay” “It could be better” “It’s awful!” “I love it!” And so on as developers and browser makers hashed out the details.</p>
<p>As of this writing the general consensus seems to be coalescing somewhere around “I love it!” and “It could be better”. </p>
<p>On a practical level — which is to say, are browsers going to support it? — <code><picture></code>‘s future is looking pretty good. It’s on <a href="https://etherpad.mozilla.org/domwebapi2014q1">Mozilla’s informal roadmap for Q1 of 2014</a> and the Chromium dev team has <a href="http://www.chromestatus.com/features/5910974510923776">started work on support for <code><picture></code></a> (which means it will be in Opera as well). Apple’s WebKit team appears to like the current implementations, though it has yet to commit to anything. The Internet Explorer team, well, who knows? Is there even still an <span class="caps">IE</span> team?</p>
<p>The good news is that <code><picture></code> degrades gracefully to a good old <code><img></code> tag, so older browsers will still display whatever you use for a fallback.</p>
<p>That said, because the spec is barely even at the draft stage, what follows is theory, not cut and paste code. There is no browser support for this. There isn’t even a modified version of Chromium you can test it in<sup id="fnref-1"><a class="footnote-ref" href="#fn-1">1</a></sup>. </p>
<p>Worse, the specifics of <code><picture></code> may well change (if they do I’ll update this post) so don’t go dropping it into your pages just yet. <strong>This tutorial is meant to give you an overview of how <code><picture></code> will work, not provide code you can use today</strong>. You’ve been warned.</p>
<h2 id="awesome-sauce-gimme-some-picture">Awesome Sauce! Gimme Some <code><picture></code></h2>
<p>For better or worse <code><picture></code> follows, at least partly, in the footsteps of <code><audio></code> and <code><video></code>, acting as a container element for <code><source></code> elements which then point to the actual images you want to load. The browser evaluates all the various attributes you’ve specified, picks the best image and then loads the image into the <code><img></code> inside your <code><picture></code> tag. In other words, <code><picture></code> doesn’t actually display your image, it just tells the browser which image to display.</p>
<p>To help the browser pick the best image you have three major components to work with, all attributes of <code><source></code> elements within the <code><picture></code> tag. </p>
<p>The three attributes are: </p>
<ul>
<li><code>srcset</code>: Yes, the same <code>srcset</code> that was <a href="http://longhandpixels.net/blog/2013/09/responsive-images-srcset">originally proposed for the <code><img></code> tag</a>. The <code>srcset</code> attribute gives the browser a list of possible images, along with some (optional) “hints” about the screen resolution and screen size that correspond with each image source.</li>
<li><code>media</code>: The <code>media</code> attribute is where you would put your <code>@media</code> query information. When the <code>@media</code> attribute evaluates to true, the browser then moves to the associated <code>srcset</code>.</li>
<li><code>sizes</code>: The <code>sizes</code> attribute allows you to specify a set of intrinsic sizes for the images described in the srcset attribute. This one is a little tricky at first, but basically it allows you to tell the browser how much of the viewport should be taken up by the image. This will become clearer in the example below.</li>
</ul>
<p>To get a better understanding of how each attribute works, let’s dive into some code.</p>
<h2 id="using-the-picture-element-for-high-resolution-images">Using the <code><picture></code> Element for High Resolution Images</h2>
<p>Let’s start with the first use case in the <a href="http://usecases.responsiveimages.org">responsive images use case list</a>: “<a href="http://usecases.responsiveimages.org/#resolution-based-selection">resolution-based selection</a>“. Essentially we want to serve high-resolution images to high-res devices while allowing low-res devices to avoid the bandwidth penalty of overly-large files.</p>
<p>Here’s how you would use <code><picture></code> to give Retina screens high-res images and regular screens regular images. </p>
<p>Let’s say we’re trying to build a more responsive version of the LongHandPixel’s bookstore. Assuming we have two book cover images for each book — <code>cover1x.jpg</code>, which is a normal resolution image and <code>cover2x.jpg</code> which is the same image, but at a much higher resolution. Let’s go ahead and make things <a href="http://futurefriendlyweb.com">future-friendly</a> by adding a third image, <code>cover4x.jpg</code>, to handle those 4K+ monitors that are just a few years away from being on every desktop. So with three images at three resolutions our <code><picture></code> code would look like this:</p>
<pre><code class="language-markup"><picture>
<source srcset="cover1x.jpg 1x, cover2x.jpg 2x, cover4x.jpg 4x">
<img src="cover1x.jpg" alt="Responsive Web Design cover">
</picture>
</code></pre>
<p>Here we have a simple <code><picture></code> tag with one <code><source></code> tag and an <code><img></code> tag which doubles as a fall back for older browsers. Within the <code><source></code> tag we’ve used the <code>srcset</code> attribute to say to the browser (or “user-agent” in spec-speak) if the screen pixel density is 1x then load <code>cover1x.jpg</code>; if the screen density is 2x then load the higher-resolution <code>cover2x.jpg</code>. Finally, if the screen density is 4x, grab <code>cover4x.jpg</code>. </p>
<p>What happens if the resolution is somewhere in between these values? Well, you could add in other resolutions (e.g. 1.3x, 1.6x and so on) and URLs if you want to be explicit. Remember though that which image to choose is entirely up to the browser. The <code>srcset</code> values we’ve given are described in the spec as “hints”. It may be that, despite having a high-res screen, the user has explicitly instructed the browser (through a preference setting) not to download large images over 3G. </p>
<p>Screen resolution is after all just one factor in deciding on the appropriate image to download. As developers we don’t (and never will) have all the information that the browser does, which is why the final decision lies with the browser. As I’ve said before, this is a good thing; this is exactly the way it should be.</p>
<p>That’s how you would handle the simple resolution-based selection scenario. Before we move on though, let’s look at another value you can add to <code>srcset</code> declarations: width. </p>
<p>Consider this scenario: we have roughly the same situation, we’ll limit it to two images this time, one high-res, one not. But we don’t know how wide the image is going to be on the user’s screen. Say our normal-res image is 640px wide. On a high-res screen that happens to be only 320 effective pixels wide, a 640px image would actually qualify as a high-res image. The situation is slightly more nuanced than a simple 1x vs 2x screen. To always send the larger image to 2x screens might still waste bandwidth because we’re not accounting for the size of the screen/image.</p>
<p>Here’s how you can handle this scenario with <code><picture></code>. Let’s stick with the same assumptions in the last scenario, but let’s be a little more specific this time, <code>cover1x.jpg</code> is 640px wide and <code>cover2x.jpg</code> is 1280px wide. Here’s what the code would look like:</p>
<pre><code class="language-markup"><picture>
<source sizes="100%" srcset="cover1x.jpg 640w, cover2x.jpg 1280w">
<img src="cover1x.jpg" alt="Responsive Web Design cover">
</picture>
</code></pre>
<p>Now our <code>srcset</code> values are based on width and the browser gets to select the best image based on another <code><source></code> attribute, <code>sizes</code>. In this case we’ve told the browser that final image selected will be as wide as the entire viewport. Later we’ll see how you can use this with other values.</p>
<p>The final result will be as wide as the viewport, so if the user is on a device that is effectively 320px wide, but at 2x density the browser would, barring other conflicting info like user settings, pick <code>cover1.jpg</code>. If the user’s viewport happened to be 640px wide, but the density was only 1x, <code>cover1.jpg</code> would again be used. On the other hand if the viewport happened to be 640px wide, but the density was 2x, <code>cover2.jpg</code> would be used.</p>
<h2 id="different-image-sizes-based-on-viewport-width">Different Image Sizes Based on Viewport Width</h2>
<p>When you think of responsive images, this is probably the use case you think of — serving smaller images to smaller screens, larger ones to larger screens. Later we’ll see how you can combine this with the pixel density stuff above for even more control.</p>
<p>First, here’s how <code><picture></code> can be used to serve up different images based on viewport width. </p>
<p>For the following examples, let’s say we have three images, <code>small.jpg</code>, <code>medium.jpg</code> and <code>large.jpg</code> and we want to serve them to the corresponding viewport sizes. Let’s make one more assumption: that we’re taking a mobile-first approach and our fallback will also be the smallest image.</p>
<p>Here’s what that code would look like:</p>
<pre><code class="language-markup"><picture>
<source media="(min-width: 45em)" srcset="large.jpg">
<source media="(min-width: 18em)" srcset="medium.jpg">
<img src="small.jpg" alt="Robert Anton Wilson laughing">
</picture>
</code></pre>
<p>This time we’ve used the <code>media</code> attribute to write a couple queries that work just like <span class="caps">CSS</span> <code>@media</code> queries. Our mobile-first approach here means any viewport larger than 45em gets <code>large.jpg</code>, any viewport between 18em and 45em gets <code>medium.jpg</code> and anything smaller than 18em gets our <code>small.jpg</code>. </p>
<p>Notice that here our smaller image is in the <code><img></code> tag, not a <code><source></code> tag. While we could add a third <code><source></code> tag with a srcset pointing to <code>small.jpg</code>, there’s no need to do that since, as I mentioned earlier, <code><picture></code> and <code><source></code> are not the tags that actually load images. The <code><picture></code> element must contain an <code><img></code> element for the browser to actually display your image. Browsers that understand <code><picture></code> will first parse through all your rules, pick an image and then swap that image into the <code>src</code> attribute on the <code><img></code> tag.</p>
<p>In this example not only is the <code><img></code> tag a fallback for older browsers, its <code>src</code> value also becomes the image used by <code><picture></code> savvy browsers if neither media query evaluates to true.</p>
<h2 id="different-image-size-and-resolution-based-on-viewport-width">Different Image Size and Resolution Based on Viewport Width</h2>
<p>Now let’s combine both of the previous examples and use <code><picture></code> to serve up different size and resolution images based on viewport width and device pixel density. To do that we’ll need six images — <code>small.jpg</code>, <code>small-hd.jpg</code>, <code>medium.jpg</code>, <code>medium-hd.jpg</code>, <code>.large.jpg</code> and <code>large-hd.jpg</code> (side note: in the future you’ll want a <span class="caps">CMS</span> that’s good at generating tons of image options from the one you actually upload. Otherwise, plan on going insane while resizing images in Photoshop).</p>
<p>Okay, let’s put all those images into a <code><picture></code> tag:</p>
<pre><code class="language-markup"><picture>
<source media="(min-width: 45em)" srcset="large.jpg, large-hd.jpg 2x">
<source media="(min-width: 18em)" srcset="medium.jpg, medium-hd.jpg 2x">
<source srcset="small.jpg, small-hd.jpg 2x">
<img src="small.jpg" alt="Robert Anton Wilson laughing" >
</picture>
</code></pre>
<p>This looks just like the previous example except that now our <code>scrset</code> includes a second image and the 2x value to indicate that our <code>-hd.jpg</code> images are for high resolution screens. </p>
<p>Also note that this time we did use a third <code><source></code> tag since small screen devices may still be high resolution. That is, while we don’t need a media attribute, we do want to check the resolution, which requires a third <code><source></code> tag.</p>
<h2 id="solving-the-art-direction-conundrum">Solving the Art Direction Conundrum</h2>
<p>Here’s a common responsive design problem: You have an image that, at full size on large screens, easily conveys its information. However, when that image is scaled down to fit on a small screen it becomes difficult to understand the image. For example consider an image of the president shaking hands with Robert Anton Wilson. At full size the image might show both men and some background, but when shrunk down you would barely be able to make out that it’s two men shaking hands, let alone have any clue who the men might be. </p>
<p>In situations like this it makes sense to crop the image rather than just scaling it down. In the example above that might mean cropping the image to be just the President and Robert Anton Wilson’s heads. You no longer know they’re shaking hands, but most of the time it’s more important to know who they are than what they’re doing.</p>
<p>Frankly, handling this scenario is really more a problem for your <span class="caps">CMS</span> than the <code><picture></code> element. But assuming you have a way to generate the cropped image (or images if you’re doing both normal and high-res) then the code would look something like this:</p>
<pre><code class="language-markup"><picture>
<source media="(min-width: 45em)" srcset="original.jpg, original-hd.jpg 2x">
<source media="(min-width: 18em)" srcset="cropped-medium.jpg, cropped-medium-hd.jpg 2x">
<source srcset="cropped-small.jpg, cropped-small-hd.jpg 2x">
<img src="cropped-small.jpg" alt="The President shaking hands with Robert Anton Wilson" >
</picture>
</code></pre>
<p>Here we’re assuming there are two crops that make sense for the viewports they’re targeting. In this case that means a crop that fits viewports between 18em and 45em and another (presumably tighter) crop for smaller screens. We’re also assuming we have both regular and high-resolution versions of the image.</p>
<p>See what I mean about having a <span class="caps">CMS</span> that makes it really easy to generate a ton of different images from a single source? Having to do something like this by hand would suck for even the smallest of blogs.</p>
<p>There are other possible scenarios that fit the art direction problem, for example, providing a black and white version of a color pie chart for monochrome screens.</p>
<h2 id="handling-more-complex-scenarios">Handling More Complex Scenarios</h2>
<p>So far we’ve looked at pretty easy-to-grok scenarios using <code><picture></code>, but the new element addresses some more complex situations as well. For example, we might have a responsive layout where images morph depending on viewport width (and thus there may not always be a one-to-one correlation between viewport width and image size). </p>
<p>The <code><picture></code> element can handle this scenario as well, but this where the syntax starts to get, well, things can get complicated (as things tend to do when you want them to be very flexible).</p>
<p>Imagine you have a storefront with three breakpoints, one for phone-ish devices, another for tablet-ish and a desktop layout. You build the site using a mobile-first approach, so you start with a single-column layout with images that span the full width of the viewport. At the first breakpoint the images switch to a two-column layout and may be a bit smaller than the full-width, single-column images just before the breakpoint (even though the viewport is larger now). Finally, on the larger layout the images move to a three-column grid and start off at the same size as the two-column layout but then scale up to be as large or larger than the images in the single-column layout.</p>
<figure aria-labelledby="cap-1" role="group"><a href="http://longhandpixels.net/media/images/2014/picture_element_illustration.png" title="View Image"><img alt="Illustration of scenario where image size does not necessary correspond to viewport" src="http://longhandpixels.net/media/images/2014/picture_element_illustration.png"></a><figcaption id="cap-1">
<p>The very common image grid scenario. In this example we’re using a single column (100% width) on small screens, two columns (50% width) on medium screens and three columns (rough 33%, but with some additional padding) on large screens.</p>
</figcaption>
</figure>
<p>So what do we do with this scenario? Again, the first thing you’ll need is a <span class="caps">CMS</span> that generates, let’s say six, images to fit this scenario. Assuming the images are in place, the code is actually not that bad, albeit a little verbose. Here’s some example code pulled directly from the responsive images spec:</p>
<pre><code class="language-markup"><picture>
<source sizes="(max-width: 30em) 100%, (max-width: 50em) 50%, calc(33% - 100px)"
srcset="pic100.jpg 100w, pic200.jpg 200w, pic400.jpg 400w,
pic800.jpg 800w, pic1600.jpg 1600w, pic3200.jpg 3200w">
<img src="pic400.jpg" alt="Robert Anton Wilson laughing">
</picture>
</code></pre>
<p>Believe it or not, this is actually the terse way to write this out. You <em>could</em> write this out as six different <code><source></code> elements each with the entire <code>srcset</code> above, though I have no idea why you would want to do that.</p>
<p>Let’s step through the code line by line. The first thing we do is set up a series of breakpoints along with the size of the image relative to the viewport width at each of those breakpoints. So <code>(max-width: 30em) 100%</code> covers our smaller screen where the layout is single column and the image is full width. Then <code>(max-width: 50em) 50%</code> covers our medium layout which happens between 30em and 50em, where images are now 50% the width of the viewport.</p>
<p>For the last argument in <code>sizes</code> things are a little trickier. There’s no max-width, this just applies to everything over 50em. The single argument uses <code>calc()</code> to say images are 1/3 the viewport width, but there’s 100px of padding as well. You may have heard that you should avoid using <code>calc()</code> in <span class="caps">CSS</span> since it tends to slow things down. Is the same thing true here? I actually don’t know; if you do, chime in in the comments. </p>
<p>Once we have the image-to-viewport ratio setup for each of our layout possibilities, then we use <code>srcset</code> to point the browser to our six image sizes, adding a width specification to help the browser pick the best one. In the end the browser will pick the optimal image based on the current image-to-viewport ratio, current viewport size and current viewport density. </p>
<p>Complicated though this may be, it’s actually pretty awesome. You’ve got the ability to serve the right image to the right screen based on the actual size the image will be on the screen. That’s far more effective and powerful than just saying send a small image to a small screen and a big on to a big screen.</p>
<h2 id="super-awesome-sauce-gimme-some">Super Awesome Sauce! Gimme Some.</h2>
<p>No. No <code><picture></code> for you. </p>
<p>Not yet anyway. No browser supports this, though as noted Chromium and Firefox are both working on support. There’s also no polyfill for this version of <code><picture></code>, though there should be one soon. </p>
<p>To make things a little more confusing there is a polyfill for an older version of <code><picture></code>. <a href="https://github.com/scottjehl/picturefill">Picturefill</a> is Scott Jehl’s clever way to bring the <code><picture></code> tag concept to the web today. The problem with Picturefill is that so far it hasn’t been updated to reflect the most recent improvements to <code><picture></code>.</p>
<p>Fear not though, there’s already an <a href="https://github.com/scottjehl/picturefill/issues/113">open issue</a> on the Picturefill GitHub page. Mat “picture-ninja” Marquis <a href="https://github.com/scottjehl/picturefill/issues/113#issuecomment-31350605">says</a> “this third version of the picture proposal is going out for review by some of the major players very soon, so I’m thinking it might be best if we wait until after any feedback comes back—then we can rework the Prollyfill branch per the spec.” In other words, Picturefill will likely be updated pretty soon.</p>
<p>In the mean time, every time you get frustrated hacking at some kind of responsive images solution just <a href="http://picture.responsiveimages.org">pull up the <code><picture></code> spec page</a> and admire the simplicity that will, if all goes well, be taken for granted within a few years.</p>
<div class="footnote">
<hr>
<ol>
<li id="fn-1">
<p>There is a special build of Chromium that supports an older version of the <code><picture></code> proposal, but as of today it doesn’t handle the new version. <a class="footnote-backref" href="#fnref-1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>
Wed, 19 Feb 2014 09:30:00 ESTInstall Nginx on Debian/Ubuntu
http://longhandpixels.net//blog/2014/02/install-nginx-debian-ubuntu
http://longhandpixels.net//blog/2014/02/install-nginx-debian-ubuntu
<p>I recently helped a friend set up his first Nginx server and in the process realized I didn’t have a good working reference for how I set up Nginx. </p>
<p>So, for myself, my friend and anyone else looking to get started with Nginx, here’s my somewhat opinionated guide to installing and configuring Nginx to serve static files. Which is to say, this is how I install and set up Nginx to serve my own and my clients’ static files whether those files are simply stylesheets, images and JavaScript or full static sites like this one. What follows is what I believe are the best practices of Nginx<sup id="fnref-1"><a class="footnote-ref" href="#fn-1">1</a></sup>; if you know better, please correct me in the comments.</p>
<h2 id="nginx-beats-apache-for-static-content2">Nginx Beats Apache for Static Content<sup id="fnref-2"><a class="footnote-ref" href="#fn-2">2</a></sup></h2>
<p>I’ve written before about how static website generators like <a href="http://jekyllrb.com">Jekyll</a>, <a href="http://blog.getpelican.com">Pelican</a> and <a href="https://github.com/koenbok/Cactus">Cactus</a> are a great way to prototype websites in a hurry. They’re also great tools for actually managing sites, not just “blogs”. There are in fact some very large websites powered by these “blogging” engines. President Obama’s very successful fundraising website <a href="http://kylerush.net/blog/meet-the-obama-campaigns-250-million-fundraising-platform/">ran on Jekyll</a>.</p>
<p>Whether you’re just building a quick live prototype or running an actual live website of static files, you’ll need a good server. So why not use Apache? Simply put, Apache is overkill.</p>
<p>Unlike Apache, which is a jack-of-all-trades server, Nginx was really designed to do just a few things well, one of which is to offer a simple, fast, lightweight server for static files. And Nginx is really, really good at serving static files. In fact, in my experience Nginx with PageSpeed, gzip, far future expires headers and a couple other extras I’ll mention is faster than serving static files from Amazon S3<sup id="fnref-3"><a class="footnote-ref" href="#fn-3">3</a></sup> (potentially even faster in the future if Verizon and its ilk <a href="http://netneutralitytest.com/">really do</a> start <a href="http://davesblog.com/blog/2014/02/05/verizon-using-recent-net-neutrality-victory-to-wage-war-against-netflix/">throttling cloud-based services</a>).</p>
<h2 id="nginx-is-different-from-apache">Nginx is Different from Apache</h2>
<p>In its quest to be lightweight and fast, Nginx takes a different approach to modules than you’re probably familiar with in Apache. In Apache you can dynamically load various features using modules. You just add something like <code>LoadModule alias_module modules/mod_alias.so</code> to your Apache config files and just like that Apache loads the alias module.</p>
<p>Unlike Apache, Nginx can not dynamically load modules. Nginx has available what it has available when you install it. </p>
<p>That means if you really want to customize and tweak it, it’s best to install Nginx from source. You don’t <em>have</em> to install it from source. But if you really want a screaming fast server, I suggest compiling Nginx yourself, enabling and disabling exactly the modules you need. Installing Nginx from source allows you to add some third-party tools, most notably Google’s PageSpeed module, which has some fantastic tools for speeding up your site. </p>
<p>Luckily, installing Nginx from source isn’t too difficult. Even if you’ve never compiled any software from source, you can install Nginx. The remainder of this post will show you exactly how. </p>
<h2 id="my-ideal-nginx-setup-for-static-sites">My Ideal Nginx Setup for Static Sites</h2>
<p>Before we start installing, let’s go over the things we’ll be using to build a fast, lightweight server with Nginx.</p>
<ul>
<li><a href="http://nginx.org">Nginx</a>.</li>
<li><a href="http://www.chromium.org/spdy/spdy-protocol"><span class="caps">SPDY</span></a> — Nginx offers “experimental support for <span class="caps">SPDY</span>”, but it’s not enabled by default. We’re just going to enable it when we install Nginx. In my testing <span class="caps">SPDY</span> support has worked without a hitch, experimental or otherwise.</li>
<li><a href="https://developers.google.com/speed/pagespeed/module">Google Page Speed</a> — Part of Google’s effort to make the web faster, the Page Speed Nginx module “automatically applies web performance best practices to pages and associated assets”. </li>
<li><a href="https://github.com/agentzh/headers-more-nginx-module/">Headers More</a> — This isn’t really necessary from a speed standpoint, but I often like to set custom headers and hide some headers (like which version of Nginx your server is running). Headers More makes that very easy.</li>
<li><a href="https://github.com/nbs-system/naxsi">Naxsi</a> — Naxsi is a “Web Application Firewall module for Nginx”. It’s not really all that important for a server limited to static files, but it adds an extra layer of security should you decided to use Nginx as a proxy server down the road.</li>
</ul>
<p>So we’re going to install Nginx with <span class="caps">SPDY</span> support and three third-party modules.</p>
<p>Okay, here’s the step-by-step process to installing Nginx on a Debian 7 (or Ubuntu) server. If you’re looking for a good, cheap <span class="caps">VPS</span> host I’ve been happy with <a href="https://www.digitalocean.com/?refcode=3bda91345045">Digital Ocean</a> (that’s an affiliate link that will help support LongHandPixels; if you prefer, here’s a non-affiliate link: <a href="https://www.digitalocean.com/">link</a>)</p>
<p>The first step is to make sure you’re installing the latest release of Nginx. To do that check the <a href="http://nginx.org/en/download.html">Nginx download page</a> for the latest version of Nginx (at the time of writing that’s 1.5.10). </p>
<p>Okay, <span class="caps">SSH</span> into your server and let’s get started. </p>
<p>While these instructions will work on just about any server, the one thing that will be different is how you install the various prerequisites needed to compile Nginx. </p>
<p>On a Debian/Ubuntu server you’d do this:</p>
<pre><code class="language-bash">$ sudo apt-get -y install build-essential zlib1g-dev libpcre3 libpcre3-dev libbz2-dev libssl-dev tar unzip
</code></pre>
<p>If you’re using <span class="caps">RHEL</span>/Cent/Fedora you’ll want these packages:</p>
<pre><code class="language-bash">$ sudo yum install gcc-c++ pcre-dev pcre-devel zlib-devel make
</code></pre>
<p>After you have the prerequisites installed it’s time to grab the latest version of Google’s Pagespeed module. Google’s <a href="https://developers.google.com/speed/pagespeed/module/build_ngx_pagespeed_from_source">Nginx PageSpeed installation instructions</a> are pretty good, so I’ll reproduce them here with just one key change, I’m going to use the master archive rather than a numbered release.</p>
<p>First grab the latest version of PageSpeed:</p>
<pre><code class="language-bash">$ wget https://github.com/pagespeed/ngx_pagespeed/archive/master.zip
$ unzip master.zip
</code></pre>
<p>Now, before we compile pagespeed we need to grab <code>psol</code>, which PageSpeed needs to function properly. So, let’s <code>cd</code> into the <code>ngx_pagespeed-master</code> folder and grab <code>psol</code>:</p>
<pre><code class="language-bash">$ cd ngx_pagespeed-master
$ wget https://dl.google.com/dl/page-speed/psol/1.7.30.1.tar.gz
$ tar 1.7.30.1.tar.gz
$ cd ../
</code></pre>
<p>Alright, so the <code>ngx_pagespeed</code> module is all setup and ready to install. All we have to do at this point is tell Nginx where to find it.</p>
<p>Now let’s grab the Headers More and Naxsi modules as well. Again, check the <a href="https://github.com/agentzh/headers-more-nginx-module/">Headers More</a> and <a href="https://github.com/nbs-system/naxsi">Naxsi</a> pages to see what the latest stable version is and adjust the version numbers in the following accordingly.</p>
<pre><code class="language-bash">$ wget https://github.com/agentzh/headers-more-nginx-module/archive/v0.24.tar.gz
$ tar -xvzf v0.24.tar.gz
$ wget https://github.com/nbs-system/naxsi/archive/0.53-2.tar.gz
$ tar -xvzf 0.53-2.tar.gz
</code></pre>
<p>Now we have all three third-party modules ready to go, we just need to grab a copy of Nginx itself:</p>
<pre><code class="language-bash">$ wget http://nginx.org/download/nginx-1.5.10.tar.gz
$ tar -xvzf nginx-1.5.10.tar.gz
</code></pre>
<p>Then we <code>cd</code> into the Nginx folder and compile. So, first:</p>
<pre><code class="language-bash">$ cd nginx-1.5.10
</code></pre>
<p>So now we’re inside the Nginx folder, let’s configure our installation. We’ll add in all our extras and turn off a few things we don’t need. Or at least they’re things I don’t need, obviously if you need the mail modules, then delete those lines. If you don’t need <span class="caps">SSL</span>, you might want to skip that as well. Here’s the config setting I use (Note: all paths are for Debian servers, you’ll have to adjust the various paths accordingly for <span class="caps">RHEL</span>/Cent/Fedora/ servers):</p>
<pre><code class="language-bash">$ ./configure \
--add-module=$HOME/naxsi-0.53-2/naxsi_src \
--prefix=/usr/share/nginx \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/access.log \
--user=www-data \
--group=www-data \
--without-mail_pop3_module \
--without-mail_imap_module \
--without-mail_smtp_module \
--with-http_stub_status_module \
--with-http_ssl_module \
--with-http_spdy_module \
--with-http_gzip_static_module \
--add-module=$HOME/ngx_pagespeed-master \
--add-module=$HOME/headers-more-nginx-module-0.24 \
</code></pre>
<p>There are a few things worth noting here. First off make sure that Naxsi is first. Here’s what the <a href="https://github.com/nbs-system/naxsi/wiki/installation">Naxsi wiki page</a> has to say on that score: “Nginx will decide the order of modules according the order of the module’s directive in Nginx’s ./configure. So, no matter what (except if you really know what you are doing) put Naxsi first in your ./configure. If you don’t do so, you might run into various problems, from random/unpredictable behaviors to non-effective <span class="caps">WAF</span>.” The last thing you want is to think you have a web application firewall running when in fact you don’t, so stick with Naxsi first.</p>
<p>There are a couple other things you might want to add to this configuration. If you’re going to be serving large files, larger than your average 1.<span class="caps">5MB</span> <span class="caps">HTML</span> page, consider adding the line: <code>--with-file-aio \</code>, which is apparently faster than the stock <code>sendfile</code> option. See <a href="https://calomel.org/nginx.html">here</a> for more details. There are quite a few other modules available. A <a href="http://wiki.nginx.org/Modules">full list of the default modules</a> can be found on the Nginx site. Read through that and if there’s something else you need, just add it to the list.</p>
<p>Okay, we’ve told Nginx what to do, now let’s actually install it:</p>
<pre><code class="language-bash">$ make
$ sudo make install
</code></pre>
<p>Once <code>make install</code> finishes doing its thing you’ll have Nginx all set up. </p>
<p>Congrats! You made it.</p>
<p>The next step is to add Nginx to the list of things your server starts up automatically whenever it reboots. Since we installed Nginx from scratch we need to tell the underlying system what we did.</p>
<h2 id="make-it-autostart">Make it Autostart</h2>
<p>Since we compiled from source rather than using Debian/Ubuntu’s package management tools, the underlying stystem isn’t aware of Nginx’s existence. That means it won’t automatically start it up when the system boots. In order to ensure that Nginx does start on boot we’ll have to manually add Nginx to our server’s list of startup services. That way, should we need to reboot, Nginx will automatically restart when the server does. </p>
<p>To do that I use the <a href="https://github.com/MovLib/www/blob/master/bin/init-nginx.sh">Debian init script</a> listed in the <a href="http://wiki.nginx.org/InitScripts">Nginx InitScripts page</a>: </p>
<p>If that works for you, just grab the raw version:</p>
<pre><code class="language-bash">$ wget https://raw.github.com/MovLib/www/master/bin/init-nginx.sh
# move it to /etc/init.d/nginx
$ sudo mv init-nginx.sh /etc/init.d/nginx
# make it executable:
$ sudo chmod +x /etc/init.d/nginx
# then just:
$ sudo service nginx start #also restart, reload, stop etc
</code></pre>
<p>I suggest taking the last bit and turning it into an alias in your <code>bashrc</code> or <code>zshrc</code> file so that you can quickly restart/reload the server when you need it. Here’s what I use:</p>
<pre><code class="language-bash">alias xrestart="sudo service nginx restart"
alias xreload="sudo service nginx reload"
</code></pre>
<p>Okay so we now have the initialization script all set up, now let’s make Nginx start up on reboot. In theory this should do it:</p>
<pre><code class="language-bash">$ update-rc.d -f nginx defaults
</code></pre>
<p>But that didn’t work for me with my Digital Ocean Debian 7 x64 droplet (which complained that “<code>insserv rejected the script header</code>“). I didn’t really feel like troubleshooting that at the time; I was feeling lazy so I just decided to use chkconfig instead. To do that I just installed chkconfig and added Nginx:</p>
<pre><code class="language-bash">$ sudo apt-get install chkconfig
$ sudo chkconfig --add nginx
$ sudo chkconfig nginx on
</code></pre>
<p>So there we have it, everything you need to get Nginx installed with <span class="caps">SPDY</span>, PageSpeed, Headers More and Naxsi. A blazing fast server for static files.</p>
<p>After that it’s just a matter of configuring Nginx, which is entirely dependent on how you’re using it. For static setups like this my configuration is pretty minimal.</p>
<p>Before we get to that though, there’s the first thing I do: edit <code>/etc/nginx/nginx.conf</code> down to something pretty simple. This is the root config so I keep it limited to just a <code>http</code> block that turns on a few things I want globally and an include statement that loads site-specific config files. Something a bit like this:</p>
<pre><code class="language-bash">user www-data;
events {
worker_connections 1024;
}
http {
include mime.types;
include /etc/nginx/naxsi_core.rules;
default_type application/octet-stream;
types_hash_bucket_size 64;
server_names_hash_bucket_size 128;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
more_set_headers "Server: My Custom Server";
keepalive_timeout 65;
gzip on;
pagespeed on;
pagespeed FileCachePath /var/ngx_pagespeed_cache;
include /etc/nginx/sites-enabled/*.conf;
}
</code></pre>
<p>A few things to note. I’ve include the core rules file from the Naxsi source. To make sure that file exists, we need to copy it over to <code>/etc/nginx/</code>.</p>
<pre><code class="language-bash">$ sudo cp naxsi-0.53-2/naxci_config/naxsi_core.rule /etc/nginx
</code></pre>
<p>Now let’s restart the server so it picks up these changes:</p>
<pre><code class="language-bash">$ sudo service nginx restart
</code></pre>
<p>Or, if you took my suggestion of creating an alias, you can just type: <code>xrestart</code> and Nginx will restart itself.</p>
<p>With this configuration we have a good basic setup and any <code>.conf</code> files you add to the folder <code>/etc/nginx/sites-enabled/</code> will be included automatically. So if you want to create a conf file for mydomain.com, you’d just create the file <code>/etc/nginx/sites-enabled/mydomain.conf</code> and put the configuration for that domain in that file.</p>
<p>I’m going to post a follow up on how I configure Nginx very soon. In the mean time here’s a pretty comprehensive <a href="https://calomel.org/nginx.html">guide to configuring Nginx</a> in a variety of scenarios. And remember, if you want to some more helpful tips and tricks for web developers, sign up for the mailing list below.</p>
<div class="footnote">
<hr>
<ol>
<li id="fn-1">
<p>If you’re more experienced with Nginx and I’m totally bass-akward about something in this guide, please let me know. <a class="footnote-backref" href="#fnref-1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn-2">
<p>In my experience anyway. Probably Apache can be tuned to get pretty close to Nginx’s performance with static files, but it’s going to take quite a bit of work. One is not necessarily better, but there are better tools for different jobs. <a class="footnote-backref" href="#fnref-2" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
<li id="fn-3">
<p>That said, obviously a <span class="caps">CDN</span> service like Cloudfront will, in most cases, be much faster than Nginx or any other server. <a class="footnote-backref" href="#fnref-3" title="Jump back to footnote 3 in the text">↩</a></p>
</li>
</ol>
</div>
Mon, 10 Feb 2014 11:35:00 ESTHTML5 Placeholder as a Label in Search Forms
http://longhandpixels.net//blog/2014/02/html5-placeholder-label-search-forms
http://longhandpixels.net//blog/2014/02/html5-placeholder-label-search-forms
<p>The <span class="caps">HTML5</span> form input attribute <code>placeholder</code> is a tempting replacement for the good old <code><label></code> form element. </p>
<p>In fact the web is littered with sites that use <code>placeholder</code> instead of labels (or worse, JavaScript to make the <code>value</code> attribute act like <code>label</code>).</p>
<p>Just because a practice is widespread does not make it a <em>best</em> practice though. Remember “skip intro”? I rest my case. Similarly, <strong>you should most definitely not use <code>placeholder</code> as a substitute for form labels</strong>. It may be a pattern on today’s web, but it’s a shitty pattern.</p>
<p>Labels help users complete forms. There are <a href="http://rosenfeldmedia.com/books/web-form-design/">mountains</a> of <a href="http://css-tricks.com/label-placement-on-forms/">data</a> and <a href="http://www.uxmatters.com/mt/archives/2006/07/label-placement-in-forms.php">eye tracking studies</a> to back this up. If you want people to actually fill out your forms (as opposed, I guess, to your forms just looking “so clean, so elegant”) then you want to use labels. The best forms, from a usability standpoint, are forms with non-bold, left aligned labels above the field they label.</p>
<p>Again, <strong>using placeholder as a substitute for labels is a horrible <span class="caps">UI</span> pattern that you should (almost) never use.</strong></p>
<p>Is that dogmatic enough for you? Oh wait, <em>almost</em> never. Yes, I think there is one specific case where maybe this pattern makes sense: search forms.</p>
<p>Search forms are so ubiquitous and so well understood at this point that it may be redundant to have a label that says “search”, a placeholder that also says “search” and a button that says “search” as well. I think just two of those would be fine. </p>
<p>We could skip the placeholder text, which should really be more of a hint anyway — e.g. “Jane Doe” rather than “Your Name” — but what if we want to dispense with the label to save a bit of screen real estate, which can be at a premium on smaller viewports?</p>
<p>The label should still be part of the actual <span class="caps">HTML</span>, whether your average sighted user actually sees it or not. We need it there for accessibility. But with search forms, well, maybe you can tuck that label away, out of site. </p>
<p>Progressive enhancement dictates that the labels should most definitely be there though. Let’s consider a simple search form example:</p>
<pre><code class="language-markup"><form action="/search" method="get">
<label id="search-label" for="search">Search:</label>
<input type="text" name="search" id="query" value="" placeholder="Search LongHandPixels">
<input class="btn" type="submit" value="Search">
</form>
</code></pre>
<p>Here we have our <code><label></code> tag and use the <code>for</code> attribute to bind it with the text input that is our search field. So far, so good for best practices. </p>
<p>Here’s what I think is the progressive enhancement route for search forms: use the <span class="caps">HTML</span> above and then use JavaScript and <span class="caps">CSS</span> to hide away the label when the it makes sense to do so. In other words, don’t just hide the label in <span class="caps">CSS</span>. </p>
<p>Hiding the label with something like <code>label {visibility: hidden;}</code> is a bad idea. That, and its evil cousin <code>display: none;</code> hide elements from screen readers and other assistive devices. Instead we’d want to do something like this:</p>
<pre><code class="language-css">.search-form-label-class {
position: absolute;
left: -999em;
}
</code></pre>
<p>Check out Aaron Gustafson’s <span class="caps">ALA</span> article <cite><a href="http://alistapart.com/article/now-you-see-me">Now You See Me</a></cite> for more details on the various ways to hide things visually without hiding them from people who may need them the most. </p>
<p>So this code is better, our label is off-screen and the placeholder text combined with descriptive button text serve the same purpose and still make the function of the form clear. The main problem we have right now is we’ve hidden the label in every browser, even browsers that won’t display the <code>placeholder</code> attribute. That’s not so great.</p>
<p>In this case you might argue that the button still makes the form function relatively clear, but I think we can do better. Instead of adding a rule to our stylesheet, let’s use a bit of JavaScript to apply our <span class="caps">CSS</span> only if the browser understands the <code>placeholder</code> attribute. Here’s a bit of code to do that:</p>
<pre><code class="language-javascript"><script>
if (("placeholder" in document.createElement("input"))) {
document.getElementById("search-label").style.position= 'absolute';
document.getElementById("search-label").style.left= '-999em';
}
</script>
</code></pre>
<p>This is just plain JavaScript, if your site already has <code>jQuery</code> or some other library running them by all means use it’s functions to select your elements and apply <span class="caps">CSS</span>. The point is the <code>if</code> statement, which tests to see if the current browser support the <code>placeholder</code> attribute. If it does them we hide the label off-screen, if it doesn’t then nothing happens. Either way the element remains accessible to screen readers.</p>
<p>If you’d like to see it in action, here’s a working demo: <a href="http://longhandpixels.net/demos/html5-placeholder/"><span class="caps">HTML5</span> placeholder as a label in search form</a></p>
<p>So is this a good idea? Honestly, I don’t know. It might be splitting hairs. I think it’s okay for search forms or other single field forms where there’s less chance users will be confused when the placeholder text disappears. </p>
<p>Pros:</p>
<ul>
<li>Saves space (no label, which can be a big help on small viewports)</li>
<li>Still offers good accessibility</li>
</ul>
<p>Cons:</p>
<ul>
<li><strong>Technically this is wrong</strong>. I’m essentially using JavaScript to make <code>placeholder</code> take the place of a label, which is not what <code>placeholder</code> is for.</li>
<li><strong>Placeholders can be confusing</strong>. Some people won’t start typing a search term because they’re waiting for the field to clear. Others will think that the field is filled and the form can be submitted. See Chris Coyier’s <span class="caps">CSS</span>-Tricks site for some ideas on how <a href="http://css-tricks.com/hang-on-placeholders/">you can make it apparent that the field</a> is ready for input.</li>
<li><strong>Not good for longer forms</strong>. Again, multi-field forms need labels. Placeholders disappear when you start typing. If you forget which field you’re in after you start typing, placeholders are no help. Despite the fact that the web is littered with forms that do this, please don’t. Use labels on longer forms.</li>
</ul>
<p>I’m doing this with the search form on this site. I started to do the same with my new mailing list sign up form (which isn’t live yet), which is what got me writing this, thinking aloud as it were. My newsletter sign up form will have two fields, email and name (only email is required), and after thinking about this some more I deleted the JavaScript and left the labels.</p>
<p>If I shorten the form to just email, which I may, depending on some A/B testing I’m doing, then I may use this technique there too (and A/B test again). As of now though I don’t think it’s a good idea for that form for the reasons mentioned above.</p>
<p>I’m curious to hear from users, what do you think of this pattern? Is this okay? Unnecessary? Bad idea? Let me know what you think.</p>
<p>Further Reading:</p>
<ul>
<li>
<p>The <span class="caps">W3C</span>’s Web Platform Docs on the <a href="http://docs.webplatform.org/wiki/html/attributes/placeholder">placeholder</a> attribute.</p>
</li>
<li>
<p>Luke Wroblewski’s book <cite><a href="http://rosenfeldmedia.com/books/web-form-design/">Web Form Design</a></cite> is the Bible of building good forms.</p>
</li>
<li>
<p>A little taste of Wroblewski’s book over on his blog: <a href="http://www.lukew.com/ff/entry.asp?1502">Web Application Form Design</a>.</p>
</li>
<li>
<p>UXMatter’s once did some <a href="http://www.uxmatters.com/mt/archives/2006/07/label-placement-in-forms.php">eyeball tracking studies</a> based on Wroblewski’s book.</p>
</li>
<li>
<p>Aaron Gustafson’s <span class="caps">ALA</span> article <a href="http://alistapart.com/article/now-you-see-me">Now You See Me</a>, which talks about best practices for hiding elements with JavaScript.</p>
</li>
<li>
<p><span class="caps">CSS</span>-Tricks: <a href="http://css-tricks.com/places-its-tempting-to-use-display-none-but-dont/">Places It’s Tempting To Use Display: None; But Don’t</a>. Seriously, don’t.</p>
</li>
<li>
<p><span class="caps">CSS</span>-Tricks: <a href="http://css-tricks.com/hang-on-placeholders/">Hang On Placeholders</a>.</p>
</li>
<li>
<p><a href="http://adactio.com/journal/6147/">Jeremy Keith on <code>placeholder</code></a>.</p>
</li>
</ul>
Fri, 07 Feb 2014 14:38:00 ESTWork Smarter: The Plain Text Workflow
http://longhandpixels.net//blog/2014/02/work-smarter-plain-text-workflow
http://longhandpixels.net//blog/2014/02/work-smarter-plain-text-workflow
<p><em>If you’ve ever struggled building responsive websites, this post is for you. It’s part of a series on responsive design and smarter workflows, all pulled from my book, <a href="http://longhandpixels.net/store/">Responsive Web Design</a>. If you find this excerpt useful, and want even more ideas on how responsive design can help you create amazing websites, sign up for the newsletter below and you’ll get a discount when the book is released.</em></p>
<nav class="toc"><h4 class="toc-title">Table of Contents</h4><ul><li><a href="#faster-easier-web-development-sign-me-up">Faster, Easier Web Development? Sign Me Up!</a></li><li><a href="#everything-starts-with-the-content">Everything Starts with the Content</a></li><li><a href="#tool-1-the-web-server">Tool #1: The Web Server</a></li><li><a href="#tool-2-plain-text">Tool #2: Plain Text</a><ul><li><a href="#the-power-of-markdown">The Power of Markdown</a></li><li><a href="#tools-for-converting-to-plain-text">Tools for Converting to Plain Text</a></li><li><a href="#pandoc-for-fame-and-fortune">Pandoc for Fame and Fortune</a></li></ul></li><li><a href="#further">Further</a></li></ul></nav>
<p>If your current workflow looks anything like mine used to, you probably start most of your design work in a graphics editor like Photoshop. There’s nothing “wrong” with that per say, nor is Photoshop some tool for evil, but I’m here to tell you there is a better, more productive way to work.</p>
<p>Here’s the thing: if you’re designing websites in Photoshop you’re doing too much work. </p>
<p>If you’re building responsive websites and you’re not working directly with the code in a web browser you’re wasting time and energy using the wrong tool for the job. There’s nothing wrong with Photoshop, but it’s not the best tool for developing responsive websites.</p>
<p>Why?</p>
<p>Photoshop has a fixed canvas size; the web has an infinitely flexible canvas. Responsive design means embracing that flexible canvas and you can’t do that when you’re working in a graphics editor.</p>
<p>The web browser is the only tool I know of that offers the same fluid, flexible canvas of the web. <strong>If you want to simplify and optimize your responsive workflow, the place to work is in the browser</strong>. </p>
<p>Designing in the browser means working with the web rather than against it, and that’s the first step toward a simpler, faster responsive design workflow.</p>
<h2 id="faster-easier-web-development-sign-me-up">Faster, Easier Web Development? Sign Me Up!</h2>
<p>For a long time I ignored the advice to design in the browser because often the people giving it stopped with the advice. Go design in the browser! It’s awesome! And, unicorns! Whereas I would just sit there thinking, <em>Uuuuuuuh, okay, but what the heck does that mean? Design in the browser…? Grumble, well, I’ve got work to do and I know how to use Photoshop…</em></p>
<p>Designing directly in the web browser makes sense at a theoretical level, but what does it mean in practical terms? What does this workflow look like and where do you start?</p>
<p>That’s why I wrote this, to outline how I finally figured out I could save tremendous time and effort working directly in the browser rather than prototyping everything in Photoshop. I’m going to share my workflow in hopes it will prove useful to you. </p>
<p>Before we dive in, realize that this is just my workflow. It’s not <span class="caps">THE</span> workflow by any means. Whether you’re part of a small team, large team or working on your own, you have your idiosyncrasies and tics to consider. A good workflow will work with, not against you. I can’t tell you how you should work. I can, however, tell you how I work and hopefully that will give you some ideas you can test in your own workflow. Take what you need, skip what you don’t.</p>
<p>In the <a href="http://longhandpixels.net/blog/2013/11/easiest-way-get-started-designing-browser">first part of this responsive design workflow series</a> we looked at a super simple way to serve files on our local development machines. After all, you can’t design in the browser if you don’t have a server for your web browser to talk to. So I’ll assume you’ve completed that tutorial (or have your own web server setup already). </p>
<h2 id="everything-starts-with-the-content">Everything Starts with the Content</h2>
<p>The first thing to do with any tough question is to break it down into smaller questions. So instead of asking what does designing in the browser look like, let’s start with a more basic question: What do we need before we can display a webpage?</p>
<p>The simple answer is: the content.</p>
<p>Before we can do anything with <span class="caps">HTML</span> or <span class="caps">CSS</span> we need the contents of our site. Everything starts with content. No content, no <span class="caps">HTML</span>. No <span class="caps">HTML</span>, no <span class="caps">CSS</span>. </p>
<p>The foundation of any design has to be the content. I know what you’re thinking; you’re thinking I’ll just grab some Lorem Ipsum. Or, if you prefer some snarky for your dev work, <a href="http://slipsum.com">Samuel L. Ipsum</a>. But that’s not going to cut it. </p>
<p>Without the content we’re designing in the dark. I can’t remember where I first saw a graphic like this, but it’s what turned the light bulb on for me…. Simply put, there’s no point in designing a layout with this:</p>
<figure aria-labelledby="cap-1" role="group"><a href="http://longhandpixels.net/media/images/2014/contentfirst1.png" title="View Image"><img alt="two plain lorem ipsum paragraphs" src="http://longhandpixels.net/media/images/2014/contentfirst1.png"></a><figcaption id="cap-1">
<p>The content you think you’re going to get.</p>
</figcaption>
</figure>
<p>When what you’re actually need to display looks like this:</p>
<figure aria-labelledby="cap-2" role="group"><a href="http://longhandpixels.net/media/images/2014/contentfirst1.png" title="View Image"><img alt="structurally complex content with lists, paragraphs and blockquotes" src="http://longhandpixels.net/media/images/2014/contentfirst2.png"></a><figcaption id="cap-2">
<p>The content you actually got.</p>
</figcaption>
</figure>
<p>As Jeffery Zeldman <a href="http://www.zeldman.com/2008/05/06/content-precedes-design/">writes</a>, “design in the absence of content is not design, it’s decoration.” We’re not decorating websites, we’re designing them, which means we need actual content.</p>
<p>In terms of workflow, this means you need to get the content as soon as you can. No content, no work to flow. It means that when you’re meeting with clients you need to emphasize the importance of having the actual content, not placeholders, but actual content. Without the content you can’t make the client’s vision a reality. You need real content to build real websites.</p>
<p>If you’re doing a redesign of existing content, you’re all set, just dump the site using a tool like <a href="http://curl.haxx.se">curl</a> or wget<sup id="fnref-1"><a class="footnote-ref" href="#fn-1">1</a></sup> and then do a content inventory — list all the contents and make a special note of any patterns, repeated content and outlier content you find. </p>
<p>Once you have the content you can move on to sketching and wireframing — figuring out the structure of the pages and overall site. I tend to do this stage mostly on paper because I find that to be the fastest way to get my ideas recorded, but I’ve seen other developers who use iPads with styluses, mind mapping tools, even one who used spreadsheets to create wireframes (yeah, he was a little strange). </p>
<p>Once I have a good idea of the hierarchy and structure of the content on the site, I immediately jump into the browser and start working with live <span class="caps">HTML</span>. At this point I’m just stacking text and creating structure, there’s no <span class="caps">CSS</span> yet.</p>
<p>There are two necessary components in this workflow: the web server and the files.</p>
<h2 id="tool-1-the-web-server">Tool #1: The Web Server</h2>
<p>For the full details on how you can start a web server in any folder on your computer, see the first part of this series. To quickly recap where we left off, recall that we set up our example project in <code>~/Sites/myproject/</code>. We then open up our terminal application and type:</p>
<pre><code class="language-bash">cd ~/Sites/myproject/ && serve
</code></pre>
<p>Assuming you set up the aliases outlined in the first post, this will start up a server in the <code>myproject</code> folder. Now point your browser to <a href="http://localhost/:8080">http://localhost/:8080</a> and you should see a directory listing of… nothing! That’s okay, the important thing is that we’ve got a server up and running. </p>
<p>Now we’re ready to turn our content into actual <span class="caps">HTML</span> files.</p>
<h2 id="tool-2-plain-text">Tool #2: Plain Text</h2>
<p>Up until now I’ve been using a phrase I don’t particularly like — “the content”. That makes it sound like it’s just a pile of stuff. But it’s not. It’s words, phrases, sentences, pitches, headlines, sub headlines, outlines, lists, tables, buttons, forms, charts, illustrations, images, videos. “The content” is generic, the contents of the site you’re building are not. This isn’t just semantics, it’s your first clue in how to get your workflow in line with the web itself.</p>
<p>Notice two that almost everything in that list is either text, an image or a video. </p>
<p>At its core this is what the web is made of — text and images. This is why starting your work in a graphics editor doesn’t make sense. The web is mostly text. Even fancy landing pages and ultra-slick web apps are ultimately about serving up text and images in the some way.</p>
<p>And within that core, for most sites, “the content” is text. So when we’re designing in the browser we’ll start where the web does, with text. Then we’ll add structure to that text. Then we can actually <strong>design</strong> pages optimized to display that structured text rather than just decorating some filler and hoping for the best.</p>
<h3 id="the-power-of-markdown">The Power of Markdown</h3>
<p>Starting with just the text makes it much easier to see the structure of your content and mark it up accordingly. </p>
<p>To my mind the best way to markup your documents at this stage is to use John Gruber’s <a href="http://daringfireball.net/projects/markdown/">Markdown</a>. Markdown is a text-to-<span class="caps">HTML</span> conversion tool which allows you to markup text using an easy-to-read, easy-to-write format and then convert it to structurally valid <span class="caps">HTML</span>. While it won’t allow you to markup every thing you might need in the end, it’s perfect for generating quick prototypes like this. You can read through the <a href="http://daringfireball.net/projects/markdown/syntax">Markdown documentation over on Daring Fireball</a>.</p>
<p>Best of all the syntax of Markdown is extremely simple, you can pick it up in an afternoon and reach the level of mastery we need in a day or two. </p>
<p>To markup our content we’d just dive into our plain text files and add a bit of structure. Let’s say you had some text that looks like this:</p>
<pre><code class="language-markup">Acme Widgets
We're Awesome Widget Makers
Crank your widgets faster with ACME Widgets
Our Widgets are the best in the business. You can rely on ACME widgets day in and day out. The toughest, most dependable widgets out there.
What can ACME Widgets do for you?
We can help you build better subwidgets
We can make you life widgetier
We can solve all your widget headaches
</code></pre>
<p>Let’s use Markdown to add some structure. The result might look something like this:</p>
<pre><code class="language-markup">#We're Awesome Widget Makers
##Crank your widgets faster with ACME Widgets
Our Widgets are the best in the business. You can rely on ACME widgets day in and day out. The toughest, most dependable widgets out there.
###What can ACME Widgets do for you?
* We can help you build better subwidgets
* We can make your life widgetier
* We can solve all your widget headaches
</code></pre>
<p>You can refer to the <a href="http://daringfireball.net/projects/markdown/syntax">Markdown docs</a> for more details on the syntax, but the main thing to know is that <code>#</code> will be converted to <code><h1></code>, <code>##</code> to <code><h2></code> and so on. The asterisks denote an unordered list. The sentences in the middle will automatically be wrapped in <code><p></code> tags. We’ve added structure to the text, but kept things readable. </p>
<p>Why bother? Why not go straight to <span class="caps">HTML</span>? Well, in this case the content is simple enough that sure, you might as well, but with much more complex, real-world content marking everything up in pure <span class="caps">HTML</span> is going to make it very difficult to read. Remember, this is the prototyping stage, things will be changing and you’ll likely need to edit, rearrange and change your content many times. The more readable it is, the easier it is to make those structural changes.</p>
<h3 id="tools-for-converting-to-plain-text">Tools for Converting to Plain Text</h3>
<p>Unfortunately, it’s rare that a client gives you plain text files. Most clients deliver content in <span class="caps">MS</span> Word files or PDFs or something even stranger. I had one client who sent over all their content as a series of PowerPoint presentations. </p>
<p>The good news is that almost any files can be reduced to plain text. Regardless of how the client delivers the content, I convert it to plain text. For Word files I just open and save as plain text. That won’t preserve any formatting, but you can keep the original around just to make sure you get the hierarchy and structure right. </p>
<p>For PDFs I use a tool called <a href="http://www.foolabs.com/xpdf/download.html">pdftotext</a>. <span class="caps">OS</span> X users can grab a handy installer from <a href="http://www.bluem.net/en/mac/packages/">Carsten Blüm</a>. There are also numerous free online <span class="caps">PDF</span>-to-text converters, as well as <span class="caps">OCR</span> software available. If the client hands you content in PowerPoint slides you can open it in PowerPoint, save it as a Rich Text document and then open the Rich Text document in TextEdit or similar and save as plain text.</p>
<p>The point is to get your content in plain text form. </p>
<h3 id="pandoc-for-fame-and-fortune">Pandoc for Fame and Fortune</h3>
<p>The next step is to convert our Markdown-formatted file into an <span class="caps">HTML</span> file we can view in the browser using the server we set up above. There’s a nearly unlimited number of ways we can convert from Markdown to actual <span class="caps">HTML</span>, but my favorite is <a href="http://johnmacfarlane.net/pandoc/">Pandoc</a>.</p>
<p>Installing Pandoc is simple, just head over to the <a href="http://code.google.com/p/pandoc/downloads/list">Pandoc download page</a> and grab the installer for your platform (for <span class="caps">OS</span> X grab the .dmg file, for Windows grab the .msi). Then double click the installer and follow the directions. </p>
<p>Once you have Pandoc installed you just need to run it on your markdown files. To do that fire up a terminal application. On <span class="caps">OS</span> X that would be Applications >> Utilities >> Terminal. On Windows you’ll need <a href="http://x.cygwin.com">Cygwin</a>.</p>
<p>I know, the command line is antiquated, mysterious and a bit frightening for many people. </p>
<p>I know that because it was that way for me too. But I kept noticing how much faster I could do things compared to visual apps. And I found that every time I used the terminal, it got a little less intimidating. I learned how to do one little thing that sped up my overall workflow. Then I learned another. And another. Today I use the terminal more than any other application. You don’t have to go that far, but don’t let it intimidate you. Just take it slow. Start with one thing that simplifies your life, like <a href="http://longhandpixels.net/blog/2013/11/easiest-way-get-started-designing-browser">the web server trick</a>. </p>
<p>With that one already under your belt you’re ready for Pandoc.</p>
<p>Open your terminal and navigate to your project folder. To stick with the previous tutorial in this series we’ll say our project files are in <code>~/Sites/myproject</code>:</p>
<pre><code class="language-bash">cd ~/Sites/myproject
</code></pre>
<p>Now that we’re in the right directory we just need to invoke Pandoc:</p>
<pre><code class="language-bash">pandoc -s --smart -t html5 -o about.html about.txt
</code></pre>
<p>This line says, take the file <code>about.txt</code>, convert it from Markdown to <span class="caps">HTML5</span> (that’s the <code>-t html5</code> bit) and save the results in a new file named <code>about.html</code>. The <code>-s</code> flag at the beginning of the line tells Pandoc that we want this to be a standalone conversion, which means Pandoc will add <code><html></code>, <code><head></code>, <code><body></code> and a few other tags so that we have an actual valid <span class="caps">HTML</span> file rather than just a fragment of <span class="caps">HTML</span>. Pandoc even adds a link to the <a href="https://code.google.com/p/html5shiv/">HTML5shiv</a> for <span class="caps">IE</span>. </p>
<p>The <code>--smart</code> flag turns on one little extra feature that converts straight quotes to actual or curly quotes. </p>
<p>Point your web browser to <a href="http://localhost:8080/about.html">http://localhost:8080/about.html</a> and you should see the results. View source and you’ll notice that Pandoc has done a bunch of stuff:</p>
<pre><code class="language-markup"><!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="generator" content="pandoc">
<title></title>
<style type="text/css">code{white-space: pre;}</style>
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<h1 id="were-awesome-widget-makers">We're Awesome Widget Makers</h1>
<h2 id="crank-your-widgets-faster-with-acme-widgets">Crank your widgets faster with ACME Widgets</h2>
<p>Our Widgets are the best in the business. You can rely on ACME widgets day in and day out. The toughest, most dependable widgets out there.</p>
<h3 id="what-can-acme-widgets-do-for-you">What can ACME Widgets do for you?</h3>
<ul>
<li>We can help you build better subwidgets</li>
<li>We can make your life widgetier</li>
<li>We can solve all your widget headaches</li>
</ul>
</body>
</html>
</code></pre>
<p>Pandoc has converted all our Markdown formatting into actual <span class="caps">HTML</span>. Our hashes change to header tags and our list gets marked up as an unordered list. Don’t worry too much about the IDs and all the header elements. That can be changed or deleted when you move to working with templates in an actual content management system. </p>
<p>As you can see we have a nicely structured <span class="caps">HTML</span> file which can serve as the basis of our templates or undergo further editing to add things like a site-wide navigation menu, header, logo and the like. </p>
<p>Hmm. Maybe that list at the end should be an ordered list (probably not, but for example’s sake, go with me here). Well, that’s easy to change. Just open up the <code>about.txt</code> files and change the markdown to look like this:</p>
<pre><code class="language-markup">#We're Awesome Widget Makers
##Crank your widgets faster with ACME Widgets
Our Widgets are the best in the business. You can rely on ACME widgets day in and day out. The toughest, most dependable widgets out there.
###What can ACME Widgets do for you?
1. We can help you build better subwidgets
2. We can make you life widgetier
3. We can solve all your widget headaches
</code></pre>
<p>Run the same Pandoc command (<strong>tip</strong>: if you hit the up arrow in your terminal app it will bring up the last used command. Assuming you’ve done nothing else in the mean time, that will be the Pandoc command we ran before). </p>
<p>Refresh your browser and you should see that the list of things <span class="caps">ACME</span> widgets can do for you is now an ordered list. Hmm, maybe that header should be an H2? Maybe the client just called, they’re sending over some updates for the page. None of that’s a problem any more, you just update your text file, run Pandoc and see the results. Simple.</p>
<h2 id="further">Further</h2>
<p>So far we’ve established a very basic, but fast workflow. We take our client provided content, convert it to text and with just two lines of code create <span class="caps">HTML</span> files and serve them locally for prototyping and structuring.</p>
<p>All this does is give you quick and dirty <span class="caps">HTML</span> you can use for prototyping. Why is that useful?</p>
<p>As Stephen Hay has <a href="http://www.the-haystack.com/">said repeatedly</a> (and <a href="http://www.responsivedesignworkflow.com/">written a book about</a>, which you should read), starting with raw, unstyled <span class="caps">HTML</span> forces you to focus and prioritize. Hay suggests asking yourself, “what is the message that needs to be communicated if I was only able to provide them with unstyled <span class="caps">HTML</span>?” Start there, with the content — the most important content — and design everything around that.</p>
<p>We’ve got that basic unstyled <span class="caps">HTML</span>. What if you want to get a little bit fancier with Pandoc? Well, you certainly can. I do. </p>
<p>In the next installment in this series we’ll look at some advanced ways to use Pandoc including customizing the <span class="caps">HTML</span> template it uses, adding site-wide elements like navigation, headers and footers, as well as the part most designers all waiting for — adding an actual stylesheet. </p>
<p>So stay tuned. In the mean time, you can head over the <a href="http://johnmacfarlane.net/pandoc/README.html">Pandoc documentation</a> if you’d like to get a head start.</p>
<p>If you want to learn some more handy tips and tricks for improving your responsive design workflows, I’m writing a book to teach you exactly that (and a whole lot more). Sign up for the mailing list below to hear more about the book and get a discount when it’s released.</p>
<div class="footnote">
<hr>
<ol>
<li id="fn-1">
<p>If you prefer a graphical download check out <a href="http://www.sitesucker.us/mac/mac.html">Sitesucker</a> for <span class="caps">OS</span> X or <a href="http://www.httrack.com">HTTrack</a> for Windows <a class="footnote-backref" href="#fnref-1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>
Sun, 02 Feb 2014 19:37:00 ESTThe Easiest Way to Get Started 'Designing in the Browser'
http://longhandpixels.net//blog/2013/11/easiest-way-get-started-designing-browser
http://longhandpixels.net//blog/2013/11/easiest-way-get-started-designing-browser
<p><em>If you’ve ever struggled to “design in the web browser” this post is for you.</em></p>
<p>You’ve probably heard that phrase before, “designing in the browser”, especially when it comes to building responsive websites. Some people even go so far as to say you shouldn’t use Photoshop at all, but should build everything right in the browser. </p>
<p>I think you should choose whatever tool works the best for you, but since I switched to developing directly in the browser a few years ago I’ve been able to greatly simplify my workflow. Skipping intermediary tools like Photoshop means I’m able to accomplish more in less time, which in turn means I can say yes to more projects.</p>
<p>Sounds awesome right? But where do you start?</p>
<h2 id="how-to-simplify-designing-in-the-browser">How to Simplify “Designing in the Browser”</h2>
<p>Start with the content. Get your content from the client, make your sketches, your wireframes, whatever other preliminary things are already part of your workflow. Then, when that’s done, instead of opening Photoshop, Illustrator or other layout apps, you convert that content to <span class="caps">HTML</span> and start structuring it to match your wireframes.</p>
<p>But how? I start up a web browser (I use Firefox), point it to my local mockup files (just <span class="caps">HTML</span> files in my project folder) and start editing. That’s it; that’s my workflow: edit, refresh; edit, refresh. It’s simple and it makes the feedback loop of design and development immediate and simple. </p>
<p>And to do that I didn’t spend hours setting up some complex development environment, nor did I have to buy some expensive <span class="caps">GUI</span> server software package. In fact, I use just one line of code to pull this off.</p>
<p>Here’s how you can simplify your responsive design workflow, and start “designing in the browser” with what I call “the Python web server trick”. I’ve been doing this for so long I often assume everyone knows about this, but I keep meeting people who don’t. So… if you don’t, here’s a dead simple way to serve files locally with just one line of code.</p>
<h2 id="the-best-web-server-is-the-one-thats-already-installed">The Best Web Server is the One That’s Already Installed</h2>
<p>The key to designing in the browser is to have <strong>a quick and easy way to serve up files locally</strong>. You don’t need anything fancy at this stage, just a basic web server.</p>
<p>The easiest way I have found to set up this workflow is to use a very simple command line tool that creates a web server wherever I want it, whenever I want it.</p>
<p>I know, I know, the command line is antiquated, mysterious and a bit frightening for many people. I know that because it was that way for me too. But I kept noticing how much faster I could do things compared to visual apps. And I found that every time I used the terminal, it got a little less intimidating. I learned how to do one little thing that sped up my overall workflow. Then I learned another. And another. Today I use the terminal more than any other application. You don’t have to go that far, but don’t let it intimidate you. Just take it slow. Start with one thing that simplifies your life, like this web server trick.</p>
<p>If you’ve ever tried to set up a local development environment with Apache, <span class="caps">PHP</span> and the like you probably know what a headache that can be. Well, it turns out, if all you want is a simple web server, there’s a much easier way. </p>
<p>Here’s how to <strong>turn any local folder on your Mac or Linux machine into a web server</strong> (Windows users can do the very same thing, though first you’ll need to install Python. Follow <a href="http://www.anthonydebarros.com/2011/10/15/setting-up-python-in-windows-7/">these instructions</a> to get Python installed and then come back and follow along).</p>
<p>Before we start our web server we need a folder to hold all our files. This folder will be the “root” of our web server. I divide my time between <span class="caps">OS</span> X and Linux, which both offer a “Sites” folder in your home folder. I use this folder to store all my projects. If you prefer to store things elsewhere just adjust all the path names in the code that follow. Open the <code>Sites</code> folder and create a new folder inside it named <code>myproject</code>. Then create a new file named <code>mydemo.html</code>. Open that file in your favorite editor and just type “Hello World”.</p>
<p>That gives us something to test with. The next step is to open up your terminal application. In <span class="caps">OS</span> X that means you head to the <code>Applications</code> folder, open the <code>Utilities</code> folder and then double-click the Terminal application (Windows users head to the Start Menu, click Run and then type <code>cmd</code>; if you’re on Linux I’ll assume you know how to open a terminal window). In the new Terminal window type/paste this line:</p>
<pre><code class="language-bash">cd ~/Sites/myproject
</code></pre>
<p>The command <code>cd</code> just means “change directory”. So we’ve changed from our home user folder to the <code>myproject</code> directory. Okay, you’re now inside the folder we created just a minute ago. Now type this line:</p>
<pre><code class="language-bash">python -m SimpleHTTPServer 8080
</code></pre>
<p>Now open your favorite web browser and head to the <span class="caps">URL</span>: <code>localhost:8080/</code>. You should now see a directory listing with a link to your <code>mydemo.html</code> file. Click that and you should see “Hello World”. Go back to your text editor and change the <code>mydemo.html</code> file to read “Hello World, it’s nice to meet you”. Jump back to the browser and reload the page. You should now see the message “Hello World, it’s nice to meet you”</p>
<p>Congratulations! You created a web server. You now have a simple and fast way to serve up <span class="caps">HTML</span> files locally. You can edit, refresh and mock up live <span class="caps">HTML</span> files right in the browser.</p>
<p>All we’re doing here is taking advantage of the fact that the <a href="http://www.python.org/">Python programming language</a> ships with a built-in web server. Since Python is built into <span class="caps">OS</span> X and Linux, it’s always there, ready to serve up files (as noted above, if you’re on Windows you’ll need to install Python. I also suggest installing <a href="http://cygwin.com/">Cygwin</a>, it will make everything you do on the command line easier).</p>
<h2 id="improving-the-script">Improving the Script</h2>
<p>So we have a very basic way to serve files locally. There are various ways to make this more sophisticated, but this basic method will work when you’re first getting started. </p>
<p>If you don’t mind another quick trip to the Terminal you can even automate the process some more. To make it even simpler we can add an alias to what’s known as a “profile”, the configuration file that loads every time we start up a new terminal window. Most operating systems these days ship with the <a href="http://en.wikipedia.org/wiki/Bash_%28Unix_shell%29">Bash shell</a>. Assuming that’s what you have (<span class="caps">OS</span> X uses Bash by default, as do most Linux distros), open a new terminal window and type this:</p>
<pre><code class="language-bash">nano ~/.bash_profile
</code></pre>
<p>Now paste this line into the window:</p>
<pre><code class="language-bash">alias serve='cd ~/Sites/myproject && python -m SimpleHTTPServer 8080'
</code></pre>
<p>Hit <code>control-x</code>, type a “y” and hit return to save the file. Now quit your terminal app and restart it.</p>
<p>Now to turn on the server all we need to do is open a new terminal window and type “serve”. Note that if your folder is in a different location, or if you move the folder you’ll need to adjust your alias accordingly.</p>
<p>If you’ve got a home network running and you’d like to be able to see your website on all your devices (handy for testing on phones, tablets and whatnot), you can alter this code slightly so other local devices can connect to your server. It’s a little more complicated, but can still be a one-liner. </p>
<p>For example, if your machine’s local network address is 192.168.1.5, you could run this command:</p>
<pre><code class="language-bash">python -c "import BaseHTTPServer as bhs, SimpleHTTPServer as shs; bhs.HTTPServer(('192.168.1.5', 8080), shs.SimpleHTTPRequestHandler).serve_forever()"
</code></pre>
<p>Now, instead of <code>localhost</code>, open the <span class="caps">URL</span> <code>192.168.1.5:8080</code> in your web browser and you’ll see the same page, but now you can point your phone to that <span class="caps">URL</span> and it will load there as well. Ditto your tablet, Kindle and any other devices connected to your local network. </p>
<p>Obviously that’s tough to remember so let’s create an alias. To do that we’ll just add another alias to the .bash_profile file we edited earlier. To open that up again just enter:</p>
<pre><code class="language-bash">nano ~/.bash_profile
</code></pre>
<p>Now paste this line into the window:</p>
<pre><code class="language-bash">alias serve_all="python -c 'import BaseHTTPServer as bhs, SimpleHTTPServer as shs; bhs.HTTPServer(('\''192.168.1.5'\'', 8080), shs.SimpleHTTPRequestHandler).serve_forever()'"
</code></pre>
<p>Now you can <code>cd</code> into any directory, type <code>serve_all</code> and run a web server that you can use to testing your sites on any device.</p>
<p>That’s all there is to it. A live web server whenever you want it, wherever you want it.</p>
<p>That’s how I “design in the browser”. </p>
<p>The next step is to take that nice content the client gave us and put it into our mockup files so we have something more useful than “Hello World” in our web browser. I do this using plain text files, <a href="http://daringfireball.net/projects/markdown/">Markdown</a> and <a href="http://johnmacfarlane.net/pandoc/">Pandoc</a>, which I cover in more detail in this follow-up post: <a href="/blog/2014/02/work-smarter-plain-text-workflow">Work Smarter: The Plain Text Workflow</a>. </p>
<p>I hope this simple Python server trick proves helpful, and, if you have any questions, drop them in the comments below.</p>
<p>If you want to learn some more handy tips and tricks for improving your responsive design workflows, I’m writing a book to teach you exactly that (and a whole lot more). Sign up for the mailing list below to hear more about the book and get a discount when it’s released.</p>
Fri, 08 Nov 2013 16:02:00 ESTResponsive Images & `srcset`
http://longhandpixels.net//blog/2013/09/responsive-images-srcset
http://longhandpixels.net//blog/2013/09/responsive-images-srcset
<p>There are, in my experience, three pain points in any responsive design — tabular data, advertising and images. The latter is the most interesting problem to me since it’s not something you can design or engineer your way around. True, there are ways you can coerce today’s browsers into doing roughly what you want — serve large images to large screens and small ones to small screens — but these are really hacks, sometimes very clever hacks, but still hacks. </p>
<p>Nathan Ford has put together a nice <a href="http://artequalswork.com/posts/responsive-images/" title="Responsive Images Mega-List">Responsive Images Mega-List</a> in an attempt to catalog all the ways you can handle images in a responsive site today.</p>
<p>That’s a great list of resources for handling images today, but what I’ve been obsessing over lately is the future, when we won’t need all these workarounds.</p>
<p>Just like we hacked video into the web using Flash and eventually got the <code><video></code> tag, we’re hacking responsive images into the web and eventually the web is going to give us a native solution. In fact, there’s one just around the browser update bend. </p>
<h2 id="how-srcset-simplifies-responsive-images">How <code>srcset</code> Simplifies Responsive Images</h2>
<p>The exciting thing is that there are not just one, but two responsive image solutions already in the works. The <span class="caps">W3C</span> is working on a couple of new tools aimed at making responsive images less complex. The first new feature that’s likely to make it to a browser near you is the new <code>srcset</code> attribute for the <code><img></code> tag.</p>
<p>[<strong>Update 02 Feb 2014</strong>: Everything below is still true, but it looks like <code>srcset</code> will be part of the proposed <code><picture></code> element rather than part of <code><img></code> (or it may be part of both, that’s still up in the air a bit). In other words, the WebKit nightly support may well be the only time <code>srcset</code> works on an <code><img></code> tag. The syntax on the <code><picture></code> element is the same, though it’s used within a <code><source></code> tag.]</p>
<p>The proposed <code>srcset</code> attribute has a controversial history, which I wrote about <a href="http://www.webmonkey.com/2012/05/ready-or-not-adaptive-image-solution-is-now-part-of-html/" title="Ready or Not, Adaptive-Image Solution Is Now Part of HTML">several</a> <a href="http://www.webmonkey.com/2012/05/browsers-at-odds-with-web-developers-over-adaptive-images/" title="Browsers at Odds With Web Developers Over 'Adaptive Images'">times</a> on Webmonkey. I don’t think any of that matters at this point though. It’s true that <code>srcset</code> doesn’t address everything about responsive images, but it looks to me like it covers the 80 percent use case and, more importantly, there is <a href="http://mobile.smashingmagazine.com/2013/08/21/webkit-implements-srcset-and-why-its-a-good-thing/">already some browser support</a> (and more on the way). </p>
<p>Here’s how <code>srcset</code> works:</p>
<pre><code class="language-markup"><img alt="Image Desc"
src="image.jpg"
srcset="image-HD.jpg 2x, image-phone.jpg 320w, image-phone-HD.jpg 320w 2x">
</code></pre>
<p>As you can see, the <code>srcset</code> attribute takes a comma-separated list of values. Within each item in the list you have three variables. First there’s the <span class="caps">URL</span> to the image, then there’s a maximum viewport dimension (optional) and then an optional pixel density (for targeting higher resolution screens). So the <code>srcset</code> value <code>image-HD.jpg 2x</code> tells the browser, roughly, if you’re on a display with high-res screen then grab this high-res image. Pretty simple. You can of course make it much more complex by adding several other images to the list, for example, to target various screen widths.</p>
<p>There are two major drawbacks to <code>srcset</code>. First, <strong>you can only specify screen width (or height) in pixels</strong>. The reason has to with how browsers pre-fetch content, which happens long before there’s enough info to calculate the value of a percentage or em width/height. See this <a href="http://lists.w3.org/Archives/Public/public-whatwg-archive/2012May/0310.html">thread on the <span class="caps">W3C</span> mailing list</a> for details. The bottom line is, flexible units for <code>srcset</code> is a no-go.</p>
<p>The other major drawback is that <strong>you can only specify the equivalent of max-width</strong> when defining the viewport dimensions. There is no min-width or orientation support like you’d use in <span class="caps">CSS</span> @media queries. That means you may not be able to line your <code>srcset</code> breakpoints up with your <span class="caps">CSS</span> breakpoints.</p>
<p>There’s some other stuff in the spec worth noting as well. For instance, “if the viewport dimensions or pixel density changes, the user agent can replace the image data with a new image on the fly.” That means (I think) that, while there’s no equivalent to <span class="caps">CSS</span> 3 @media’s <code>orientation</code> query, you could get the same effect because the viewport dimensions change on rotation, triggering larger images to load (though to make that work you’d end up targeting specific device widths, which is not <a href="http://futurefriend.ly/">future-friendly</a>). It’s hard to imagine a scenario in which the pixel density would change, but hey, why not I guess?</p>
<p>There is one very cool part of the spec though, it puts the ultimate decision about which images are served in the hands of the user. </p>
<p>No browser supports it, but the spec says that the higher res images specified in <code>srcset</code> are just candidates. Here’s the <a href="http://www.w3.org/html/wg/drafts/srcset/w3c-srcset/#processing-the-image-candidates">relevant bit</a>:</p>
<blockquote>
<p>Optionally, return the <span class="caps">URL</span> of an entry in <em>candidates</em> chosen by the user agent, and that entry’s associated pixel density, and then abort these steps. The user agent may apply any algorithm or heuristic in its selection of an entry for the purposes of this step.</p>
</blockquote>
<p>So in theory the browser gets the final say. This means the browser can check the available network and make a decision about whether or not to actually obey <code>srcset</code>. For instance it might reject the high-res images on 3G, but accept them over wifi. Even better, mobile browsers could add a user preference so users can say (as they can today with native apps), “I only want high-res images over wifi”. Or all the time or whatever. The user is in control.</p>
<p>I think that’s probably the best way to handle what’s possibly a user-developer conflict. For example, I want my images to look good on your retina iPad, but you might want to save your (possibly) expensive bandwidth for other things. I think the user should trump the developer in that scenario. With <code>srcset</code> the browser can give the user the power to make that decision.</p>
<h2 id="testing-srcset-today">Testing <code>srcset</code> Today</h2>
<p>This is all largely academic right now. Only one browser supports <code>srcset</code> and even that’s just the nightly builds of Apple’s WebKit.</p>
<p>If you want to see it in action, go grab the <a href="http://nightly.webkit.org/">latest WebKit nightly</a>. Here’s a live demo:</p>
<p><img src="/media/images/demos/srcsetdemo-fallback.jpg" srcset="/media/images/demos/srcsetdemo-2x.jpg 2x" alt="demo of srcset in action" width="660"/>
This first test is for retina displays, which looks like this:</p>
<pre><code class="language-markup"><img alt="demo of srcset in action"
src="/media/images/demos/srcsetdemo-fallback.jpg"
srcset="/media/images/demos/srcsetdemo-2x.jpg 2x" />
</code></pre>
<p><img src="/media/images/demos/srcsetdemo-fallback.jpg" srcset="/media/images/demos/srcsetdemo-widthquery.jpg 420w" alt="demo of srcset in action" />
This test is for mobile screens with a maximum viewport of 420px, here’s the code:</p>
<pre><code class="language-markup"><img alt="demo of srcset in action"
src="/media/images/demos/srcsetdemo-fallback.jpg"
srcset="/media/images/demos/srcsetdemo-widthquery.jpg 420w" />
</code></pre>
<p><img src="/media/images/demos/srcsetdemo-fallback.jpg" srcset="/media/images/demos/srcsetdemo-mobile2x.jpg 420w x2" alt="demo of srcset in action" />
The last test is for mobile high res screens and uses this code:</p>
<pre><code class="language-markup"><img alt="demo of srcset in action"
src="/media/images/demos/srcsetdemo-fallback.jpg"
srcset="/media/images/demos/srcsetdemo-mobile2x.jpg 420w x2" />
</code></pre>
<p><img src="/media/images/demos/srcsetdemo-fallback.jpg" srcset="/media/images/demos/srcsetdemo-superwidequery.jpg 9000w" alt="demo of srcset in action" />
This final test is designed to check WebKit’s current implementation, which does not yet support specifying a width. It’s the same query as above, but with a much wider max-width which should trigger it to load in desktop WebKit Nightly.</p>
<pre><code class="language-markup"><img alt="demo of srcset in action"
src="/media/images/demos/srcsetdemo-fallback.jpg"
srcset="/media/images/demos/srcsetdemo-superwidequery.jpg 9000w" />
</code></pre>
<p>As of September 30, 2013, using the latest WebKit Nightly (v8536.30.1, 538+) only the first test works. WebKit only supports the pixel density queries, not the max viewport width query.</p>
<h2 id="which-web-browsers-support-srcset">Which Web Browsers Support <code>srcset</code>?</h2>
<p>Eventually caniuse.org will probably <a href="http://nightly.webkit.org/">add</a> <code>srcset</code> (I think they require at least one shipping version of the feature before they’ll track it), but for now I threw together a table for keeping track of which web browsers support <code>srcset</code>.</p>
<p>Here’s the list as of November 15, 2013:</p>
<div class="longtable">
<table>
<colgroup>
<col style="text-align:left;"/>
<col style="text-align:left;"/>
</colgroup>
<thead>
<tr>
<th style="text-align:left;">Browser</th>
<th style="text-align:left;"><code>srcset</code> support</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left;">WebKit Nightly</td>
<td class="yes" style="text-align:left;">yes</td>
</tr>
<tr>
<td style="text-align:left;">Safari 6</td>
<td class="no" style="text-align:left;">no</td>
</tr>
<tr>
<td style="text-align:left;">Firefox 25</td>
<td class="no" style="text-align:left;">no</td>
</tr>
<tr>
<td style="text-align:left;">Chrome 29</td>
<td class="no" style="text-align:left;">no</td>
</tr>
<tr>
<td style="text-align:left;">Opera 16</td>
<td class="no" style="text-align:left;">no</td>
</tr>
<tr>
<td style="text-align:left;"><span class="caps">IE</span> 10</td>
<td class="no" style="text-align:left;">no</td>
</tr>
<tr>
<td style="text-align:left;">Mobile Safari 7</td>
<td class="no" style="text-align:left;">no</td>
</tr>
<tr>
<td style="text-align:left;">Opera Mini 7</td>
<td class="no" style="text-align:left;">no</td>
</tr>
<tr>
<td style="text-align:left;">Opera Mobile 14</td>
<td class="no" style="text-align:left;">no</td>
</tr>
<tr>
<td style="text-align:left;">Android Default 4.2</td>
<td class="no" style="text-align:left;">no</td>
</tr>
<tr>
<td style="text-align:left;">Chrome for Android</td>
<td class="no" style="text-align:left;">no</td>
</tr>
<tr>
<td style="text-align:left;">Firefox for Android</td>
<td class="no" style="text-align:left;">no </td>
</tr>
</tbody>
</table>
</div>
<p>Yes, it’s a slightly ridiculous table, but with any luck Chrome will be joining the list of <code>srcset</code> supporters in the very near future. That means that Opera will be there as well. My contacts at Mozilla tell me that Firefox is also working on support. So things are looking pretty good for the future. That doesn’t help today though, so if you need something now, remember to check out Nathan Ford’s <a href="http://artequalswork.com/posts/responsive-images/" title="Responsive Images Mega-List">Responsive Images Mega-List</a> for a complete collection of responsive image solutions that work today.</p>
Mon, 30 Sep 2013 20:08:00 ESTWriting in the Open
http://longhandpixels.net//blog/2013/09/writing-in-the-open
http://longhandpixels.net//blog/2013/09/writing-in-the-open
<p>Whew! Crazy weekend. I wasn’t really prepared for how the web would react to learning that <a href="/blog/2013/09/whatever-happened-to-webmonkey">Webmonkey is no more</a>. My inbox blew up. Clearly Webmonkey will be missed. Thanks to everyone who sent me their thoughts on Webmonkey shutting down and all the stories about learning <span class="caps">HTML</span> (<span class="caps">DHTML</span> natch), <span class="caps">CSS</span> or JavaScript from the site. Also, glad to hear that there are apparently so many Webmonkey beanies out there. Anyway, if I’m a little slow responding to you, I apologize, but rest assured I have read everyone’s email and I will get back to you all in the next few days</p>
<p>In the mean time, you should go read Brad Frost’s recent post on <a href="http://bradfrostweb.com/blog/post/designing-in-the-open/" title="bradfrostweb.com, Designing in the Open">Designing in the Open</a>. </p>
<p>Frost and his wife, Melissa, are redesigning the Greater Pittsburgh Community Food Banks website and have decided to do everything in the open so the rest of us can see the process. There’s a <a href="http://foodbank.bradfrostweb.com/">very cool looking timeline</a> and a <a href="http://melissafrostdesign.com/post/pittsburgh-food-bank-open-redesign/">post about their process so far</a>. In that post Melissa quotes a comment Josh Long wrote some time ago on Chris Coyier’s <a href="http://chriscoyier.net/2012/09/23/working-in-public/">Working in Public</a> post (itself a good example) about why you would want to risk the potential embarrassment or ridicule or whatever else you’re afraid of to work publicly:</p>
<blockquote>
<ol>
<li>It makes you think clearly and directly.</li>
<li>It forces you to know what the hell you’re talking about.</li>
<li>It shows people how much you put into your work.</li>
<li>It’s a great way to document your work.</li>
<li>It’s a great way to give back and teach others.</li>
</ol>
</blockquote>
<p>To that I would add a couple more: it teaches you what you know (and don’t), and it’s fun, because really, if this isn’t fun you shouldn’t do it. </p>
<p>The main reason we don’t show our processes more or work in public is fear. Fear that, as Melissa Frost says, you’ll embarrass yourself or that you’ll be seen as a fraud or <your fear here>. Fear is self-created though. Fear is <em>our</em> reaction to an imaginary negative event <em>we’ve</em> projected into the future. It’s something that might happen, but hasn’t. Fear can be helpful. For example, you’re afraid you’ll forget about an important meeting and that fear prompts you to write it down on your calendar. But more often than not fear is not helpful. More often than not fear - that imaginary projection into the future - ends up inhibiting us in the present. It stops you from sharing the stuff you’ve made for instance. I put off launching this site for months, at least partly out of fear. </p>
<p>So fuck fear. I don’t have a cool looking timeline like the Frosts’, nor do I have a super cool working new/old design split for this site like <a href="http://building.seesparkbox.com/">Sparkbox’s open redesign site</a>. But, in lieu of anything else, I do have a screenshot of my responsive web design book in progress: </p>
<p>b’<figure role="group"><a href="http://longhandpixels.net/media/images/2013/rwdbook-inprogress.jpg" title="view larger image">\n <img src="http://longhandpixels.net/media/images/2013/rwdbook-inprogress-sm.jpg" style="width:100%;height:auto;max-width:660px" alt="Responsive Web Design Book In-Progress" /></a>\n<figcaption>Please pardon the terrible titles/subtitles. Those will be improved before this thing goes on sale, I promise.</figcaption>\n</figure>\n’</p>
<p>Does that count as working in the open? Probably not. But that’s the best I can do at the moment. One of the early issues of McSweeneys had a line drawing of a bird with one wing, below it was the caption “trying, trying, trying”. That’s how I feel.</p>
<p>If there’s interest I could write more about what it’s like to write a book (which I could title, how I tricked myself into writing 40,000 words in three weeks). At some point I’d like to take working in the open even further and put the “source” of the book in a public Git repository to make it easy for other people to fix typos, contribute resource links or, well - who knows what else people might end up doing? </p>
<p>I think that’s probably the best reason to do anything “in the open” - it opens more doors for other people. Yeah some of them will be jerks and trolls. But in my experience most of them are not.</p>
<p>And opening the door to others opens the door to serendipity. And serendipity often leads to magic.</p>
<p>When you put things out in the world the world takes them, plays with them - sometimes nicely, sometimes not - and unexpected things start to happen. In my experience these things tend to be good. Random @replies morph into friends, ideas spark others’ imaginations. I find there ends up being a lot of synchronicity - ideas colliding in interesting ways, what Robert Anton Wilson called “<a href="http://www.amazon.com/Coincidance-Head-Robert-Anton-Wilson/dp/1561840041">Coincidance</a>“. </p>
<p>I’ve never tried designing in the open, but I’d like to do more writing in the open. If you’ve got any good ideas on how to do that, please let me know.</p>
<p>Okay, back to work.</p>
Wed, 25 Sep 2013 14:14:00 ESTWhatever Happened to Webmonkey.com?
http://longhandpixels.net//blog/2013/09/whatever-happened-to-webmonkey
http://longhandpixels.net//blog/2013/09/whatever-happened-to-webmonkey
<p>People on Twitter have been asking what’s up with <a href="http://www.webmonkey.com/">Webmonkey.com</a>. Originally I wanted to get this up on Webmonkey, but I got locked out of the <span class="caps">CMS</span> before I managed to do that, so I’m putting it here.</p>
<p>Earlier this year Wired decided to stop producing new content for Webmonkey.</p>
<p>For those keeping track at home, this is the fourth, and I suspect final, time Webmonkey has been shut down (previously it was shut down in 1999, 2004 and 2006).</p>
<p>I’ve been writing for Webmonkey.com since 2000, full time since 2006 (when it came back from the dead for a third run). And for the last two years I have been the sole writer, editor and producer of the site.</p>
<p>Like so many of you, I learned how to build websites from Webmonkey. But it was more than just great tutorials and how tos. Part of what made Webmonkey great was that it was opinionated and rough around the edges. Webmonkey was not the product of professional writers, it was written and created by the web nerds building Wired’s websites. It was written by people like us, for people like us.</p>
<p>I’ll miss Webmonkey not just because it was my job for many years, but because at this point it feels like a family dog to me, it’s always been there and suddenly it’s not. Sniff. I’ll miss you Webmonkey.</p>
<p>Quite a few people have asked me why it was shut down, but unfortunately I don’t have many details to share. I’ve always been a remote employee, not in San Francisco at all in fact, and consequently somewhat out of the loop. What I can say is that Webmonkey’s return to Wired in 2006 was the doing of long-time Wired editor Evan Hansen (<a href="https://medium.com/@evanatmedium">now at Medium</a>). Evan was a tireless champion of Webmonkey and saved it from the Conde Nast ax several times. He was also one of the few at Wired who “got” Webmonkey. When Evan left Wired earlier this year I knew Webmonkey’s days were numbered. </p>
<p>I don’t begrudge Wired for shutting Webmonkey down. While I have certain nostalgia for its heyday, even I know it’s been a long time since Webmonkey was leading the way in web design. I had neither the staff nor the funding to make Webmonkey anything like its early 2000s self. In that sense I’m glad it was shut down rather than simply fading further into obscurity.</p>
<p>I am very happy that Wired has left the site in place. As far as I know Webmonkey (and its ever-popular cheat sheets, which still get a truly astounding amount of traffic) will remain available on the web. That said, note to the <a href="http://www.archiveteam.org/index.php?title=Main_Page">Archive Team</a>, it wouldn’t hurt to create a backup. Sadly, many of the very earliest writings have already been lost in the various <span class="caps">CMS</span> transitions over the years and even much of what’s there now has incorrect bylines. Still, at least most of it’s there. For now.</p>
<p>As for me, I’ve decided to go back to what I enjoyed most about the early days of Webmonkey: teaching people how to make cool stuff for the web. </p>
<p>To that end I’m currently working on a book about responsive design, which I’m hoping to make available by the end of October. If you’re interested drop your email in the box below and I’ll let you know when it’s out (alternately you can follow <a href="https://twitter.com/LongHandPixels">@LongHandPixels</a> on Twitter).</p>
<p>If you have any questions or want more details use the comments box below. </p>
<p>In closing, I’d like to thank some people at Wired — thank you to my editors over the years, especially <a href="http://snackfight.com/">Michael Calore</a>, <a href="https://twitter.com/evanatmedium">Evan Hansen</a> and <a href="http://www.cultofmac.com/about/">Leander Kahney</a> who all made me a much better writer. Also thanks to Louise for always making sure I got paid. And finally, to everyone who read Webmonkey and contributed over the years, whether with articles or even just a comment, thank you. </p>
<p>Cheers and, yes, thanks for all the bananas.</p>
Fri, 20 Sep 2013 21:12:00 EST