<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
    xmlns:admin="http://webns.net/mvcb/"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
    
	<title><![CDATA[High Integrity Design : Blog Articles]]></title>
    <link>http://www.highintegritydesign.com/</link>
	<atom:link href="http://www.highintegritydesign.com/blog/rss" rel="self" />	
    <description>Conversations on web design and life, all mashed together</description>
    <dc:language>en</dc:language>
    <dc:creator>&#110;or&#116;h&#64;highint&#101;g&#114;it&#121;de&#115;ign&#46;&#99;&#111;m</dc:creator>
    <dc:rights>Copyright 2012</dc:rights>
    <dc:date>2012-02-12T01:07:32+00:00</dc:date>
    <admin:generatorAgent rdf:resource="http://expressionengine.com/" />


    <item>
      <title>Creating a modern AJAX contact form in ExpressionEngine</title>
      <link>http://www.highintegritydesign.com/blog/articles/creating-a-modern-ajax-contact-form-in-expressionengine</link>
      <guid>http://www.highintegritydesign.com/blog/articles/creating-a-modern-ajax-contact-form-in-expressionengine#When:01:07</guid>
      <description><![CDATA[
			Through the magic of JQuery and AJAX, you can AJAX-ify EE's built-in contact form to get a more responsive user experience. And you can do it with a minimum of hassle. All you'll need is some fresh JQuery and CSS to go with your ordinary EE contact form in your template. Here's how.
			<p>
	ExpressionEngine has a <a href="http://expressionengine.com/user_guide/modules/email/contact_form.html">nice built-in e-mail contact form</a>&nbsp;which works great. All of the hard work is taken care of for you-- including a custom recipients list, auto fill-in of fields for logged in users, and basic security measures to discourage spammers.</p>
<p>
	It&#39;s great that EE provides a simple and robust contact form. However, as shipped the contact form&#39;s interactive presentation is not very modern-- you get temporarily redirected to a separate success page after you&#39;ve submitted the form, then you get redirected back to your site. This provides a user experience which is not as responsive as I wanted, and didn&#39;t match the look and feel of the rest of my site.</p>
<p>
	There are some great custom form addons for EE, including the flexible and powerful <a href="http://www.solspace.com/software/detail/freeform/">Freeform from Solspace</a>. Freeform does all kinds of useful things, including saving form submissions in the database. But what if all you want is a simple e-mail contact form that&#39;s more responsive and modern?</p>
<h3>
	AJAX-ify it</h3>
<p>
	Through the magic of JQuery and <a href="http://en.wikipedia.org/wiki/AJAX">AJAX</a>, you can AJAX-ify EE&#39;s built-in contact form to get a more responsive user experience. And you can do it with a minimum of hassle. All you&#39;ll need is some fresh JQuery and CSS to go with your ordinary EE contact form in your template. The approach I&#39;ll show you uses EE&#39;s regular contact form tag <code>&#123;exp:email:contact_form&#125;</code> inside a template as you normally would, but it uses JQuery to submit the form through AJAX instead of as a regular HTTP Post. So instead of displaying success or failure on a separate page before redirecting back to your site, you stay on your site&#39;s page the whole time.</p>
<p>
	After posting the form, the JQuery script receives EE&#39;s success or failure page as an HTML AJAX response which it parses to determine if the submit was OK or not. Finally it displays a success or failure message right on the original page. The result is a snappy, modern and seamless feel that maintains your site&#39;s design! Here is an example of the Javascript code you&#39;ll need, below. You&#39;ll combine this with EE&#39;s <a href="http://expressionengine.com/user_guide/modules/email/contact_form.html">contact form template</a> to generate your HTML form.&nbsp;</p>
<p>
	Here&#39;s the Javascript code. Save this script as "contact-form-ajax.js" (or change the name of the script in the sample EE template shown later in this post):</p>
<p>
	<strong>NOTE: be sure to visit my <a href="https://github.com/northk/ee-ajax-contact-form">Github repository</a> to get the latest version of the script and EE template!</strong></p>
<pre class="prettyprint">
// This software is licensed under the MIT License, <a href="http://www.opensource.org/licenses/mit-license.php&#10;//">http://www.opensource.org/licenses/mit-license.php&#10;//</a> Copyright (c) 2012 High Integrity Design, LLC.&nbsp;&nbsp;&nbsp; <a href="http://www.highintegritydesign.com&#10;//&#10;//">http://www.highintegritydesign.com&#10;//&#10;//</a> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated&#10;// documentation files (the "Software"), to deal in the Software without restriction, including without limitation&#10;// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,&#10;// and to permit persons to whom the Software is furnished to do so, subject to the following conditions:&#10;//&#10;// The above copyright notice and this permission notice shall be included in all copies or substantial portions&#10;// of the Software.&#10;//&#10;// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED&#10;// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL&#10;// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF&#10;// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER&#10;// DEALINGS IN THE SOFTWARE.&#10;// *************************************************************************************************************&#10;//&#10;// convert the standard ExpressionEngine contact form to use AJAX.&#10;$(document).ready(function()&#10;{&#10;/* helper function to display a message describing the results of the form submit */&#10;function displayAjaxMessage(message)&#10;{&#10;&nbsp; $("#ajax-message").html(message);&#10;&nbsp; $("#ajax-message").fadeIn(1000);&#10;}&#10;&#10;/* attach a submit handler to the contact form. By default, EE generates the ID "contact_form" */&#10;$("#contact_form").submit(function(event)&#10;{&#10;&nbsp; /* stop the contact form from submitting normally */&#10;&nbsp; event.preventDefault();&#10;&nbsp;&#10;&nbsp; /* hide any left over message from a previous submit */&#10;&nbsp; $("#ajax-message").hide();&#10;&#10;&nbsp; /* send the form data using post and check the results for any errors*/&#10;&nbsp; $.ajax(&#10;&nbsp; {&#10;&nbsp;&nbsp; url: "/",&#10;&nbsp;&nbsp; type: "post",&#10;&nbsp;&nbsp; dataType: "html",&nbsp;&nbsp;&#10;&nbsp;&nbsp; data: $(this).serialize(),&#10;&nbsp;&nbsp;&#10;&nbsp;&nbsp; /* If there was some kind of an AJAX error, display an appropriate message or take some other action of your choice */&#10;&nbsp;&nbsp; error: function(jqXHR, textStatus, errorThrown)&#10;&nbsp;&nbsp; {&#10;&nbsp;&nbsp;&nbsp; displayAjaxMessage("Sorry, there was an error submitting your form. Please call me at 999-999-9999 and I&#39;ll be glad to assist you.");&#10;&nbsp;&nbsp; },&#10;&#10;&nbsp;&nbsp; /*&nbsp; parse the HTML returned by EE to see if they forgot to enter an email address or a message.&#10;&nbsp;&nbsp;&nbsp; If so, the HTML will contain a specific error string we can match, and then we can display our own message */&#10;&nbsp;&nbsp; success: function(html, textStatus, jqXHR)&#10;&nbsp;&nbsp; {&#10;&nbsp;&nbsp;&nbsp; if (html.match(/&lt;title&gt;Error&lt;\/title&gt;/))&#10;&nbsp;&nbsp;&nbsp; {&#10;&nbsp;&nbsp;&nbsp;&nbsp; var error = $(html).find(&#39;ul li:first&#39;).text();&#10;&nbsp;&nbsp;&nbsp;&nbsp; if (error == "A valid sender email is required")&#10;&nbsp;&nbsp;&nbsp;&nbsp; {&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; displayAjaxMessage("Please enter your email address.");&#10;&nbsp;&nbsp;&nbsp;&nbsp; }&#10;&nbsp;&nbsp;&nbsp;&nbsp; else if (error == "Email Message is Required")&nbsp;&nbsp;&nbsp;&nbsp;&#10;&nbsp;&nbsp;&nbsp;&nbsp; {&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; displayAjaxMessage("Please enter a message.");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#10;&nbsp;&nbsp;&nbsp;&nbsp; }&#10;&nbsp;&nbsp;&nbsp; }&#10;&nbsp;&nbsp;&nbsp; else&#10;&nbsp;&nbsp;&nbsp; {&#10;&nbsp;&nbsp;&nbsp;&nbsp; displayAjaxMessage("Thanks for contacting me!");&#10;&nbsp;&nbsp;&nbsp; }&#10;&nbsp;&nbsp; }&#10;&#10;&nbsp; });&#10;});&#10;});</pre>
<p>
	And here is a simple EE template based on the standard EE contact form:</p>
<pre class="prettyprint">
&lt;!DOCTYPE html&gt;&#10;&lt;html lang="en"&gt;&#10;&lt;head&gt;&#10;&lt;meta charset="utf-8"&gt;&#10;&#10;&lt;!--[if lt IE 9]&gt;&#10;      &lt;script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"&gt;&lt;/script&gt;&#10;    &lt;![endif]--&gt;     &#10;   &#10;   &#10;      &lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"&gt;&lt;/script&gt;&#10;      &lt;script src="http://www.yoursite.com/js/contact-form-ajax.js"&gt;&lt;/script&gt;&#10;     &#10;     &#10;      &lt;style&gt;&#10;  body&#10;  {&#10;   width: 30em;&#10;   margin: 2em auto;&#10;  }&#10;  #ajax-message&#10;  {&#10;   border: 1px solid #333;&#10;   background-color: #FFEAEA;&#10;   padding: 1em;&#10;   display: none;&#10;  }&#10;&lt;/style&gt;&#10;&lt;title&gt;AJAX EE Contact Form Test Page&lt;/title&gt;&#10;&lt;/head&gt;&#10;&lt;body&gt;&#10;&#123;exp:email:contact_form user_recipients="no" recipients="you@yourwebsite.com" charset="utf-8"&#125;&#10;        &lt;h2&gt;Support Form&lt;/h2&gt;&#10;        &lt;p id = "ajax-message"&gt;&#10;        &lt;/p&gt;&#10;        &lt;p&gt;&#10;                &lt;label for="from"&gt;Your Email:&lt;/label&gt;&lt;br /&gt;&#10;                &lt;input type="text" id="from" name="from" size="40" maxlength="35" value="{member_email}" /&gt;&#10;        &lt;/p&gt;&#10;        &lt;p&gt;&#10;                &lt;label for="subject"&gt;Subject:&lt;/label&gt;&lt;br /&gt;&#10;                &lt;input type="text" id="subject" name="subject" size="40" value="Contact Form" /&gt;&#10;        &lt;/p&gt;&#10;        &lt;p&gt;&#10;                &lt;label for="message"&gt;Message:&lt;/label&gt;&lt;br /&gt;&#10;                &lt;textarea id="message" name="message" rows="18" cols="40"&gt;&#10;                        Support Email from: {member_name}&#10;                        Sent at:  {current_time format="%Y %m %d"}&#10;                &lt;/textarea&gt;&#10;        &lt;/p&gt;&#10;        &lt;p&gt;&#10;                &lt;input name="submit" type=&#39;submit&#39; value=&#39;Submit Form&#39; /&gt;&#10;        &lt;/p&gt;&#10;&#123;/exp:email:contact_form&#125;&#10;&lt;/body&gt;&#10;&lt;/html&gt;</pre>
<h3>
	<br />
	What you need to change</h3>
<p>
	This post is more of a tutorial-- the sample EE template and JQuery AJAX script above are meant to be a good starting point which you can modify to better suit your needs. You&#39;ll need to modify the template to include your email address and you may want to change the location of the JQuery script, etc. You may also want additional or fewer form fields in your contact form, and you&#39;ll want to modify the CSS to match the style of the rest of your site. For my site, I chose to keep the form ultra-simple and have only a message field.</p>
<h3>
	Which fields are required?</h3>
<p>
	It wasn&#39;t entirely clear to me from the documentation, but EE&#39;s built-in contact form requires the "message" and "from" fields to be filled in if those fields are present in your form. And, there&#39;s no option to make other fields required. That&#39;s a limitation of using EE&#39;s built-in form, but again this solution is for a simple contact form. Solspace&#39;s Freeform addon allows you to specify additional required fields. For a longer discussion of required fields in EE&#39;s built-in contact form, see <a href="http://expressionengine.com/forums/viewthread/207460/">http://expressionengine.com/forums/viewthread/207460/</a>.</p>
<h3>
	Same origin policy problem</h3>
<p>
	An earlier version of my script would work fine when I visited my site using the "www" prefix, but the contact form didn&#39;t work if I left out the "www". What was going on? It turns out I got bit by Javascript&#39;s "<a href="http://en.wikipedia.org/wiki/Same_origin_policy">same origin policy protection</a>". This is a built-in security measure that disallows AJAX requests to a site that&#39;s different than where the originating request comes from. Sounds reasonable, right? Well it is-- except in my case <a href="http://www.highintegritydesign.com">http://www.highintegritydesign.com</a> and highintegritydesign.com were considered different sites! The result was the AJAX request failed.</p>
<p>
	This issue has been fixed in the current version of the script by using a relative path of "/". But, I decided to direct both URL&#39;s to go to <a href="http://www.highintegritydesign.com">http://www.highintegritydesign.com</a> anyway. As a helpful fellow pointed out on <a href="http://stackoverflow.com/questions/4834932/access-is-denied-error-on-ie8-using-jquery-ajaxform">my StackOverflow post</a>&nbsp;about this, it&#39;s a good idea to <a href="http://en.wikipedia.org/wiki/URL_normalization">normalize URL&#39;s</a> for search engine purposes anyway. Here&#39;s what that section of my .htaccess file looks like in case you want to normalize URL&#39;s for your site:</p>
<pre class="prettyprint">
&#9;RewriteCond %{HTTP_HOST} !^www\. [NC]&#10;&#9;RewriteRule ^(.*)$ <a href="http://www.%{HTTP_HOST}/$1">http://www.%{HTTP_HOST}/$1</a> [R=301,L]</pre>
<h3>
	<br />
	Other things that could go wrong</h3>
<p>
	The script parses the HTML page returned by EE to see if the submit succeeded or failed. It does this by looking for specific text patterns in the HTML returned through AJAX. So, if Ellis Labs changes what their HTML or error text looks like for their standard contact form, you would have to update the script to parse their new HTML page. This is something to be aware of if you use this approach. However I doubt they would have a reason to change what their contact form returns, and the script would be easy to change if they did.</p>
<p>
	Also, you&#39;ll notice the script contains an error function that executes in case the AJAX request fails for some reason. In that case I decided to encourage the visitor to call me. But you could take another approach such as attempting the AJAX request again or providing a simple <code>mailto</code> link, for example.</p>
<h3>
	Troubleshooting&nbsp;</h3>
<p>
	If the script isn&#39;t working on your site for some reason, it&#39;s very helpful add some <code>console.log()</code> statements to see what is going on. For example in the <code>success()</code> function you could add <code>console.log(html)</code>; to see what the HTML page returned from EE looks like. Then you can open up the console in Firefox or Chrome to see what happened. If you haven&#39;t used <code>console.log()</code> before, it&#39;s a great debugging tool!</p>
<h3>
	Why not AJAX-ify Solspace Freeform instead?</h3>
<p>
	You could absolutely do this, and Fabian Socarras has a slide set <a href="http://vimeo.com/12909760">showing you how</a>. For my site, I wanted a very simple contact form. I wanted to avoid installing another addon, and I didn&#39;t want to save the form submissions in the database. So I opted to use EE&#39;s built-in contact form instead. However if you have a more complicated form, need more required fields, and/or want to save the submitted data, using Freeform with AJAX would be a great solution.</p>
<h3>
	Credit where credit is due</h3>
<p>
	I can&#39;t take credit for coming up with this idea-- EE community member Rob Sanchez stepped up and pointed me in the right direction on EE&#39;s forum which helped me tremendously in understanding how AJAX works. Thanks a lot Rob! You can <a href="http://expressionengine.com/forums/viewthread/177523/">view the thread here</a>.</p>
<h3>
	Your turn</h3>
<p>
	OK, now you know everything you need to implement your own AJAX contact form in EE-- and it wasn&#39;t very hard! What about using this same approach for other interactions in EE such as a comment submission form? The good news is you can AJAX-ify your comment submission form in the same way. It&#39;s a bit more tricky because there are several error messages you can get back from EE which you have to deal with. But, I&#39;ve done it for my site-- enter a comment to see how it works.</p>
<p>
	Now it&#39;s your turn-- take it away, implement something cool with EE and AJAX, and post back here so we can see it!</p>

			]]>
	  </description>
      <dc:subject>{channel_description}</dc:subject>
      <dc:date>2012-02-12T01:07:32+00:00</dc:date>
    </item>

    <item>
      <title>Faster page loads part two: automating minification with Phing</title>
      <link>http://www.highintegritydesign.com/blog/articles/faster-page-loads-part-two-automating-minification-with-phing</link>
      <guid>http://www.highintegritydesign.com/blog/articles/faster-page-loads-part-two-automating-minification-with-phing#When:03:35</guid>
      <description><![CDATA[
			In part two of the series, I'll show you how to harness the power of a Phing build.xml script to automate your Javascript and CSS minification.
			<p>
	If you read <a href="http://www.highintegritydesign.com/blog/articles/faster-page-loads-part-one-installing-phing-and-yui-compressor">Part 1 of my blog series</a>, you know that modern websites can pay a heavy price in page load times, with all of the Javascript libraries and css files they use. I covered how to install <a href="http://developer.yahoo.com/yui/compressor/">YUI Compressor</a> so you can manually <a href="http://en.wikipedia.org/wiki/Minification_(programming)">minify</a> your Javascript and CSS files. And, I covered how to install <a href="http://www.phing.info/trac/">Phing</a> which will help you automate the process of minification.</p>
<p>
	In this article, I&#39;ll continue my discussion of Phing by presenting you with a <em>finished build.xml file you can customize for your own projects</em>. With a build.xml file, you&#39;ll be able to automate minification of Javascript and CSS files so you don&#39;t have to type long command lines every time you want to run the minifer. But what is a build.xml file and how does it work?</p>
<h3>
	how Phing uses a build.xml file</h3>
<p>
	Phing is a PHP program you run from a command line in <a href="http://www.apple.com/macosx/apps/all.html#terminal">Terminal</a>, that reads and interprets an XML file in order to perform menial tasks you don&#39;t want to type over and over! You write a <a href="http://www.phing.info/docs/guide/stable/chapters/GettingStarted.html#WritingASimpleBuildfile">build.xml file</a> which tells Phing what to do, and Phing will read that file looking for tasks to perform. <em>Phing can intelligently select sets of files to work on, manipulate those files, and perform many types of tasks on them</em>.</p>
<h3>
	Phing building blocks</h3>
<p>
	The main building blocks for Phing are <a href="http://www.phing.info/docs/guide/stable/chapters/ProjectComponents.html">projects, targets, types and tasks</a>. You define these in a build.xml file, which Phing reads in order to know what to do:</p>
<ul>
	<li>
		a <strong>project</strong> is required, and it&#39;s simply a container with a name that wraps all the rest of the stuff in your build.xml file. You get to choose one project name for the build file.</li>
	<li>
		a <strong>target</strong> is a name you choose for a set of logically-related tasks you want Phing to do. For example, you might want Phing to make a separate output folder for your compressed files before running YUI Compressor on the original files. You could put both of these tasks into one target. You can have several targets in one build file. For example you might want one target for minification and another target for creating non-minified, debug output.</li>
	<li>
		a <strong>type</strong> holds a value or collection of values that you can perform tasks on. One of the most common types is a "fileset", which defines a set of files you want to operate on.&nbsp; For example, you might define a fileset for all of your CSS files so you can compress them all at once.</li>
	<li>
		a <strong>task</strong> defines a specific action you want to perform. For example, you might have a task that runs YUI compressor.</li>
</ul>
<p>
	I think the easiest way to explain how a build.xml file works, is to present a finished one and then talk about what each chunk of code does. The good news is, I&#39;ve done most of the work for you and you only have to change a few things to have a working build.xml for your own projects. So without further ado, here is the build.xml file:</p>
<pre class="prettyprint">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;&#10;&#10;&lt;project name="MyProject" default="all" basedir="./"&gt;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;!-- Modify the following lines for your project:                       --&gt;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;property name="yui-jarfile" value="/usr/local/bin/yuicompressor-2.4.6/build/yuicompressor-2.4.6.jar" /&gt;&#10;    &lt;property name="js-source-directory" value="./js-source" /&gt;&#10;    &lt;property name="js-output-directory" value="./js-output" /&gt;&#10;    &lt;property name="css-source-directory" value="./css-source" /&gt;&#10;    &lt;property name="css-output-directory" value="./css-output" /&gt;&#10;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;!-- Target: clean-css                       --&gt;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;target name="clean-css"&gt;&#10;        &lt;echo msg="**** Creating output directory for CSS files." /&gt;&#10;        &lt;mkdir dir="${css-output-directory}" /&gt;&#10;        &lt;echo msg="**** Cleaning output directory." /&gt;       &#10;        &lt;delete&gt;&#10;         &lt;fileset dir="${css-output-directory}"&gt;&#10;          &lt;include name="*.css" /&gt;&#10;         &lt;/fileset&gt;&#10;        &lt;/delete&gt;&#10;    &lt;/target&gt;&#10;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;!-- Target: clean-js                       --&gt;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;target name="clean-js"&gt;&#10;        &lt;echo msg="**** Creating output directory for Javascript files." /&gt;&#10;        &lt;mkdir dir="${js-output-directory}" /&gt;&#10;        &lt;echo msg="**** Cleaning output directory." /&gt;&#10;        &lt;delete&gt;&#10;            &lt;fileset dir="${js-output-directory}"&gt;&#10;                &lt;include name="*.js" /&gt;&#10;            &lt;/fileset&gt;&#10;        &lt;/delete&gt;&#10;    &lt;/target&gt;&#10;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;!-- Target: clean-all                       --&gt;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;target name="clean-all" depends="clean-css, clean-js"&gt;&#10;    &lt;/target&gt;&#10;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;!-- Target: css                       --&gt;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;target name="css" depends="clean-css"&gt;&#10;        &lt;echo msg="**** Minifying CSS files." /&gt;&#10;        &lt;foreach param="filename" absparam="absfilename" target="minify-css-file"&gt;&#10;            &lt;fileset dir="${css-source-directory}"&gt;&#10;                &lt;include name="*.css"/&gt;&#10;            &lt;/fileset&gt;&#10;        &lt;/foreach&gt;&#10;    &lt;/target&gt;&#10;&lt;target name="minify-css-file"&gt;&#10;  &lt;exec command="java -jar ${yui-jarfile} -o ${css-output-directory}/${filename} ${css-source-directory}/${filename}" checkreturn="true" /&gt;&#10;&lt;/target&gt;&#10;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;!-- Target: js                       --&gt;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;target name="js" depends="clean-js"&gt;&#10;        &lt;echo msg="*** Minifying Javascript files." /&gt;&#10;        &lt;foreach param="filename" absparam="absfilename" target="minify-javascript-file"&gt;&#10;            &lt;fileset dir="${js-source-directory}"&gt;&#10;                &lt;include name="*.js"/&gt;&#10;                &lt;exclude name="*.min.js"/&gt;                               &#10;            &lt;/fileset&gt;&#10;        &lt;/foreach&gt;&#10;    &lt;/target&gt;&#10;    &lt;target name="minify-javascript-file"&gt;&#10;  &lt;exec command="java -jar ${yui-jarfile} -o ${js-output-directory}/${filename} ${js-source-directory}/${filename}" checkreturn="true" /&gt;&#10;    &lt;/target&gt;&#10;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;!-- Target: debug-css                                 --&gt;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;target name="debug-css" depends="clean-css"&gt;&#10;        &lt;echo msg="**** Copying CSS source files to output directory." /&gt;&#10;        &lt;copy todir="${css-output-directory}"&gt;&#10;            &lt;fileset dir="${css-source-directory}"&gt;&#10;                &lt;include name="*.css"/&gt;&#10;            &lt;/fileset&gt;&#10;        &lt;/copy&gt;&#10;    &lt;/target&gt;&#10;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;!-- Target: debug-js                                 --&gt;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;target name="debug-js" depends="clean-js"&gt;&#10;        &lt;echo msg="**** Copying Javascript source files to output directory." /&gt;&#10;        &lt;copy todir="${js-output-directory}"&gt;&#10;            &lt;fileset dir="${js-source-directory}"&gt;&#10;                &lt;include name="*.js"/&gt;&#10;                &lt;exclude name="*.min.js"/&gt;               &#10;            &lt;/fileset&gt;&#10;        &lt;/copy&gt;&#10;    &lt;/target&gt;&#10;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;!-- Target: debug-all                                 --&gt;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;target name="debug-all" depends="clean-all, debug-css, debug-js"&gt;&#10;    &lt;/target&gt;&#10;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;!-- Target: all                                 --&gt;&#10;    &lt;!-- ============================================  --&gt;&#10;    &lt;target name="all" depends="clean-all, css, js"&gt;&#10;    &lt;/target&gt;&#10;&lt;/project&gt;</pre>
<h3>
	<br />
	modify the top section for your project</h3>
<p>
	At the top of the file, you&#39;ll see a section that says <em>Modify the following lines for your project</em>. This section tells Phing where to find the files you want to work with. You&#39;ll need to modify five lines in that section to point to the <a href="http://en.wikipedia.org/wiki/File_path">paths to your files</a>. The file paths tell Phing:</p>
<ul>
	<li>
		where to find the YUI Compressor executable jar file</li>
	<li>
		where your original, uncompressed Javascript files are</li>
	<li>
		where you want the minified Javascript output files to be placed</li>
	<li>
		where your original, uncompressed CSS files are</li>
	<li>
		where you want the minified CSS output files to be placed</li>
</ul>
<p>
	<strong><em>These are the only lines of code you&#39;ll need to modify, in order to have a working build.xml file!</em></strong> If you followed along in Part 1, hopefully you&#39;ll know where the path to the YUI Compressor jar file is on your system. If you don&#39;t remember where it is, you can use Spotlight to search for the name of the jar file. Mine is at <code>/usr/local/bin/yuicompressor-2.4.6/build/yuicompressor-2.4.6.jar</code>, since I installed it in <code>/usr/local/bin</code> as <a href="http://www.highintegritydesign.com/blog/articles/faster-page-loads-part-one-installing-phing-and-yui-compressor">Part 1 outlines</a>.</p>
<p>
	As you can see, I specified the complete path to YUI Compressor in the build.xml file. That way, you can store the build.xml file anywhere on your system and it will know where to find YUI Compressor. I like to store my build.xml file one level above the folders that contain my Javascript and CSS source files.</p>
<p>
	I made the paths to the other folders relative. For example the line that says <code>&lt;property name="js-source-directory" value="./js-source" /&gt;</code> means <em>"starting from the current folder, go down one level to a folder called js-source and look for the Javscript source files there."</em></p>
<p>
	<strong>It&#39;s a good idea to define separate folders for your original source files and your minified files, so you don&#39;t accidentally overwrite something you didn&#39;t intend to!</strong> Plus it keeps things nice and tidy. You are using <a href="http://en.wikipedia.org/wiki/Revision_control">revision control</a> in case you mess up and overwrite a file, aren&#39;t you?</p>
<h3>
	the "clean" targets</h3>
<p>
	The <code>clean-css</code>, <code>clean-js</code>, and <code>clean-all</code> targets delete any output files from previous runs of Phing. I separated these out so you can choose to clean up only the CSS files or Javascript files independently, according to your needs. Here you can see how I used the Phing "depends" syntax to define that <code>clean-all</code> will first run the other cleaning tasks. In fact, that is all it does!</p>
<p>
	These targets will also create folders for their output files if those folders don&#39;t already exist. You can see how they define a fileset to work on. For example, <code>clean-css</code> defines a fileset "*.css" so all of the minified CSS files generated previously will get deleted. To delete all previously minified files, just type the following command <em>(note that you need to be in the folder in Terminal where your build.xml file is)</em>:</p>
<pre class="prettyprint">
phing clean-all</pre>
<h3>
	<br />
	the "css" target</h3>
<p>
	This task minifies all CSS files in the CSS source folder (which is defined by the property name at the top of the file called <code>css-source-directory</code>. It will output the minified files to the location specified by the property name <code>css-output-directory</code>. Remember, you need to change the <code>css-source-directory</code> and <code>css-output-directory</code> paths to point where you want them! To minify all your CSS files at once, simply type:</p>
<pre class="prettyprint">
phing css</pre>
<p>
	Now wasn&#39;t that easy? You can see the benefit of using Phing to automate menial tasks like running the minifier on a bunch of files!</p>
<h3>
	the "js" target</h3>
<p>
	This task minifies all the Javascript source files found in the source folder defined with <code>js-source-directory</code>, and sticks the minified files into the <code>js-output-directory</code>. It&#39;s very similar to the <code>css</code> target, except it builds its fileset from your Javascript files. To run it, just type:</p>
<pre class="prettyprint">
phing js</pre>
<h3>
	<br />
	why no .min?</h3>
<p>
	One thing you&#39;ll notice is my build.xml does not add the suffix ".min.js" to the minified Javascript files (which a lot of people do). So why did I do it that way? I decided to break with tradition because I want the files named the same whether they are minified or not. Then I can SFTP them to my site, going back and forth between minified and non-minified code (for debugging) without changing any HTML that points to those files.</p>
<h3>
	so what about debugging?</h3>
<p>
	If you look at minified Javascript or CSS, it&#39;s not very readable. So if you have a bug you&#39;ll want to work with your original uncompressed files so you can follow along in <a href="http://getfirebug.com/">Firebug</a>. My build.xml makes this easy by providing three targets, <code>debug-css</code>, <code>debug-js</code>, and <code>debug-all</code>. All these do is copy over the original source files to the folder you designated to hold the minified files.</p>
<p>
	Then, as mentioned above you can SFTP those files over to your site and debug to your heart&#39;s content with fully commented source code. Yay! When you&#39;ve fixed the bug just run Phing again to re-compress your files and SFTP them to your site once more.</p>
<h3>
	so why no SFTP target?</h3>
<p>
	OK, you got me. I wish there was an SFTP task type for Phing, but unfortunately as of this writing <em>there is no built-in SFTP task</em>. There is an SCP task type, but my web host doesn&#39;t support SCP. That&#39;s really too bad. It would be great if I could include an SFTP task as part of my minification targets so all the files would automatically get copied over to my live site.</p>
<p>
	There may be an extension or a trick for Phing which provides SFTP, but if so I haven&#39;t found it yet. I&#39;ll probably end up with an <code>exec</code> SFTP command line in my build.xml file, but that&#39;s tricky to automate since SFTP requires authentication (and a password). Stay tuned for me to come up with a solution, or better yet, let me know how you solved it!</p>
<h3>
	the "all" target</h3>
<p>
	All this target does is clean up all previously generated files, then it minifies everything. Super easy and you can see how powerful it is to use the "depends" syntax in Phing. Hint: you can get the same effect just by typing <code>phing</code> and nothing else! To run it, just type:</p>
<pre class="prettyprint">
phing</pre>
<h3>
	<br />
	Phing can do a lot more</h3>
<p>
	Well, that&#39;s pretty much it for my build.xml file. Phing is a very powerful build automation tool, and I&#39;ve barely scratched the surface of what it can do. For example you can have your build script automatically run tests, and much more. Check out the <a href="http://www.phing.info/docs/guide/stable/">Phing documentation</a> and you&#39;ll see what I mean!</p>
<h3>
	other compression tools</h3>
<p>
	Finally, there are other great minification tools besides YUI Compressor. I actually use <a href="http://compass-style.org/">Compass</a> most of the time rather than YUI Compressor. Compass is a fantastic tool that does much more than compression. It actually <em>adds new syntax to CSS and pre-compiles it so you can do things like use true inheritance!</em> I don&#39;t think I could get along without it. But that&#39;s a whole other post.</p>
<p>
	I hope this series of posts helps you learn and master Phing, creating your own build.xml files that do amazing things. When you do, please come back and share with the rest of us!</p>

			]]>
	  </description>
      <dc:subject>{channel_description}</dc:subject>
      <dc:date>2011-11-05T03:35:21+00:00</dc:date>
    </item>

    <item>
      <title>Faster page loads part one: installing Phing and YUI Compressor</title>
      <link>http://www.highintegritydesign.com/blog/articles/faster-page-loads-part-one-installing-phing-and-yui-compressor</link>
      <guid>http://www.highintegritydesign.com/blog/articles/faster-page-loads-part-one-installing-phing-and-yui-compressor#When:01:02</guid>
      <description><![CDATA[
			If you are building modern websites like me, you're probably using plenty of Javascript and CSS. It can take a significant chunk of time to load these resources. So is there an easy way to reduce the load time on all those scripts and CSS? And will it really make a difference? Yes, and Yes!
			<p>
	Modern websites tend to use lots of Javascript and the CSS files are pretty good-sized as well. Javascript makes for a great user experience, but all of that code can slow down page loads. As you probably know, Google <a href="http://www.mattcutts.com/blog/site-speed/">now incorporates page load speed</a> as part of their algorithm for determining their search results.</p>
<p>
	More importantly, research shows that <a href="http://www.reuters.com/article/2011/07/19/idUS40241718520110719">real people hate waiting for slow page loads</a>, especially on mobile devices. A lot of people simply abandon websites with slow load times. But, do you really need a study to prove that? I have little patience myself for websites that load slowly!</p>
<h3>
	measuring page load speed</h3>
<p>
	Using <a href="http://code.google.com/chrome/devtools/docs/network.html">Chrome&#39;s developer tools</a>&nbsp;or <a href="http://getfirebug.com/network">Firebug</a>&nbsp;in Firefox, you can easily see just how much time it takes to load all that CSS and Javascript. You&#39;ll probably find like me, that it takes a significant chunk of time to load these resources.</p>
<p>
	So is there an easy way to reduce the load time on all those scripts and CSS? And will it really make a difference? The answers are Yes, and Yes! Using YUI Compressor, you can<em> easily&nbsp;reduce the size of these assets by 50% or more, making a real-world noticable difference in page load times. </em></p>
<p>
	<a href="http://en.wikipedia.org/wiki/Minification_(programming)"><strong>Minification</strong></a> tools such as <a href="http://developer.yahoo.com/yui/compressor/">YUI Compressor</a> remove all unnecessary characters from programming code without changing how the code works. Stuff like white space characters and comments which add readability but are not required for the code to run. Minification tools will often change the names of programming variables, function names etc to be shorter as well.</p>
<p>
	Taking a look at Google&#39;s <a href="http://code.google.com/speed/page-speed/docs/payload.html">best practices for page load performance</a>, minification of both Javascript and CSS files are listed as major ways you can improve your site&#39;s load speed.&nbsp;</p>
<p>
	<img alt="Firebug load time screen capture" class="caption" src="http://www.highintegritydesign.com/uploads/firebug-timing-capture.png" style="width: 700px; height: 231px; " /></p>
<h3>
	but does it really make a difference?</h3>
<p>
	I tested load times for my home page using Firebug, gathering timings both before and after minification of javascript and css. I ran each test five times and took the average, clearing the browser cache between each run. My site doesn&#39;t use that much Javascript or CSS, and<strong> I was still able to reduce load times by .67 seconds which is a 24% savings</strong>. This is basically free speed. On a more complex site the savings would be significant.</p>
<p>
	<img alt="Average load times before and after minification" class="caption" src="http://www.highintegritydesign.com/uploads/load-time-chart.png" style="width: 483px; height: 291px; " /></p>
<h3>
	but isn&#39;t it a hassle?</h3>
<p>
	I knew I should have learned to do this a long time ago. But I didn&#39;t because I thought it would be too much hassle.&nbsp;But I discovered that using a build automation tool like <a href="http://www.phing.info/trac/">Phing</a> along with <a href="http://developer.yahoo.com/yui/compressor/">YUI Compressor</a>, it&#39;s quite easy. There are several steps to set things up, but none of them is particularly complicated so I hope you&#39;ll give it a try. If you get stuck feel free to email me or enter a comment describing what isn&#39;t working, and if I have time I&#39;ll help!</p>
<p>
	I&#39;m going to focus on Mac OS X for this article since that&#39;s what I use most of the time. But, much of it will apply if you use Windows as well. In part one, we&#39;ll install Phing and YUI Compressor. In part two, we&#39;ll write a Phing build script that automates the javascript and css minification tasks for us.</p>
<h3>
	what is Phing?</h3>
<p>
	<a href="http://www.phing.info/trac/">Phing</a>&nbsp;is an open-source <a href="http://en.wikipedia.org/wiki/Build_automation">build automation tool</a> that executes tedious build tasks based on rules you give it in a build script. The kind of tasks you don&#39;t want to type manually over and over. For example, you could tell Phing to minify all Javascript files in your &#39;source&#39; folder and save the minified Javascript files to a &#39;deploy&#39; folder. You could even tell Phing to then FTP all of the minified files to their place on the server.</p>
<h3>
	what is YUI Compressor?</h3>
<p>
	<a href="http://developer.yahoo.com/yui/compressor/">YUI Compressor</a>&nbsp;is a great open-source tool that minifies both Javascript and CSS. That&#39;s what we&#39;ll cover in this article. However, there are other good compression tools out there. My intention is for you to feel comfortable enough with Phing to explore it and write your own build script that uses whatever tools you like.</p>
<h3>
	you&#39;ll need to use Terminal</h3>
<p>
	<a href="http://www.apple.com/macosx/apps/all.html#terminal">Terminal</a>&nbsp;is an OS X application which allows you to interact with your system by typing <a href="http://en.wikipedia.org/wiki/Command-line_interface">command lines</a>. If you haven&#39;t used it before, don&#39;t be afraid because it&#39;s not a big deal. Phing and YUI Compressor run from a command line, so you&#39;ll need to use Terminal in order for these tools to work.</p>
<h3>
	you need PHP, Pear and Java too</h3>
<p>
	If you&#39;re using OS X, you&#39;re lucky because PHP and Pear are all installed already. Phing requires PHP to run. And Pear is a PHP tool which installs additional PHP components that are not on your system by default (and it&#39;s what we need to install Phing). Finally, YUI Compressor requires Java to run. Java is already installed on most versions of OS X, but it looks like it <a href="http://reviews.cnet.com/8301-13727_7-20081032-263/java-for-os-x-lion-available-from-apple/">may not be installed on OS X Lion</a>. So I&#39;ll cover installing Java on OS X Lion below.</p>
<h3>
	OK, let&#39;s get to it</h3>
<p>
	First things first, let&#39;s install Phing using Pear. Open a new Terminal session by using the Finder to go to Applications-&gt;Utilities-&gt;Terminal.</p>
<p>
	You&#39;ll need choose an install location for Phing. I chose to install it in the&nbsp;<code>/usr/local/bin</code> folder. That&#39;s the recommended location for tools such as this, and it will give all users of your machine access to Phing. Here&#39;s how:</p>
<pre class="prettyprint">
cd /usr/local/bin&#10;sudo pear channel-discover pear.phing.info&#10;sudo pear install phing/phing</pre>
<p>
	You will need to type in your administrator password in order to install Phing in <code>/usr/local/bin</code>. If you get the error "<code>Notice: unserialize(): Error at offset 276 of 1133 bytes in Config.php on line 1050</code>", you&#39;ll need to delete the bad Pear configuration file that was included in some versions of MAMP (note that your version number for MAMP may be different than mine). Then, re-run the sudo command again from above (make sure you&#39;ve changed directories back to <code>/usr/local/bin</code>. Here&#39;s how you delete the bad Pear config file:</p>
<pre class="prettyprint">
cd /Applications/MAMP/bin/php/php5.3.6/conf&#10;rm pear.conf</pre>
<p>
	Next, change directories back to <code>/usr/local/bin</code> and see if you can access Phing. In your Terminal window type:</p>
<pre class="prettyprint">
cd /usr/local/bin&#10;Phing -v</pre>
<p>
	If you get an error that Phing can&#39;t be found, you&#39;ll need to change your PATH. Your PATH tells Terminal where to look for stuff on you computer. If Phing is found, you can skip ahead to "<strong>Install Java</strong>".</p>
<h3>
	changing your path</h3>
<p>
	When you type a command from a Terminal session in OS X, it looks for that command using the folders (also called directories) listed in your PATH as &#39;places to search&#39;. If Terminal can&#39;t find the command on your machine, you&#39;ll need to modify your PATH to tell it where to look for that command. This is probably the most tricky part of setting up Phing and YUI Compressor.</p>
<p>
	You tell Terminal where to look for commands by editing your PATH variable in a hidden file called ".profile". This file is in your <a href="http://en.wikipedia.org/wiki/Home_directory">home directory</a>, for example "<code>/Users/Joe</code>". To get to your home directory and display your .profile, in Terminal type:</p>
<pre class="prettyprint">
cd ~&#10;cat .profile&#10;pwd</pre>
<p>
	This will display your .profile as well as the current directory you are in. If you want to know more about each of these commands, check out <a href="http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/index.html#//apple_ref/doc/framework/manpages">Apple&#39;s developer docs</a>.</p>
<p>
	First make a backup of your .profile:</p>
<pre class="prettyprint">
cp .profile profile-backup</pre>
<p>
	Now open your .profile in TextEdit with:</p>
<pre class="prettyprint">
open -t .profile</pre>
<p>
	Look in .profile for a section that says "<code>export PATH=</code>". If you find that section but Terminal can&#39;t find the commands, you need to add a piece to the end of your PATH that tells Terminal where to look for the command. If you don&#39;t have a PATH section at all, you&#39;ll need to add one.</p>
<p>
	If you installed Phing in <code>/usr/local/bin</code>, then that&#39;s what you need to add to the end of your path. For example, my PATH looks Like this:<br />
	<code>export PATH=/usr/bin:/usr/sbin:/sbin:/usr/local/bin:$PATH</code></p>
<p>
	Make sure there are colons between path sections, and that there is a "<code>:$PATH</code>" at the end. This tells Terminal to tack on whatever PATH was already set up before .profile modifies it. Now save the file, close the terminal window and open a new terminal window so the new PATH will take effect. Again test to see if you can run Phing:</p>
<pre class="prettyprint">
Phing -v</pre>
<p>
	If you can get this to work, everything else will be easy! If you want to know more about how to modify your PATH in .profile, <a href="http://www.tech-recipes.com/rx/2621/os_x_change_path_environment_variable/">read this</a>.&nbsp;If you really mess things up, just copy the backup you made to your .profile and start over:</p>
<pre class="prettyprint">
cd ~&#10;cp profile-backup .profile</pre>
<br />
<h3>
	install Java</h3>
<p>
	First, let&#39;s see if you already have Java installed. If you have OS X prior to Lion, then you probably do. In your Terminal window, type:</p>
<pre class="prettyprint">
java -version</pre>
<p>
	This should tell you that you can run Java and what the version is. If you have OS X Lion but Terminal tells you it can&#39;t find the command, you probably don&#39;t have Java installed and will need to do so. <a href="http://support.apple.com/kb/DL1421">Get it from Apple here</a>.&nbsp;I suspect the Apple installer will do everything for you that needs doing, including updating your PATH so Java can be found. You may need to close your Terminal window and re-open it after installing Java though.</p>
<h3>
	install YUI Compressor</h3>
<p>
	Okay, next let&#39;s install YUI compressor. First <a href="http://yuilibrary.com/download/yuicompressor/">download the tool</a>.&nbsp;Open a finder window in <code>/usr/local/bin</code> by typing:</p>
<pre class="prettyprint">
open -a Finder /usr/local/bin</pre>
<p>
	Then unzip the downloaded YUI Compressor folder and copy it from your Download folder to <code>/usr/local/bin</code> using Finder. Finder will ask you to authenticate before it will copy the files. Check if YUI Compressor is working by typing:</p>
<pre class="prettyprint">
java -jar /usr/local/bin/yuicompressor-x.y.z/build/yuicompressor-x.y.z.jar</pre>
<p>
	Where x.y.z is the version of YUI Compressor you downloaded. This should give you the usage help information for YUI Compressor.</p>
<h3>
	everything&#39;s installed - let&#39;s do some compression!</h3>
<p>
	Finally, you&#39;ve got everything installed, whew! Let&#39;s run YUI compressor on your files and see how much it reduces their size. Create a test folder in Finder and copy your original, uncompressed files there. Then in terminal, go to your test folder and type commands like these (but using the location of your test folder and the version number of YUI Compressor that you downloaded):</p>
<pre class="prettyprint">
cd /users/north/desktop/test&#10;java -jar /usr/local/bin/yuicompressor-2.4.6/build/yuicompressor-2.4.6.jar -o &#39;.css$:-min.css&#39; *.css&#10;&#10;java -jar /usr/local/bin/yuicompressor-2.4.6/build/yuicompressor-2.4.6.jar -o &#39;.js$:-min.js&#39; *.js</pre>
<p>
	This will compress all your CSS and javascript files in that directory, into files that are named the same but with "-min.css" or "-min.js". <strong>NOTE</strong>: this command will only work if you have multiple files to compress. Here&#39;s an example of a command to compress a single file called "script-setup.js":</p>
<pre class="prettyprint">
java -jar /usr/local/bin/yuicompressor-2.4.6/build/yuicompressor-2.4.6.jar -o script-setup-min.js script-setup.js</pre>
<p>
	Now upload those compressed files to your site and see how much faster your pages load!</p>
<h3>
	what comes next</h3>
<p>
	We covered a lot in this article-- you can now compress javascript and CSS files manually any time you want, and we installed Phing. However, the real power comes when you use Phing to automate the process instead of typing a long command every time. Stay tuned for <a href="http://www.highintegritydesign.com/blog/articles/faster-page-loads-part-two-automating-minification-with-phing">part two</a> to learn how to make this a piece of cake!</p>
<p>
	&nbsp;</p>

			]]>
	  </description>
      <dc:subject>{channel_description}</dc:subject>
      <dc:date>2011-09-01T01:02:06+00:00</dc:date>
    </item>

    <item>
      <title>Equally spaced horizontal navigation links that align with their container : a JQuery script</title>
      <link>http://www.highintegritydesign.com/blog/articles/equally-spaced-horizontal-navigation-links-jquery-script</link>
      <guid>http://www.highintegritydesign.com/blog/articles/equally-spaced-horizontal-navigation-links-jquery-script#When:16:44</guid>
      <description><![CDATA[
			Have you ever wanted a list of equally-spaced navigation links that line up with the left and right edges of their container?  I don't think CSS can do that, so I wrote a JQuery script.
			<h3>
	the problem</h3>
<p>
	Recently, I needed to create a horizontal navigation list of text links, with the links being equally spaced. Also the links needed to be variable-width. Finally, the links needed to line up with the edges of their fixed-width <code>&lt;ul&gt;</code> container for a "justified" look, like this:</p>
<p>
	<img alt="Navigation links screen capture" src="http://www.highintegritydesign.com/uploads/nav-links-snip.PNG" style="width: 512px; height: 33px;" /></p>
<p>
	You can see from the green container border how the first nav link lines up with the left side of the container, the last nav link&#39;s right edge lines up with the right side of the container, and the links are equally spaced.&nbsp; The overall effect would look similar to <a href="http://www.potterybarn.com/">Pottery Barn&#39;s</a> top nav links (only they used images for their links!). The HTML code looks like this:</p>
<pre class="prettyprint">
&lt;ul id="main-nav"&gt;&#10;&lt;li&gt;&lt;a href="#"&gt;item one&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#"&gt;longer item two&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#"&gt;item 3&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#"&gt;another item&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#"&gt;5th item&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</pre>
<h3>
	easy, right?</h3>
<p>
	Well, that&#39;s easy to do in CSS, right? Unfortunately, I don&#39;t think so.<em> It&#39;s tricky to get equal spacing with the first and last links lining up with the edges of their container, when each link is variable-width.</em> I Google&#39;d far and wide for solutions on how to do this, and surprisingly I came up empty. The closest solution I found is <a href="http://css-tricks.com/577-equidistant-objects-with-css/">this article on CSS-Tricks</a>. However, I think the article solves a slightly different problem than I was trying to solve.</p>
<p>
	I even posted a <a href="http://stackoverflow.com/questions/6509183/evenly-spaced-navigation-links-that-take-up-entire-width-of-ul-in-css3/6515301#6515301">question to StackOverflow</a> and got a few answers. But, it doesn&#39;t look like people understood my question. They even down-voted it-- ouch!</p>
<h3>
	so, how do you do it?</h3>
<p>
	After thinking about how to do this in CSS until my brain hurt, I realized I could do it pretty easily in JQuery-- we just need a little math. Here is the algorithm:</p>
<pre>
<code>X = the sum of all of the rendered widths of each link as calculated by JQuery.&#10;Y = the width of the container the links are in.&#10;Z = (Y - X) / (number of links - 1), rounded down. This is the spacing we need between each link!</code></pre>
<p>
	I rounded down so the script wouldn&#39;t cause the spacing to be off by a pixel (too big) which would cause the list of links to overflow their container. All that&#39;s left for the script to do is give each link a margin-right equal to "Z".</p>
<p>
	Well, actually it&#39;s a bit more tricky than that. We have to remove the margin-right from the last link, so it will line up with the right edge of the container without overflowing.</p>
<h3>
	algorithm != reality</h3>
<p>
	There was one more problem I had to fix. For some navigation lists, the last link was not lining up with the right edge of its container. Instead, it overflowed the container and wrapped to another line.</p>
<p>
	I had rounded down on the link spacing calculation, and the links had no additional padding or margin other than the margin-right my script gave them. So what the heck was going on? Not acceptable! After scratching my head on this, I couldn&#39;t figure out what might be wrong with my algorithm.</p>
<p>
	So I screen-captured the navigation links as rendered in the browser and brought them into Photoshop to measure their widths, comparing those rendered widths to the width JQuery calculated for each link. <em>Their actual rendered widths were different from what JQuery calculated for some links!</em> Sometimes JQuery was off by a pixel, plus or minus. Double what-the-heck?</p>
<p>
	I can only conclude that somehow JQuery wasn&#39;t measuring the full rendered width of the links correctly-- though that is hard for me to believe. It&#39;s very unlikely that I found a bug in JQuery or in the browser DOM, but I just don&#39;t have any other explanation. Do you?</p>
<h3>
	how I fixed it</h3>
<p>
	I realized the fix was pretty easy. Just remove the margin-right from both the last link and the second-to-last link, and then float the last link right. This will force the last link to line up with the right side of its container. And removing the margin-right on the second-to-last link will create a "shock-absorber" between it and the last link. The "shock-absorber" will allow a little bit of pixel-flex between the two links, which will make up for any small errors in width calculations.</p>
<p>
	This is hard to explain so I encourage you to look at the CSS my script tacks onto each <code>&lt;li&gt;</code>, in FireBug. Here&#39;s a picture that may help:</p>
<p>
	<img alt="Navigation links showing no margins on last two links" src="http://www.highintegritydesign.com/uploads/nav-links-snip-2.png" style="width: 512px; height: 150px;" /></p>
<h3>
	the jquery.justifyNav.js plug-in</h3>
<p>
	Without further ado, here is the final script. I am licensing it under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT license</a>, so you can use it for commercial purposes if you want. You should <a href="https://github.com/northk/justifyNav">check my respository on GitHub</a> to see if there is a newer version of this script!</p>
<pre class="prettyprint">
// jquery.justifyNav.js plug-in&#10;// This software is licensed under the MIT License&#10;// Copyright (c) 2011 High Integrity Design, LLC.&nbsp;&nbsp;&nbsp; &#10;// highintegritydesign.com&#10;//&#10;&#10;(function($) {&#10;$.fn.justifyNav = function() {&#10;  return this.each(function() {&#10;   var $this = $(this),&#10;    $children = $this.children(),&#10;    containerWidth = $this.width(),&#10;    linksWidth = 0,&#10;    count = $children.length;&#10;   $children.each(function() {&#10;    linksWidth += $(this).width();&#10;   });&#10;&#10;   // Don&#39;t give the last item or the 2nd to last item any right margin, then float the last item right.&#10;   // This will account for small errors in JQuery&#39;s calculation of the item widths.&#10;   // Otherwise the list can overflow the container!&#10;   var linkSpacing = Math.floor((containerWidth - linksWidth) / (count - 1));&#10;   $children&#10;    .css(&#39;margin-right&#39;, linkSpacing + "px")&#10;    .filter(":last")&#10;     .css({"margin-right":0,"float":"right"})&#10;     .prev()&#10;      .css({"margin-right":0});&#10;  });&#10;};&#10;})(jQuery);</pre>
<p>
	<br />
	Here is an HTML example of how to use the script:</p>
<pre class="prettyprint">
&lt;!DOCTYPE html&gt;&#10;&lt;html lang="en"&gt;&#10;&lt;head&gt;&#10;&lt;meta charset="utf-8" /&gt;&#10;&lt;script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.js"&gt;&lt;/script&gt; &#10;    &lt;script src="jquery.justifyNav.js"&gt;&lt;/script&gt;&#10;&lt;script&gt;&#10;  $(document).ready(function(){&#10;   $(&#39;ul#main-nav&#39;).justifyNav();&#10;  });&#10;&lt;/script&gt;&#10;&lt;title&gt;jquery.justifyNav example&lt;/title&gt;&#10;&lt;style&gt;&#10;  * {margin: 0; padding: 0;}&#10;  #main-nav {width: 500px; margin:50px auto; border: 1px solid green;  overflow: hidden; *zoom: 1;}&#10;  #main-nav li {display: block; float: left;}&#10;  #main-nav li a {display: inline-block;}&#10;&lt;/style&gt;&#10;&lt;/head&gt;&#10;&lt;body&gt;&#10;&lt;ul id="main-nav"&gt;&#10;&lt;li&gt;&lt;a href="#"&gt;item one&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#"&gt;longer item two&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#"&gt;item 3&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#"&gt;another item&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#"&gt;5th item&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/body&gt;&#10;&lt;/html&gt;</pre>
<h3>
	&nbsp;</h3>
<h3>
	fallback for no-javascript</h3>
<p>
	What if the visitor doesn&#39;t have JavaScript turned on? Then they will get a bunch of links all smashed together with no spacing between them. I decided to deal with this by providing an arbitrary default margin-right for links in my style sheet. Then if there&#39;s no JavaScript, the links will still have a margin-right. The links won&#39;t line up with their container edges, but they will still be usable.</p>
<h3>
	am I making this too hard?</h3>
<p>
	After writing the script, I&#39;m still wondering if I&#39;m missing something obvious, and if there is a simple way to do this in CSS. Perhaps I simply mis-understood either the article on CSS-Tricks or the answers people gave me on StackOverflow. It seems a pretty serious omission in CSS if there&#39;s no way to do this.</p>
<p>
	If you know of a way to achieve equally-spaced navigation links like this in CSS, <em>please let me know! </em>I&#39;m willing to have egg on my face if there&#39;s an easier answer.</p>

			]]>
	  </description>
      <dc:subject>{channel_description}</dc:subject>
      <dc:date>2011-07-11T16:44:18+00:00</dc:date>
    </item>

    <item>
      <title>Mountain bike shopping part two &#45; secrets to great customer service</title>
      <link>http://www.highintegritydesign.com/blog/articles/mountain-bike-shopping-part-two-secrets-to-great-customer-service</link>
      <guid>http://www.highintegritydesign.com/blog/articles/mountain-bike-shopping-part-two-secrets-to-great-customer-service#When:19:15</guid>
      <description><![CDATA[
			With just a few simple techniques we can create great customer experiences. We just have to think about the customer throughout every interaction. Here's how.
			<h3>
	more adventures in mountain bike shopping</h3>
<div>
	As you know if you&#39;ve read <a href="http://www.highintegritydesign.com/blog/articles/mountain-bike-shopping-for-short-people-lessons-in-economics-and-design">my earlier article</a>, I&#39;ve been shopping for a new mountain bike. It&#39;s been a less-than-smooth experience, and it&#39;s got me thinking about what makes a great customer experience.</div>
<div>
	&nbsp;</div>
<div>
	I don&#39;t want to pick on the particular bike shop I&#39;ve been working with, because this story is so common in so many businesses. I just want to share how I feel as a customer, and how with just a few simple changes my whole experience could have been much better.&nbsp;</div>
<div>
	&nbsp;</div>
<div>
	Also I want to &#39;fess up that&nbsp;I&#39;ve made mistakes like these, so this post is as much a reminder to me as it is to anyone.&nbsp;<em>We can all use these tactics to improve our customer service, no matter what kind of business we are in!&nbsp;</em></div>
<meta charset="utf-8" />
<div>
	&nbsp;</div>
<h3>
	first impression - not so good</h3>
<div>
	I had such trouble finding a mountain bike that fits, that I contemplated buying a woman&#39;s model so I could get the standover height clearance I wanted. I called around and talked with a shop within reasonable driving distance, and low and behold they said they had a women&#39;s high-end Trek in a 14.5" size.</div>
<div>
	&nbsp;</div>
<div>
	<img alt="Trek 6700 WSD mountain bike" class="image-box caption image-box-left" src="http://www.highintegritydesign.com/uploads/trek-womens-bike.jpg" style="width: 300px; height: 196px; " />It&#39;s rare to find a bike like this in stock, so I lucked out! Or so I thought. I explained to the shop employee ("Joe"), that it was more than a one-hour drive to the shop so I confirmed with him that they had the bike on the floor. Then I drove to the shop eagerly anticipating my test ride.</div>
<div>
	&nbsp;</div>
<div>
	When I arrived Joe brought out the bike. I stood over it and hmmmm, I noticed there wasn&#39;t much standover height clearance at all. So I looked at the tag and saw it was actually a 16" bike! <em>No way was it going to fit.</em> I felt angry and frustrated-- I had specifically checked with Joe on the size before making the drive to the shop.</div>
<div>
	&nbsp;</div>
<div>
	Joe apologized but there wasn&#39;t much else to say. He hadn&#39;t gone to the trouble of actually checking the bike on the floor, to confirm it was the right size.&nbsp;</div>
<div>
	&nbsp;</div>
<div>
	<strong>Here are the takeaways I can think of from that experience:</strong></div>
<ul>
	<li>
		Details count! Be aware of details that may impact the customer, and check them if the cost of not checking them is high.</li>
	<li>
		First impressions matter!</li>
	<li>
		Every interaction forms the basis of the customer&#39;s opinion of you.</li>
	<li>
		Trust is hard to gain and easy to lose.</li>
</ul>
<h3>
	second impression - more broken promises</h3>
<div>
	<img alt="Santa Cruz Chamelion" class="image-box image-box-right caption" src="http://www.highintegritydesign.com/uploads/santa-cruz-chameleon-bike.jpg" style="width: 300px; height: 179px; " />Well, it turned out that the shop also sold the Santa Cruz Chameleon, which on paper should fit me pretty well. Joe offered to order one in for me to test ride without my putting down a deposit. Great news! So I asked him to Make It So.</div>
<div>
	&nbsp;</div>
<div>
	The next day Joe called and said he spoke with the manager and there would indeed be a deposit required. Again I felt frustrated. I wasn&#39;t upset that they needed a deposit-- I was frustrated that Joe had made me a promise and then broken it.</div>
<div>
	&nbsp;</div>
<div>
	So, I spoke with the manager about it, let&#39;s call him "Bob." Bob confirmed that yes, a deposit would be needed <em>but he didn&#39;t know how much! </em>He said he would have to check with the owner to find out. At this point, I am thinking, I can&#39;t believe the manager doesn&#39;t know how much deposit is required on a special order!&nbsp;</div>
<div>
	&nbsp;</div>
<div>
	My trust in the shop is now seriously eroded. I&#39;m wondering if I should even continue engaging with them. Frankly, the only reason I continued is they are the only shop within a reasonable distance who was willing to bring in that bike for me to test ride.</div>
<div>
	&nbsp;</div>
<div>
	Now, we are all new startups in the beginning-- so we can&#39;t be expected to have a complete set of policies. However this bike shop has been around for more than 25 years. Imagine how many other frustrated customers they must have had (or even lost) due to experiences like these.</div>
<div>
	&nbsp;</div>
<div>
	<strong>Here are the takeaways from my second experience with the shop:</strong></div>
<ul>
	<li>
		Make promises and set expectations carefully-- then make every effort to keep your promises!</li>
	<li>
		Know what you are promising and articulate it clearly.</li>
	<li>
		When you cannot deliver on a promise, think about ways you could make it up to the customer.</li>
	<li>
		Face your errors and apologize-- don&#39;t just gloss over your failure to deliver as if it&#39;s not important.</li>
	<li>
		If you don&#39;t have policies for common circumstances, create them.</li>
	<li>
		Know your polices and communicate them (and make sure all your employees know your policies).</li>
</ul>
<h3>
	third impression - still waiting</h3>
<div>
	<img alt="Question marks" class="right" src="http://www.highintegritydesign.com/uploads/question-marks.png" style="width: 217px; height: 118px; " />I went ahead and gave them my deposit. More than two weeks went by and no call from the shop. So, I called them to find out what was up. Joe wasn&#39;t available and no one else (including the manager) knew the status of the order.</div>
<div>
	&nbsp;</div>
<div>
	However this time Joe did a good job with follow-up, calling me back later that day to say that Santa Cruz did not have all the parts needed for a complete parts kit. He gave me an estimated ship date of two weeks later. Once again, I was disappointed but at least satisfied that the shop had followed up.</div>
<div>
	&nbsp;</div>
<div>
	<strong>Here are the takeaways from my third experience:</strong></div>
<ul>
	<li>
		Have a system in place so that everyone can look up the status of an order. This doesn&#39;t have to be in a computer; it can be on paper.</li>
	<li>
		Make everyone responsible for follow up on an issue if need be-- not just the person who initiated it.</li>
	<li>
		Keeping your customers informed is your responsibility, not theirs!</li>
	<li>
		If you let too much time go by on an open issue without contact, your customers will assume you don&#39;t give a Flying Kangaroo about them.</li>
	<li>
		Have a way to track when you should call customers.</li>
	<li>
		Don&#39;t be afraid to deliver bad news. The customer will appreciate knowing what&#39;s going on.</li>
</ul>
<h3>
	final thoughts - am I asking too much?</h3>
<div>
	As I ponder my experiences with Joe and Bob, the question arises-- am I asking too much? It&#39;s quite possible that my expectations for customer service are simply unrealistic. That I&#39;m just setting myself up for frustration and disappointment. I might be better off if I let go of these expectations and accept what is. And yet, saying this implies that it&#39;s a lot more work to provide great customer service-- <em>and I don&#39;t believe this is true.</em></div>
<div>
	&nbsp;</div>
<div>
	When I think about what is needed, it seems like just a few changes to approach can make a greatly improved customer experience. It probably does take a little more time and effort, but not very much. What do you think?</div>
<div>
	&nbsp;</div>

			]]>
	  </description>
      <dc:subject>{channel_description}</dc:subject>
      <dc:date>2011-04-29T19:15:35+00:00</dc:date>
    </item>

    <item>
      <title>The Caption&#45;ator &#45; image captions in HTML5 using figcaption and JQuery</title>
      <link>http://www.highintegritydesign.com/blog/articles/image-captions-in-html5-using-figcaption-and-jquery</link>
      <guid>http://www.highintegritydesign.com/blog/articles/image-captions-in-html5-using-figcaption-and-jquery#When:21:44</guid>
      <description><![CDATA[
			I wanted to automatically generate HTML5 image captions from an image element, using figure and figcaption. Here's how I did it.
			<h3>
	image captions in HTML5</h3>
<p>
	I wanted to create image captions for my blog using HTML5, so I was excited to find out that HTML5 provides the new <code>&lt;figure&gt;</code> and <code>&lt;figcaption&gt;</code> elements. The <a href="http://dev.w3.org/html5/spec/Overview.html">HTML5 spec</a> says that&#39;s exactly what these elements are intended for. After doing a <a href="http://html5doctor.com/the-figure-figcaption-elements/">bit of reading up</a> on how <code>&lt;figure&gt;</code> and <code>&lt;figcaption&gt;</code> work, here is an example of the code I wanted to use:</p>
<pre class="prettyprint">
&lt;figure&gt;&#10;    &lt;img src="http://www.highintegritydesign.com/uploads/kona-bike.jpg" alt="Kona Cinder Cone mountain bike" /&gt;&#10;    &lt;figcaption&gt;Kona Cinder Cone mountain bike&lt;/figcaption&gt;&#10;&lt;/figure&gt;&#10;</pre>
<p>
	And here is what it looks like:</p>
<p>
	<img alt="Kona Cinder Cone mountain bike" class="caption" src="http://www.highintegritydesign.com/uploads/kona-bike.jpg" style="width: 300px; height: 182px;" /></p>
<p>
	Looks simple enough, doesn&#39;t it? But, I soon found out that <em>making image captions work in the real world was harder than I thought</em>. Things get more tricky when you&#39;re using a <a href="http://plone.org/documentation/faq/what-is-a-cms">content management system</a> and you want to make it easy for clients to insert an image with a caption into their page. Read on to see what I learned and how I solved the problems that came up.</p>
<h3>
	the solution - a JQuery script</h3>
<p>
	I wanted clients to be able to easily upload an image into their page using a content management system, then mark the image as "having a caption" using a CSS class. I realized I needed to write a JQuery script which would grab the "marked" image and automatically generate the code for <code>&lt;figure&gt;</code> and <code>&lt;figcaption&gt;</code> around the original image. The script would use the image&#39;s ALT attribute to supply the caption text. For example, the image caption code above should be generated from the following <code>&lt;img&gt;</code> tag:</p>
<pre class="prettyprint">
&lt;img class="caption" src="http://www.highintegritydesign.com/uploads/kona-bike.jpg" alt="Kona Cinder Cone mountain bike" /&gt;&#10;</pre>
<p class="prettyprint">
	Most modern content management systems allow the user to specify a CSS class(es) when embedding an image into their page. I&#39;m using <a href="http://expressionengine.com/">ExpressionEngine</a> with the <a href="http://pixelandtonic.com/wygwam">WYGWAM</a> extension, which bundles in the popular <a href="http://en.wikipedia.org/wiki/WYSIWYG">WYSIWYG</a> <a href="http://ckeditor.com/">CKEditor</a>. Here is what CKEditor&#39;s dialog box looks like for embedding an image using a class:</p>
<p>
	<img alt="Setting the caption CSS class in CKEditor" class="caption" src="http://www.highintegritydesign.com/uploads/CKEditor-image-dialog.jpg" style="width: 370px; height: 283px;" /></p>
<h3>
	first attempt - code that works but doesn&#39;t validate</h3>
<p>
	I wrote the script and everything seemed to work OK. But, I always like to validate my code so I took the code in the modified <a href="http://en.wikipedia.org/wiki/Document_Object_Model">DOM</a> that my script created and ran it through the <a href="http://validator.w3.org/">W3C HTML validator</a>. <em>To my dismay, the code wasn&#39;t valid</em>. That&#39;s because CKEditor always embeds images inside of a paragraph tag.</p>
<p>
	The problem with this is wrapping the <code>&lt;img&gt;</code> with a <code>&lt;figure&gt;</code> creates a block level element. And, <em>it isn&#39;t valid HTML to nest a block-level element inside of a paragraph</em>. Does it really matter that the script-generated HTML code isn&#39;t valid? It&#39;s just in the DOM, so no one will ever see it. Frankly, as long as it renders correctly in modern browsers it probably doesn&#39;t need to be valid HTML. But, I took this as a challenge to learn how to better use JQuery.</p>
<h3>
	second attempt - valid, yummy HTML</h3>
<p>
	So I modified my script to construct a <code>&lt;figure&gt;</code> and <code>&lt;figcaption&gt;</code> around the <code>&lt;img&gt;</code>, then move the entire construct to be placed just before the paragraph it was formerly embedded in. Like this:</p>
<pre class="prettyprint">
&lt;figure&gt;&#10;    &lt;img src="http://www.highintegritydesign.com/uploads/kona-bike.jpg" alt="Kona Cinder Cone mountain bike" /&gt;&#10;    &lt;figcaption&gt;Kona Cinder Cone mountain bike&lt;/figcaption&gt;&#10;&lt;/figure&gt;&#10;&lt;p&gt;The image was originally contained inside this paragraph.&lt;/p&gt;&#10;&#10;</pre>
<p>
	This should always work with CKEditor (and other WYSIWYG editors) that embed images inside of paragraphs. At this point the script worked, and produced valid HTML! I was feeling pretty proud of myself, until I started using it on my site and realized I didn&#39;t account for images that are contained in links. Oops. So I modified my script yet again to generate slightly different code in the case of an image link.</p>
<h3>
	final code - introducing the "Image Caption-ator" script</h3>
<p>
	Here is my final code. This code works with either images or images inside of links. I call it the "Image Caption-ator." To use the code, <a href="https://github.com/northk/captionate">see the example HTML in my GitHub repository</a>. Use it and let me know how it works for you! If you find any bugs or think of any useful enhancements, please let me know in the comments. Otherwise, enjoy! I have some additional notes about how the script works, below.</p>
<p>
	<strong>NOTE: I updated this code on 7/15/2011 so please check my <a href="https://github.com/northk/captionate">respository on GitHub</a> for the latest version. Also I licensed the code with an MIT license so you can use it for commercial purposes. The script was updated for efficiency, as well as becoming a JQuery plug-in.</strong></p>
<pre class="prettyprint">
// This software is licensed under the MIT License, opensource.org/licenses/mit-license.php&#10;// Copyright (c) 2011 High Integrity Design, LLC.&nbsp;&nbsp; highintegritydesign.com&#10;//&#10;(function($) {&#10;  $.fn.captionate = function() {&#10;&nbsp; return this.each(function() {&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var&nbsp;&nbsp; $this = $(this), // save a reference to the current img.caption element&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; altText = $this.attr(&#39;alt&#39;), // grab the value of the image ALT attribute&nbsp;&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; imgWidth = $this.width(), // grab the width of the image&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; classList = $this.attr(&#39;class&#39;); // save any classes attached to the &lt;img&gt;&#10;&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this.removeAttr(&#39;class&#39;); // remove any classes from the original &lt;img&gt; element&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // check and see if the image is contained in an immediate parent anchor link.&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // if it is, construct a &lt;figure&gt; wrapping the anchor link instead of wrapping the &lt;img&gt;&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // add the &lt;figcaption&gt; after the link, using the ALT element&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // set the &lt;figure&gt; width to be the same as the &lt;img&gt;&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // add back in any classes from the original &lt;img&gt; to the new &lt;figure&gt;&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // finally move the new &lt;figure&gt; to be just before the paragraph it was contained in.&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var $parentAnchorLink = $this.parent();&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($parentAnchorLink.is(&#39;a&#39;)) {&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $newFigure = $parentAnchorLink.wrap(&#39;&lt;figure&gt;&lt;/figure&gt;&#39;).parent();&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $parentAnchorLink.after(&#39;&lt;figcaption&gt;&#39; + altText + &#39;&lt;/figcaption&gt;&#39;);&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $newFigure.width(imgWidth);&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $newFigure.addClass(classList);&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $newFigure.parent(&#39;p&#39;).before($newFigure);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // or else it&#39;s just an image tag, not wrapped with an anchor link.&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // so do all the same as above except wrap the &lt;img&gt; instead of an anchor link&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $newFigure = $this.wrap(&#39;&lt;figure&gt;&lt;/figure&gt;&#39;).parent();&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this.after(&#39;&lt;figcaption&gt;&#39; + altText + &#39;&lt;/figcaption&gt;&#39;);&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $newFigure.width(imgWidth);&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $newFigure.addClass(classList);&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $newFigure.parent(&#39;p&#39;).before($newFigure);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&#10;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });&#10;&nbsp;&nbsp;&nbsp; };&#10;})(jQuery);&#10;</pre>
<p class="prettyprint">
	And here is the CSS I used:</p>
<pre class="prettyprint">
figcaption {&#10;    display: block;&#10;    text-align: center;&#10;    font-size: 0.8em;&#10;    font-style: italic;&#10;    font-weight: bold;&#10;    padding: 5px 0 0 0;&#10;}&#10;&#10;</pre>
<h3>
	notes on the script</h3>
<p>
	What if the width of the caption is greater than the image? In this case the caption would look kind of funny since it would extend past the end of the image. So, I set the width of the caption to be the same as the image width. This will make the caption text wrap lines if it is too long. The script also takes any CSS classes that are assigned to the <code>&lt;img&gt;</code> and re-assigns them to the resulting <code>&lt;figure&gt;</code>. That way, if you have a class which gives the image a border or floats it left the resulting <code>&lt;figure&gt;</code> will preserve that styling.</p>
<p>
	I also learned something valuable about JQuery. When you give JQuery a reference to an HTML element and tell it to place that element somewhere else using <code>add()</code>, <code>before()</code>, <code>after()</code> etc, <em>it will move the element rather than creating a new copy</em>. That was exactly what I wanted for this script, but it may not be what you want in all situations. To make a <a href="http://en.wikipedia.org/wiki/Deep_copy#Deep_copy">deep copy</a> you need to use the JQuery <code>clone()</code> method. See <a href="http://www.elated.com/articles/jquery-removing-replacing-moving-elements/">http://www.elated.com/articles/jquery-removing-replacing-moving-elements/</a> for more info.</p>
<p>
	Is there any way this script could break? <del>If the image isn&#39;t contained inside a paragraph, it could break</del> (I later tested this and images outside of paragraphs seemed to work ok). But we already established that&#39;s the way CKEditor does it, so it should be safe with any WYSIWYG editor that sticks images inside of paragraphs. Is there any other way it could break? If you think of something, let me know!</p>
<p>
	I also want to publicly thank <a href="http://stackoverflow.com/questions/5438600/using-each-to-iterate-over-selections-for-html5-figure-and-figcaption">T.J Crowder over at StackOverflow</a>, for helping me modify my script so it&#39;s more efficient. <a href="http://stackoverflow.com/">StackOverflow</a> is a fantastic resource with extremely knowledgeable, helpful people. If you have a tough question about anything programming related, there is probably someone at StackOverflow who is willing to help.</p>
<h3>
	No styling in IE8</h3>
<p>
	Finally, I noticed that for some reason the <code>&lt;figcaption&gt;</code> element wasn&#39;t accepting CSS styling in IE8.&nbsp; So you just get regular looking text no matter how you style it. Looking into this further I discovered that HTML5 elements cannot be styled in IE8 when they are dynamically generated in the DOM by JQuery. This is true even when using the <a href="http://html5shiv.googlecode.com/svn/trunk/html5.js">HTML Shiv</a> script, which adds support for HTML5 elements to IE.&nbsp; There is a solution called the <a href="http://jdbartlett.github.com/innershiv/">innerShiv script</a>. I played with that script a little and it worked well for simple test cases. But it turned out to be difficult to make it work with my script and it wasn&#39;t worth the time. So, I decided to simply let image captions remain unstyled for IE8.</p>
<p>
	That&#39;s it, let me know how it works for you!</p>

			]]>
	  </description>
      <dc:subject>{channel_description}</dc:subject>
      <dc:date>2011-03-31T21:44:05+00:00</dc:date>
    </item>

    <item>
      <title>Mountain bike shopping for short people &#45; lessons in economics and design</title>
      <link>http://www.highintegritydesign.com/blog/articles/mountain-bike-shopping-for-short-people-lessons-in-economics-and-design</link>
      <guid>http://www.highintegritydesign.com/blog/articles/mountain-bike-shopping-for-short-people-lessons-in-economics-and-design#When:16:09</guid>
      <description><![CDATA[
			I've been shopping for a mountain bike recently. I'm short, and it was hard to find a bike that fits. The experience really made me think about economics and design, and how that relates to web design.
			<h3>
	shopping for a new mountain bike</h3>
<p>
	This year my goal is to celebrate life, celebrate good health, and get in lots of miles on my bike. Some changes I made include commuting to work by bicycle like I used to, meditating every day, and reducing my work schedule to 32 hrs/week. Oh, and I need to buy a new mountain bike. Well, I don&#39;t actually "<em>need</em>" a new mountain bike. I have a perfectly serviceable, good handling, 14 year old mountain bike that fits me well. But, I <em>wanted </em>a new one with disc brakes and a modern suspension design.&nbsp;</p>
<p>
	I thought it would be pretty straightforward to find a new bike that was right for me, but it turned out to be a lot harder than I thought. As I got into it, I realized there are some great lessons in web design, economics and bike shopping here-- so I wanted to share my thoughts with you. I hope you&#39;ll share your thoughts with me in the comments too.</p>
<h3>
	lesson #1 - what&#39;s popular may not be what&#39;s best for you</h3>
<p>
	My budget was $1500, which sounds like a lot for a bike. But, most of the bikes in local shops were either expensive <a href="http://en.wikipedia.org/wiki/Bicycle_suspension">full suspension</a> rigs, or inexpensive entry-level <a href="http://en.wikipedia.org/wiki/Bicycle_suspension">hard tails</a> with lower grade components and heavy frames. There were hardly any bikes in the price range I was looking for.</p>
<p>
	<img alt="Kona Cinder Cone mountain bike" class="image-box image-box-right caption" src="http://www.highintegritydesign.com/uploads/kona-bike.jpg" style="width: 300px; height: 182px;" />It seems that most enthusiast riders these days want full suspension. However, I decided to go with a hardtail. Why? In my younger racing days, I rode a 19 lb road bike and I knew I wouldn&#39;t be satisfied with the weight, braking and shifting of an inexpensive, entry level mountain bike. So that meant either spending $3,000-$4,000 on a quality full suspension bike, or finding a good hardtail that was within my budget. Easy decision! A hardtail represents the best combination of light weight, high performance components, and affordability <em>for me and for the type of riding I do</em>.</p>
<p>
	The lesson I noticed is, <em>sometimes the popular and easily available solutions do not meet my needs</em>. That&#39;s why, as a web designer I think it&#39;s so important to have in-depth conversations with customers about their needs before choosing technologies and solutions. And, just because a technology is popular is not reason enough to choose it. As a client, what this means is, <em>it pays to get clear up front on what your needs are now and in the future</em>. A good web designer will use specific questions and discussions to help you develop that clarity.</p>
<h3>
	lesson #2 - newer is not necessarily better</h3>
<p>
	Most of the new mountain bikes have 29" wheels compared to the older standard of 26". I&#39;d never ridden a <a href="http://en.wikipedia.org/wiki/29er_%28bicycle%29">29er</a> so I decided to try them out. I test rode a couple of them on different days, comparing them back-to-back with my old 26" mountain bike...and I have to say I was unimpressed. The larger wheels felt too big and ponderous to me, and not as maneuverable at slow <a href="http://en.wikipedia.org/wiki/Singletrack">singletrack </a>speeds. What did work well are the disc brakes-- far superior to the <a href="http://en.wikipedia.org/wiki/Cantilever_brake#Rim_brakes">V-brakes</a> on my old bike. Perhaps I could have gotten used to a 29er, but I believe a good bike should feel like an extension of your body. There are plenty of people who love 29ers, and that&#39;s OK. But what works well for them apparently doesn&#39;t work well for me.</p>
<p>
	The lesson here was, be open-minded about newer solutions you may not have tried-- but <em>just because it&#39;s a newer idea doesn&#39;t mean it is better for you</em>. I&#39;ll stick with a 26" wheeled bike, thank you. How I apply this to web design: I stay on top of new developments in web design and I constantly try out new ideas and technologies. But,<em> I pick out the stuff that I think works well rather than everything that is cool and new</em>.</p>
<h3>
	lesson #3 - companies sell what is profitable (or, sometimes it sucks to be real short or real tall)</h3>
<p>
	Well, it seems that most bike companies build frames that fit people in the mid-range of height. And it turns out that at 5&#39;5" tall, I&#39;m <a href="http://www.cdc.gov/nchs/data/nhsr/nhsr010.pdf">among the shortest 10% of adult males in the U.S.</a> The bike companies probably just don&#39;t sell enough frames for tall or short people to justify the expense of design, tooling, extra production runs and testing to make sure everything works together.</p>
<p>
	<img alt="Bicycle geometry diagram" class="image-box image-box-left caption" src="http://www.highintegritydesign.com/uploads/bike-geometry.jpg" style="width: 350px; height: 209px;" />Bah! I wanted a bike that has 2-3" of clearance between my crotch and the top tube-- otherwise known as "standover height" clearance. If you&#39;re a guy and you&#39;ve ever done an "unplanned emergency dismount" on a mountain bike, you know why you want this clearance! And if you ride a mountain bike at the limits of your abilities, you will at some point have to do such a dismount. Some people debate how important this is, but to me it seems pretty important.</p>
<p>
	At my height, that means on a modern mountain bike frame I need about a 14"-14.5" size. Cool. Only, hardly anyone makes a production frame in that size! Trek and Specialized make a 15.5" or 16", which is just too big (I test rode a couple just to make sure-- not enough clearance). Marin and a few others make a 13", but that&#39;s too small. Kona makes one in the right size but not with good quality components.</p>
<p>
	Making things more complicated is that the <a href="http://en.wikipedia.org/wiki/Top_tube#Top_tube">top tube</a> length is proportionately sized to the frame. The top tube length has to be real close to spot-on, or else you will feel scrunched up or too stretched out. Some people think top tube length is even more important than standover height.</p>
<p>
	<img alt="Trek 6700 Women's Specific Design mountain bike" class="image-box image-box-right caption" src="http://www.highintegritydesign.com/uploads/trek-womens-bike.jpg" style="width: 300px; height: 196px;" />So what about riding a women&#39;s mountain bike? Some manufacturers, to their credit, make higher-end women&#39;s hardtail bikes in a 14"-14.5" size. The frames are proportionately sized to fit womens&#39; bodies, which are generally shorter. Unfortunately they also have very short top tubes, which would make me way too scrunched up on the bike. I have shorter legs and a longer upper body. So no dice again.</p>
<h3>
	precise fit equals a good user experience</h3>
<p>
	Why am I so hung up on frame size? Because I know from experience that having a precise and proper fit makes all the difference in better handling, better confidence, and in general a better experience. I can&#39;t blame the bike manufacturers-- they want to maximize their profits in a highly competitive industry.</p>
<p>
	The adult male population who needs a smaller bike has got to be a pretty big number, but it&#39;s just not enough for the bike manufacturers to build smaller frames. For them, it&#39;s simple economics. But for me, I am left without a good solution.</p>
<p>
	How does this relate to web design? I think it is a reminder of <em>how important it is to know our audience and how they want to use our site</em>. If we make cost or feature decisions that leave people out (for example requiring Javascript to work, or not supporting IE6)-- make it a conscious decision.</p>
<p>
	Do your research on how many people will be impacted and if they are likely to be users of your site. Be aware that you may lose some customers. I believe this is where the up-front work of developing <a href="http://thinkvitamin.com/design/how-to-understand-your-users-with-personas/">personas </a>and a <a href="http://en.wikipedia.org/wiki/Target_audience">target audience</a> description can keep your design on track. And, testing your site with real users can quickly reveal if you made mistakes in your assumptions.</p>
<h3>
	so what about the bike?</h3>
<p>
	<img alt="Santa Cruz Bicycles Chameleon mountain bike" class="image-box image-box-left caption" src="http://www.highintegritydesign.com/uploads/santa-cruz-chameleon-bike.jpg" style="width: 300px; height: 179px;" />So what bike did I end up with? Well, I&#39;m still looking. The ideal solution would have been to order a custom-built bike. I&#39;ve ridden custom bikes and they are truly awesome.</p>
<p>
	There are some <a href="http://iglebike.com/">fantastic bike builders</a> in the U.S. that produce functional bicycle art that is a joy to behold and to ride. Unfortunately, they don&#39;t meet my budget goals right now. So, I kept looking and found that <a href="http://www.santacruzbicycles.com/">Santa Cruz Bicycles</a> makes a 14.5" hardtail bike (the <a href="http://www.santacruzbicycles.com/chameleon/">Chameleon</a>) with a standover height of 28.2" and a top tube length of 21.5". On paper, that should be just about a perfect fit for me. I&#39;m currently trying to find a dealer who is willing to bring one in for me, and I&#39;ll keep you posted.</p>
<p>
	I think the lesson here is, <em>if you don&#39;t find the solution you need, keep looking!</em> I think this is true for both web designers and clients. As a designer, don&#39;t give up if you don&#39;t find the technical or creative solutions you need to create a fantastic result. The solution is probably out there.</p>
<p>
	If you are a client, be patient about finding the right web designer to work with, and be honest with your designer if your relationship isn&#39;t working for you. Sometimes just being honest with each other can cause a breakthrough.</p>
<p>
	Do you have a similar shopping story to tell, where you felt left out? Let me know in the comments section below!</p>

			]]>
	  </description>
      <dc:subject>{channel_description}</dc:subject>
      <dc:date>2011-03-20T16:09:40+00:00</dc:date>
    </item>

    <item>
      <title>Building a modern website part two &#45; how I used HTML5</title>
      <link>http://www.highintegritydesign.com/blog/articles/building-a-modern-website-part-two-how-i-used-html5</link>
      <guid>http://www.highintegritydesign.com/blog/articles/building-a-modern-website-part-two-how-i-used-html5#When:15:15</guid>
      <description><![CDATA[
			There are a ton of new features in HTML5. I chose just a few in building this site. Here are the features I used and why.
			<h3>
	the HTML5 spec is huge</h3>
<p>
	If you read my <a href="http://www.highintegritydesign.com/blog/articles/building-a-modern-website-part-one-should-you-use-html5">earlier post about HTML5</a>, you know why I chose to use it for this site. In this post, I&#39;ll talk about which specific HTML5 features I used and how I used them.</p>
<div>
	First, I want to mention&nbsp;<em>there is a ton of stuff I&#39;m not using</em>. The HTML5 spec is huge, offering a dizzying array of new functionality, most of which I won&#39;t talk about in this post. It covers everything from <a href="http://diveintohtml5.org/storage.html">local storage</a>, to web applications that continue to work <a href="http://diveintohtml5.org/offline.html">while offline</a>.&nbsp;A lot of it I just didn&#39;t need for this site, I haven&#39;t had time to look into, or it isn&#39;t well supported in browsers yet. If you&#39;re wondering what your browser supports, here is a <a href="http://findmebyip.com">great discovery tool</a> for finding out. And there&#39;s another helpful site with a&nbsp;<a href="http://caniuse.com/">comprehensive list of what&#39;s supported in all browsers</a>.</div>
<div>
	&nbsp;</div>
<h3>
	new structural page elements</h3>
<div>
	<div>
		I decided it was "safe" to use the new HTML5 structural page elements. Safe because these will work in all browsers if you use the <a href="http://remysharp.com/2009/01/07/html5-enabling-script/">HTML5 Shiv</a> script I talked about in my earlier post. My thought was I can use them now, see how they feel, and then refine my understanding and use of them over time. In technical terms, we call this "getting your feet wet." Or, in relationship terms, "dating before you get married." Here are the elements I used:</div>
	<div>
		&nbsp;</div>
</div>
<div>
	<div>
		<div>
			<strong><code>&lt;header&gt;</code>&nbsp;</strong>: This is for what you&#39;ve been doing for years--&nbsp;<code>&lt;div id="header"&gt;</code>. Only now it&#39;s more semantic. The spec says it is intended to contain a "group of introductory or navigational aids", including heading elements like <code>&lt;h1&gt;</code> and <code>&lt;h2&gt;</code>. I use it to contain my main navigation links and logo. Note that a&nbsp;<code>&lt;header&gt;</code>&nbsp;does not have to be at the top of the document. A common theme with the new elements is,&nbsp;<em>they don&#39;t imply a specific position in the document</em>. In HTML5 you can have multiple <code>&lt;header&gt;</code> elements. Huh? More on this later.</div>
		<div>
			&nbsp;</div>
		<div>
			<strong><code>&lt;section&gt;</code></strong> : This&nbsp;is a grouping of related content. How is it different from a <code>&lt;div&gt;</code>?&nbsp;It&#39;s different because a <code>&lt;div&gt;</code> <em>doesn&#39;t necessarily have to group related content</em>. &nbsp;A <code>&lt;div&gt;</code> is just a generic container, usually used for styling purposes. The spec says "A Web site&#39;s home page could be split into sections for an introduction, news items, and contact information." So, I used <code>&lt;div&gt;</code> where I just needed to style some content, and I used <code>&lt;section&gt;</code> where it seemed like the content really was a related chunk that should be grouped together.</div>
		<div>
			&nbsp;</div>
	</div>
	<h3>
		autonomous document trees</h3>
	<div>
		I made up the term "autonomous document tree", mostly because I think it sounds cool. But, also because I think it describes a neat feature of HTML5. Notice that a <code>&lt;section&gt;</code> can have headings associated with it (and the spec says it typically will, but you don&#39;t have to). Here&#39;s the interesting part: each <code>&lt;section&gt;</code> can have it&#39;s own self-contained "heading tree", including a <code>&lt;header&gt;</code> and <code>&lt;h1&gt;</code> thru <code>&lt;h6&gt;</code>. Previously it was discouraged to use more than one <code>&lt;h1&gt;</code> in a page. The new method makes content more self-contained, modular and portable since the headings in each section don&#39;t depend on which headings were used in other sections. &nbsp;So, you can do things like this:</div>
	<div>
		&nbsp;</div>
	<pre class="prettyprint">
&lt;section&gt;&#10;  &lt;header&gt;&#10;    &lt;h1&gt;My First Header&lt;/h1&gt;&#10;    &lt;h2&gt;My Subtitle for First Header&lt;/h2&gt;&#10;  &lt;/header&gt;&#10;&lt;/section&gt;&#10;&lt;section&gt;&#10;  &lt;header&gt;&#10;    &lt;h1&gt;My Second Header&lt;/h1&gt;&#10;    &lt;h2&gt;My Subtitle for Second Header&lt;/h2&gt;&#10;  &lt;/header&gt;&#10;&lt;/section&gt;&#10;</pre>
	<div>
		You could lift out each of the above sections and <em>it would be a complete, portable document sub-tree by itself</em> with its own hierarchy of headings. Why is this good? Ultimately, I think it is good because improved portability makes information easier to share on the web, and easier for people to consume.</div>
	<div>
		&nbsp;</div>
	<div>
		Is this good practice to use right now? I&#39;m not sure, but I think this will make more sense over time as more data is shared between sites (as in RSS, Facebook etc.). I chose not to structure my code like this yet, because it&#39;s unclear to me how Google will react to lots of heading elements on a page. Most of the stuff I&#39;ve read says it won&#39;t hurt, but it won&#39;t help either. Also, the popular site <a href="http://html5doctor.com">HTML5 Doctor</a> site says that using too many <code>&lt;h1&gt;</code> elements can <a href="http://html5doctor.com/the-header-element/">cause accessibility issues</a>. I think I&#39;ll check out this idea again after I&#39;ve had some time to cogitate on it more. By the way, if you want to see what the "semantic outline" of your code looks like, <a href="http://gsnedders.html5.org/outliner/">here&#39;s a great tool</a>. The tool will give you an outline view showing the information hierarchy of your page as an HTML5 parser understands it.</div>
	<div>
		&nbsp;</div>
	<h3>
		more new HTML5 elements</h3>
	<div>
		<strong><code>&lt;nav&gt;</code></strong> : This is pretty straightforward-- it should contain navigation links (only major links, not every single link). I used one <code>&lt;nav&gt;</code> element in the page header, and another one in the page footer.</div>
</div>
<div>
	<div>
		&nbsp;</div>
	<div>
		<strong><code>&lt;aside&gt;</code></strong> : This does not necessarily mean sidebar-- it could be a sidebar, but it doesn&#39;t have to be. For example, you could use it to wrap your twitter message feed on your site. Hmm, after reading that in the spec, I should probably change my code so it does that! OK, did that and I&#39;m back. The spec essentially says <code>&lt;aside&gt;</code> should contain information that is related to the main content, but you could take it out and the rest of the page would still make sense without it. Again, the <code>&lt;aside&gt;</code> element is not supposed to describe where it occurs in the page layout. I used <code>&lt;aside&gt;</code> for pull-quotes in my blog articles.</div>
	<div>
		&nbsp;</div>
	<div>
		<strong><code>&lt;article&gt;</code></strong> : The spec says this is a self-contained composition that is independently distributable or reusable. It&#39;s intended for stuff like blog articles that you want to syndicate in an RSS feed, and that&#39;s exactly what I used it for. Note that an <code>&lt;article&gt;</code> can have an "autonomous document tree" just like I described for <code>&lt;section&gt;</code> above. In the context of an article that is meant to be shared with other sites, using a self-contained autonomous structure makes even more sense than it does for <code>&lt;section&gt;</code>.</div>
	<div>
		&nbsp;</div>
	<div>
		<strong><code>&lt;footer&gt;</code></strong> : This is a better alternative to <code>&lt;div id="footer"&gt;</code> with more semantic meaning. The twist is that you can have multiple <code>&lt;footer&gt;</code> elements in a document, just like you can have multiple <code>&lt;header&gt;</code> elements. And, a <code>&lt;footer&gt;</code> does not necessarily have to go at the bottom of the page. Again, the element is defined by its content, not its location. According to the spec, a <code>&lt;footer&gt;</code> should contain information about its containing element-- such as copyright information, who wrote it, related content etc. This kind of information could show up on a sidebar, for example-- so it could make sense to use <code>&lt;footer&gt;</code> in your sidebar. I used it for copyright, navigation links, and a short "about me" section in the traditional footer area at the bottom of my document.</div>
	<div>
		&nbsp;</div>
	<h3>
		the placeholder attribute</h3>
</div>
<div>
	<p>
		I really like this one. The placeholder attribute is used with other page elements, and provides a short hint (a word or a short phrase) intended to aid the user with data entry. I used it in the <code>&lt;textarea&gt;</code> inside of my contact form. The hint text appears in the input field until the user enters that input field. Then, the hint will disappear and the user can enter text. If the user leaves the input field without entering anything, the hint text will re-appear. I think this is a clear example of helping the user know what to do when they see an input field, and makes the site easier to use. Here is what it looks like:</p>
	<pre class="prettyprint">
<span class="webkit-html-tag">&lt;textarea <span class="webkit-html-attribute-name">placeholder</span>="<span class="webkit-html-attribute-value">Don&amp;rsquo;t forget your name and email!</span>" <span class="webkit-html-attribute-name">cols</span>="<span class="webkit-html-attribute-value">20</span>" <span class="webkit-html-attribute-name">rows</span>="<span class="webkit-html-attribute-value">10</span>"&gt;&lt;/textarea&gt;</span>&#10;</pre>
	<p>
		And here is what it looks like:</p>
	<p>
		<img alt="Placeholder attribute" height="60" src="http://www.highintegritydesign.com/uploads/placeholder.jpg" width="219" /></p>
	<p>
		What happens if the user&#39;s browser is older and doesn&#39;t understand the placeholder attribute? Good news-- nothing happens at all. The placeholder hint simply doesn&#39;t show up, which isn&#39;t so bad. However, I like this feature so much that I wanted it to work in older browsers too. And it turns out I can just <a href="https://github.com/mathiasbynens/Placeholder-jQuery-Plugin">drop in a JQuery script</a> and it will magically implement placeholder for older browsers that don&#39;t support the new attribute. For newer browsers, the script will detect that placeholder is natively supported, and will simply let the browser handle it. This is a good example of the many great, open-source scripts people have written to help us move to HTML5!</p>
</div>
<h3>
	that&#39;s all folks</h3>
<p>
	So, there you have it. That&#39;s all of the new HTML5 goodies that I used. A pretty small chunk of what&#39;s in HTML5 actually. You can see it doesn&#39;t take much to get your feet wet-- you can make your code more semantically meaningful and easier for your site visitors to use without much effort. I learned a lot about HTML5 just using some of the new structural elements. I&#39;m really curious about how other people are using HTML5, so I hope you&#39;ll let me know in the comments below. Thanks for reading!</p>

			]]>
	  </description>
      <dc:subject>{channel_description}</dc:subject>
      <dc:date>2011-03-12T15:15:42+00:00</dc:date>
    </item>

    <item>
      <title>Building a modern website part one &#45; should you use HTML5?</title>
      <link>http://www.highintegritydesign.com/blog/articles/building-a-modern-website-part-one-should-you-use-html5</link>
      <guid>http://www.highintegritydesign.com/blog/articles/building-a-modern-website-part-one-should-you-use-html5#When:16:25</guid>
      <description><![CDATA[
			I built this website using HTML5 and CSS3. Many of the new HTML5 features work in browsers right now. Here's what I learned about HTML5 and why I chose to use it.
			<h3>
	what&#39;s up with HTML5?</h3>
<p>
	You&rsquo;ve probably read a lot of hype about using HTML5 and CSS3. I know I have! I kept on seeing articles pop up all over the place. At first, I thought, why bother? It will be years before HTML5 and CSS3 are implemented by most browsers, and I can do nearly everything I want today using XHTML and JQuery. There is a <a href="http://www.techrepublic.com/blog/programming-and-development/html-5-editor-ian-hickson-discusses-features-pain-points-adoption-rate-and-more/718">widely repeated quote with Ian Hickson</a>, where he mentions that <em>HTML5 is expected to become a &ldquo;proposed recommendation&rdquo; in the year 2022!</em>&nbsp;Are you kidding me?</p>
<p>
	But, the articles kept popping up and wouldn&rsquo;t leave me alone. So I started looking into HTML5 in more detail. I found out some interesting things:</p>
<ul>
	<li>
		The &ldquo;real&rdquo; date we should care about is 2012 - That&rsquo;s when the specification is due to become a<em> &ldquo;candidate recommendation&rdquo;, meaning discussions and changes are done.</em> The 2022 date is the estimated date when two complete browser implementations of HTML5 are done, which didn&#39;t happen for HTML4 for a long time (is it even true now?).</li>
	<li>
		HTML5 is a collection of features, which are being worked on at different rates by the different browser manufacturers. <em>Many useful features work right now in modern browsers.</em></li>
	<li>
		You can often use Javascript to provide a &ldquo;fallback&rdquo; if the visitor is using a browser that doesn&rsquo;t support the new HTML5 features you are using.&nbsp; Several awesome people have written good, open source JQuery scripts that make it easy&mdash;all you have to do is drop them in.</li>
</ul>
<p>
	So, after looking into it, I decided to rebuild my site using HTML5. This post contains some goodies and resources I learned about that will help you get started with HTML5. If you&#39;re using HTML5, I hope you will describe your experiences in the comments so I can learn something too.</p>
<h3>
	can we and should we use HTML5 today?</h3>
<p>
	Well, my opinion is, &ldquo;it depends!&rdquo; As much as I like shiny new stuff, I honestly don&rsquo;t think there is a lot of practical value you can deliver today using HTML5 that you couldn&rsquo;t deliver in HTML4 or XHTML <em>if your site needs to work on older browsers</em>. But, if you know your audience will be using newer browsers, there is definitely a lot more you can do with HTML5.</p>
<p>
	My focus is on building modern websites so I&rsquo;m choosing to use HTML5. The point is that you need to know who your audience is, and decide based on that. However, there are still some good reasons to start using HTML5 today even if your users are on older browsers:</p>
<ul>
	<li>
		New page elements like <code>&lt;section&gt;</code>, <code>&lt;header&gt;</code>, <code>&lt;article&gt;</code>, <code>&lt;aside&gt;</code>, and <code>&lt;footer&gt;</code> are ready to use right now. This leads to better semantic richness. According to articles I&rsquo;ve read, Google doesn&rsquo;t actually care (yet) but my opinion is they will likely care in the future. And, I suspect screen readers will benefit from the new elements.</li>
	<li>
		It gives you more semantic &ldquo;hooks&rdquo; to use in your styling (CSS). For example, you can style <code>&lt;article&gt;</code>&nbsp;differently than <code>&lt;div&gt;</code>.&nbsp;Using the new elements makes it&nbsp;easier to read and understand both your HTML and CSS files.</li>
	<li>
		The new elements already work in every modern browser except IE. And older versions of&nbsp;IE have <a href="http://remysharp.com/2009/01/07/html5-enabling-script/">easy&nbsp;fixes available through Javascript</a>. Further, <a href="http://msdn.microsoft.com/en-us/ie/ff468705.aspx">IE9 will support HTML5</a>.</li>
</ul>
<p>
	There is a <a href="http://www.smashingmagazine.com/2010/12/10/why-we-should-start-using-css3-and-html5-today/">great article on Smashing Magazine</a> with further reasons to use HTML5 today.</p>
<h3>
	changes in syntax, and some good reading</h3>
<div>
	In HTML5, you can use syntax from XHTML, HTML4 or a mixture of both-- meaning things like you can use upper or lower case, and you can choose to close tags or not.&nbsp;There are <a href="http://www.w3.org/TR/2008/WD-html5-diff-20080122/">several other small changes worth reviewing</a> if you&#39;re going to start working with HTML5. I&#39;ll keep using XHTML syntax which just "feels" cleaner to me.</div>
<div>
	&nbsp;</div>
<div>
	By the way, I don&#39;t usually spend time reading web specifications-- I prefer a good book that distills the spec down to something I can understand. However, I found the <a href="http://dev.w3.org/html5/spec/Overview.html">HTML5 spec</a> surprisingly readable, with lots of good code samples. Snap my suspenders! It&#39;s worth checking out as a reference when you have a question about how a new element works.</div>
<div>
	&nbsp;</div>
<div>
	Besides the spec, I highly recommend reading the free online book&nbsp;<a href="http://diveintohtml5.org/">Dive Into HTML5</a>&nbsp;by Mark Pilgrim, which covers a lot of the new functionality in a great, funny, easy-to-read format. Finally, I recommend <a href="http://books.alistapart.com/products/html5-for-web-designers">HTML5 for Web Designers</a> by Jeremy Keith. His book a short, to-the-point introduction to HTML5 which is also easy to read.</div>
<div>
	&nbsp;</div>
<h3>
	a simple, valid HTML5 document</h3>
<p>
	A minimal HTML5 document for you to play with is below-- this is absolutely minimal; I do more than this in my production code.&nbsp;</p>
<div>
	You might also want to check out the <a href="http://html5boilerplate.com/">HTML5 boilerplate</a>. I don&#39;t use the boilerplate in it&#39;s entirety, but I do use some bits and pieces of it in my code. There are a ton of great tricks in there that will help you write more robust, maintainable HTML5 documents. Specifically I use IE conditional comments to <a href="http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/">discover which version of IE</a> the site visitor is using,&nbsp;and then set CSS styles based on that so I can deal with IE bugs.&nbsp;</div>
<div>
	&nbsp;</div>
<div>
	The most important thing to note is that I use the "HTML5 shiv" script by&nbsp;<a href="http://remysharp.com/2009/01/07/html5-enabling-script/">Remy Sharp</a>. In a nutshell, what this does is get IE 6, 7, and 8 to understand the new page elements. Without this script, IE will blow chunks and will render the new elements in a way that will surely break your site. Thanks, Remy!</div>
<div>
	&nbsp;</div>
<p>
	Of course, this means visitors must have Javascript enabled for your site to work in older versions of IE. To me, this is no big deal since I focus on modern websites and <a href="http://developer.yahoo.com/blogs/ydn/posts/2010/10/how-many-users-have-javascript-disabled/">nearly everyone has Javascript turned on</a>. But, it may be a deal-breaker for you depending on who your visitors are. By the way, you can validate your HTML5 code using the same familiar&nbsp;<a href="http://validator.w3.org/">W3C validator</a> that you&#39;ve always used-- it will recognize the HTML5 doctype and validate accordingly. You do validate your code, right? OK, here&#39;s the code:</p>
<div>
	<pre class="prettyprint">
&lt;!doctype html&gt;&#10;&lt;html lang=en&gt;&#10;&lt;head&gt;&#10;    &lt;meta charset=utf-8&gt;&#10;    &lt;!--[if lt IE 9]&gt;&#10;    &lt;script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"&gt;&lt;/script&gt;&#10;    &lt;![endif]--&gt;&#10;    &lt;title&gt;blah&lt;/title&gt;&#10;&lt;/head&gt;&#10;&lt;body&gt;&#10;    &lt;p&gt;I&#39;m the content&lt;/p&gt;&#10;&lt;/body&gt;&#10;&lt;/html&gt;&#10;</pre>
	<p>
		I like the simple <code>&lt;doctype&gt;</code> and <code>&lt;head&gt;</code> elements. You&#39;ll notice there&#39;s no version number in the doctype, and <a href="http://html5doctor.com/html5-living-standard/">here&#39;s why</a>. For a more in-depth, excellent discussion of what makes a basic HTML5 document, <a href="http://www.brucelawson.co.uk/2010/a-minimal-html5-document/ ">here you go</a>.</p>
	<p>
		OK, this should be enough to give you some basic background on what&#39;s going on with HTML5 and why I chose to use it. In the <a href="http://www.highintegritydesign.com/blog/articles/building-a-modern-website-part-two-how-i-used-html5">next article</a>, I&#39;ll talk about the specific HTML5 elements I used and how I used them. Hope to see you there!</p>
</div>
<p>
	&nbsp;</p>

			]]>
	  </description>
      <dc:subject>{channel_description}</dc:subject>
      <dc:date>2011-03-02T16:25:53+00:00</dc:date>
    </item>

    <item>
      <title>Sitting down all day can kill you, but it doesn&#8217;t have to</title>
      <link>http://www.highintegritydesign.com/blog/articles/sitting-down-all-day-can-kill-you-but-it-doesnt-have-to</link>
      <guid>http://www.highintegritydesign.com/blog/articles/sitting-down-all-day-can-kill-you-but-it-doesnt-have-to#When:13:03</guid>
      <description><![CDATA[
			New research shows harsh evidence that sitting down all day has serious negative effects on your health...but you can do something about it.
			<h3>
	the new research</h3>
<p>
	Recently, there have been a number of articles showing the link between sitting down for several hours at a time and poor health. This has long been my gut feeling, but I thought I wouldn&rsquo;t be affected much since I work out several days a week.</p>
<p>
	Well, I was blown away when I read about the new studies showing <em>there are pretty bad consequences even if you work out regularly</em>. One of the best articles on this subject is the <a href="http://opinionator.blogs.nytimes.com/2010/02/23/stand-up-while-you-read-this/">New York Times story</a>. As the article says:</p>
<blockquote>
	<p>
		<em>&ldquo;If you spend most of the rest of the day sitting &mdash; in your car, your office chair, on your sofa at home &mdash; you are putting yourself at increased risk of obesity, diabetes, heart disease, a variety of cancers and an early death. In other words, irrespective of whether you exercise vigorously, sitting for long periods is bad for you.&rdquo;</em></p>
</blockquote>
<p>
	So, I&rsquo;m reading this and I&rsquo;m thinking, &ldquo;what the heck am I supposed to do about this&mdash;change careers?&rdquo; A lot of us spend our day sitting down at a desk and a computer. One thing we could do is <em>work less</em>. But, that&rsquo;s the subject of another post.&nbsp; For now though, it turns out there is something else we can do. <em>We can stand up while we work</em>.</p>
<h3>
	the stand-up desk</h3>
<p>
	<img alt="Adjustable height stand-up desk" class="image-box image-box-right caption" src="http://www.highintegritydesign.com/uploads/stand-up-desk.jpg" style="width: 200px; height: 200px;" />The <a href="http://opinionator.blogs.nytimes.com/2010/02/23/stand-up-while-you-read-this/">New York Times article</a> goes into the physiology, but basically standing is a lot better than sitting. And it can help you lose weight. So, I did some searches on Google and Amazon. It turns out there are a number of adjustable-height stand-up desks designed for office work. If you have an awesome boss, perhaps he/she will buy one for you (I&rsquo;m trying that option first). But if not, they aren&rsquo;t as expensive as I imagined.</p>
<p>
	One thing to watch out for: <em>an adjustable-height desk is not necessarily a stand-up desk</em> (which has a work surface minimum height of around 35 inches). I&rsquo;m not much of a do-it-yourself-er, but if you are you could build your own as well. Here is one I found that looks pretty good. It would be nice if it were a bit wider, but it&rsquo;s not bad at all. If my boss won&rsquo;t buy me one, this is probably the one I&rsquo;ll get.</p>
<h3>
	the sit-down chair for the stand-up desk</h3>
<p>
	<img alt="Tall drafting chair" class="image-box image-box-left caption" src="http://www.highintegritydesign.com/uploads/stand-up-desk-chair.jpg" style="width: 166px; height: 166px;" /><em>Okay, but you still need a chair</em>. Or at least I do. I&rsquo;m not going to stand every minute of the day, especially at first. And especially after a weight-lifting workout. And it needs to be extra-tall to work with the stand-up desk. After a bit of fruitless searching for the wrong type of chair, I figured out what I needed is a <em>drafting chair</em>. There are a lot of them available; here&rsquo;s one I was looking at.</p>
<p>
	&nbsp;</p>
<h3 style="clear:both">
	the rubber mat</h3>
<p>
	Finally, I&rsquo;m going to get a rubber mat because that makes a huge difference in comfort when standing so much. One of the first things I learned in my career was standing all day on a hard cement floor at a trade show really hurts! I&rsquo;m still looking for a good mat, but I saw one at the local bike shop they bought for their mechanics (which by the way, is an awesome way to treat your employees). Hats off to you <a href="http://www.peaksportscorvallis.com/bikes/index.html">Peak Sports</a>.</p>
<h3>
	adding it all up, and what you can do</h3>
<p>
	Hmmm, when I add it all up it gets to be more expensive than I thought. <em>Total cost is around $400-$600</em>. That&rsquo;s not cheap, though I&rsquo;m willing to pay for it when I consider the health benefits. However, I&rsquo;m still troubled. For me this is a significant expense, but I can afford it. But a lot of people live paycheck to paycheck. And there are jobs which require sitting down all day, such as the truck drivers who deliver our food to us. What about them?</p>
<p>
	I wish I had a good answer for helping everyone, but I don&rsquo;t. However, I can do my part to model positive change by showing my boss the research. And, in a non-adversarial way, by buying a stand-up desk or convincing my boss to buy one for me. And so can you. Perhaps together we can begin to change the cultural expectation that we have to trade in our health for our job. Is your job worth dying for? Mine isn&rsquo;t, and I can do something about it. So can you.</p>

			]]>
	  </description>
      <dc:subject>{channel_description}</dc:subject>
      <dc:date>2011-02-04T13:03:50+00:00</dc:date>
    </item>

    
    </channel>
</rss>
