<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>NCZOnline</title>
	
	<link>http://www.nczonline.net/blog</link>
	<description>The Official Web Site of Nicholas C. Zakas</description>
	<lastBuildDate>Tue, 21 May 2013 16:00:20 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/nczonline" /><feedburner:info uri="nczonline" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>nczonline</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>GitHub workflows inside of a company</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/wl4tTija-Cs/</link>
		<comments>http://www.nczonline.net/blog/2013/05/21/github-workflows-inside-of-a-company/#comments</comments>
		<pubDate>Tue, 21 May 2013 16:00:20 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[GitHub]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=3409</guid>
		<description><![CDATA[Recently I asked engineers to share their experiences working with GitHub at companies. I&#8217;ve always used GitHub for open source projects, but I was interested in learning more about using it professionally and how one&#8217;s development workflow might change given all of GitHub&#8217;s capabilities. I set up a gist[1] so people could leave the answers [...]]]></description>
				<content:encoded><![CDATA[<p>Recently I asked engineers to share their experiences working with GitHub at companies. I&#8217;ve always used GitHub for open source projects, but I was interested in learning more about using it professionally and how one&#8217;s development workflow might change given all of GitHub&#8217;s capabilities. I set up a gist<sup>[1]</sup> so people could leave the answers to my questions and got some great responses. The information comes from companies such as Yammer, BBC News, Flickr, ZenDesk, Simple, and more. This is an overview of the responses I received plus some detail from Scott Chacon&#8217;s post on Git Flow at GitHub<sup>[2]</sup>.</p>
<h2>Basic setup</h2>
<p>Everyone has at least one GitHub organization under which the official repositories live. Some have more than one organization, each representing a different aspect of the business, however all official repositories are owned by an organization. I suspect this would be the case as it would be horribly awkward to have an important repository owned by a user who may or may not be at the company next year. Also, using an organizational owner for these repositories allows better visibility as to what&#8217;s going on with official projects just by looking at the organization.</p>
<p>Several people mentioned that no one is barred from creating their own repositories on GitHub for side projects or other purposes. Creating repositories for company-related work is generally encouraged. If a side project becomes important enough, it can be promoted to an organizational repository.</p>
<h2>Developer setup</h2>
<p>Companies took a couple of different approaches to submitting code:</p>
<ul>
<li>Most indicated that developers clone the organization repository for their product and then work on feature branches within that repository. Changes are pushed to a remote feature branch for review and safe-keeping.</li>
<li>Some indicated that each developer forks the organization repository and does the work there until it&#8217;s ready for merging into the organization repository.</li>
<li>A couple indicated that they started out with forks and then switched to feature branches on the organization repository due to better transparency and easier workflow.</li>
</ul>
<p>The general trend is in the direction of feature branches on the organization repository. Since you can send pull requests from one branch to another, you don&#8217;t lose the review mechanism.</p>
<h2>Submitting code</h2>
<p>In the open source world, external contributors submit pull requests when they want to contribute while the maintainers of the project commit directly to the repository. In the corporate world, where everyone may logically be a maintainer for the repository, does it makes sense to have developers send pull requests? The responses were:</p>
<ul>
<li><span style="line-height: 13px;">Some required pull requests for all changes.</span></li>
<li>Some required pull requests only for changes outside of their responsibility area (i.e., making a change to another team&#8217;s repo). Other changes can be submitted directly to the organization repository.</li>
<li>Some left this up to the developer&#8217;s discretion. The developer should know the amount of risk associated with the change and whether or not another set of eyes is useful. The option to submit directly to the repository is always there.</li>
</ul>
<p>The responsibility for merging in pull requests varied across the responses. Some required the team leads to do the merging, others allowed anyone to do the merging.</p>
<p>Interestingly, some indicated that they start a pull request as soon as a new feature branch is created in order to track work and provide better visibility. That way, there can be a running dialog about the work being done in that branch instead of temporary one at the time of work completion.</p>
<h2>Preparing code for submission</h2>
<p>A secondary part of this process is how the code must be prepared before being merged in. The accepted practice of squashing commits and rebasing still  remains common across the board though the benefits aren&#8217;t clear to everyone. Of those who responded:</p>
<ul>
<li><span style="line-height: 13px;">Some required a squash and rebase before a pull request can be merged in.</span></li>
<li>Some will merge in a pull request regardless of the makeup of commits.</li>
<li>Some care about keeping a strict, non-branching history while others do not.</li>
</ul>
<p>It&#8217;s hard to outline any consistent trends in this regard. Whether or not you squash, rebase, or merge is very much a team-specific decision (not an organization-specific one).</p>
<h2>What about git-flow?</h2>
<p>I didn&#8217;t ask this question specifically, but it came up enough. Git-flow[3] is a process for managing changes in Git that was created by Vincent Driessen and accompanied by some Git extensions[4] for managing that flow. The general idea behind git-flow is to have several separate branches that always exist, each for a different purpose: master, develop, feature, release, and hotfix. The process of feature or bug development flows from one branch into another before it&#8217;s finally released.</p>
<p>Some of the respondents indicated that they use git-flow in general. Some started out with git-flow and moved away from it. The primary reason for moving away is that the git-flow process is hard to deal with in a continuous (or near-continuous) deployment model. The general feeling is that git-flow works well for products in a more traditional release model, where releases are done once every few weeks, but that this process breaks down considerably when you&#8217;re releasing once a day or more.</p>
<h2>Conclusion</h2>
<p>A lot of people shared a lot of very interesting anecdotes about using GitHub at their companies. As I expected, there&#8217;s no one accepted way that people are using GitHub for this purpose. What&#8217;s interesting is the range of ways people have chosen to adapt what is essentially an open source workflow for enterprise use. Since GitHub also has GitHub Enterprise, I&#8217;m certain that this trend will continue. It will be interesting to see if the feedback from GitHub Enterprise and corporate needs will end up changing the public-facing GitHub in any way.</p>
<p>I&#8217;m interested in doing more research about how Git and GitHub in particular are used inside of companies. I&#8217;ve yet to see any good research done on whether or not squashing and rebasing is important in the long run, and I think that would be great to figure out. Please feel free to share your experiences in the comments.</p>
<h2>References</h2>
<ol>
<li><a href="https://gist.github.com/nzakas/5511916">How do you use GitHub at your company?</a> (GitHub Gist)</li>
<li><a href="http://scottchacon.com/2011/08/31/github-flow.html">GitHub flow</a> by Scott Chacon (Scott Chacon&#8217;s Blog)</li>
<li><a href="http://nvie.com/posts/a-successful-git-branching-model/">A successful Git branching model</a> by Vincent Driessen (nvie.com)</li>
<li><a href="https://github.com/nvie/gitflow">git-flow Git Extensions</a> (GitHub)</li>
</ol>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=wl4tTija-Cs:DmB7c1GyKX8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=wl4tTija-Cs:DmB7c1GyKX8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=wl4tTija-Cs:DmB7c1GyKX8:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=wl4tTija-Cs:DmB7c1GyKX8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=wl4tTija-Cs:DmB7c1GyKX8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=wl4tTija-Cs:DmB7c1GyKX8:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/wl4tTija-Cs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2013/05/21/github-workflows-inside-of-a-company/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.nczonline.net/blog/2013/05/21/github-workflows-inside-of-a-company/</feedburner:origLink></item>
		<item>
		<title>Blink and the end of vendor prefixes</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/rJ_v9xbUvsA/</link>
		<comments>http://www.nczonline.net/blog/2013/04/30/blink-and-the-end-of-vendor-prefixes/#comments</comments>
		<pubDate>Tue, 30 Apr 2013 14:00:39 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Blink]]></category>
		<category><![CDATA[Vendor Prefix]]></category>
		<category><![CDATA[WebKit]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=3404</guid>
		<description><![CDATA[When Google announced that it was forking WebKit into Blink, there was a lot of discussion around what this would mean for web developers, and if the WebKit monoculture was truly breaking or not. Amongst the consternation and hypotheticizing was a detail that went overlooked by many: Blink&#8217;s plan to stop creating new vendor prefixes. [...]]]></description>
				<content:encoded><![CDATA[<p>When Google announced that it was forking WebKit into Blink, there was a lot of discussion around what this would mean for web developers, and if the WebKit monoculture was truly breaking or not. Amongst the consternation and hypotheticizing was a detail that went overlooked by many: Blink&#8217;s plan to stop creating new vendor prefixes. This, to me, is one of the most significant shifts in browser philosophy that has occurred in recent memory.</p>
<h2>Why vendor prefixes anyway?</h2>
<p>The idea behind vendor-prefixed features (both JavaScript and CSS) is quite simple: give browser developers and web developers opportunities to work with as-yet-incompletely-specified features to get feedback. The goal was just. How do browser developers really know if a proposed feature will work if they don&#8217;t actually try to build it? Likewise, how do web developers know that a feature is useful if they never have the chance to try and use it? Vendor-prefixed features gave browsers the freedom to implement stuff that might not be quite ready and web developers the chance to give feedback to the browsers regarding these features. It seemed like a win-win situation. So what went wrong?</p>
<h2>To a person with a hammer&#8230;</h2>
<p>There were problems with these vendor-prefixed features. First, browser developers were hanging on to them for far longer than originally anticipated. Firefox had <code>-moz-border-radius</code> from the beginning and it was only officially removed in Firefox 13, a timespan of over 8 years. Vendor-prefixed properties ended up being a playground for browser vendors where any experiment, prototype, or other &#8220;not exactly standard&#8221; feature could be implemented. After all, it was free to do so and developers should be forewarned by the vendor-prefix that this thing shouldn&#8217;t be relied upon.</p>
<p>Web developers, however, saw vendor-prefixed properties more as &#8220;the way that browser X is choosing to support this feature&#8221; rather than as an experimental extension. That meant web sites started to depend on these experimental features for their functionality or appearance, leading to the creation of tools that would help by pointing out or automatically adding the correct vendor-prefixed version of CSS properties. Lest we forget this mess:</p>
<pre><code>.box {
    background: #1e5799; /* Old browsers */
    background: -moz-linear-gradient(top,  #1e5799 0%, #2989d8 50%, #207cca 51%, #7db9e8 100%); /* FF3.6+ */
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#1e5799), color-stop(50%,#2989d8), color-stop(51%,#207cca), color-stop(100%,#7db9e8)); /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(top,  #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); /* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(top,  #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); /* Opera 11.10+ */
    background: -ms-linear-gradient(top,  #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); /* IE10+ */
    background: linear-gradient(to bottom,  #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); /* W3C */
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1e5799', endColorstr='#7db9e8',GradientType=0 ); /* IE6-9 */
}</code></pre>
<p>And in JavaScript, more and more code ended up looking like this<sup>[1]</sup>:</p>
<pre><code>    var vendors = ['ms', 'moz', 'webkit', 'o'];
    for(var x = 0; x < vendors.length &#038;&#038; !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] 
                                   || window[vendors[x]+'CancelRequestAnimationFrame'];
    }</code></code></pre>
<p>These patterns in CSS and JavaScript indicated that web developers were not treating these features as experimental, but as dependencies they needed for things to work. Browser vendors didn&#8217;t do web developers any favors by keeping these features around as long as they did. Certainly, quickly-disappearing vendor-prefixed features would teach web developers not to rely on them.</p>
<h2>More recently</h2>
<p>The quickly-disappearing theory of vendor-prefixed features also seemed to be incorrect. Internet Explorer 10 introduced some features with a <code>ms</code> extension in the beta version, and then removed the prefixes when the final version was released. This created a lot of confusion amongst web developers as to whether or not <code>ms</code> was necessary to use certain features. Likewise, Chrome had started moving features through vendor-prefixed versions to standard ones much faster than before. Yet, there were still features that lagged far behind, so there&#8217;s a mix of <code>webkit</code> prefixed functionality: some that have been around for a while and no one&#8217;s quite sure where they&#8217;re going (<code>-webkit-appearance</code>) while others moved quickly into a standardized version (<code>webkitIndexedDB</code>).</p>
<p>Due to this confusion, and the desire of browsers to properly support a large number of sites, some Mozilla and Opera considered supporting <code>webkit</code> CSS properties to have better compatibility with the web at large.<sup>[2]</sup> There were a lot of opinion pieces about whether or not this was a good thing, but all agreed that vendor prefixes resulted in a massive mess that there was no easy way to clean up.</p>
<h2>Goodbye, vendor prefixes!</h2>
<p>Blink&#8217;s decision to stop creating new vendor-prefixed functionality is the right approach to me. Remember, the whole point of vendor prefixes was to allow browser developers to test implementations and for web developers to give feedback. You don&#8217;t need vendor prefixes for that. Blink&#8217;s approach is to allow you to turn on certain experimental features through browser settings is something I&#8217;m very excited about. Doing so allows browser developers to continue with experimental implementations without the fear that web developers will come to rely on those features. It also gives web developers the opportunity to turn on those features and try them out, with a very clear directive that you cannot rely on your users having this feature enabled, therefore you should not depend on it.</p>
<p>I definitely welcome and look forward to a prefix-free world. We got into such a mess and placed so much cognitive burden on so many people for so long that it may be a crime in certain parts of the universe. Everyone needs the ability to experiment so that the web can continue to develop new functionality, but we all need to be smarter about how we implement and use those features. The Blink approach follows a systems approach that I like: make it difficult for people to do the wrong thing. If other browsers adopt the same approach then we can be assured that the future CSS and JavaScript we write won&#8217;t be hampered down by numerous duplicate declarations or annoying feature tests. We can all just go back to what we really want to do: make awesome web experiences without forking our code for every browser.</p>
<h2>References</h2>
<ol>
<li><a href="https://gist.github.com/paulirish/1579671">requestAnimationFrame() polyfill</a> (GitHub)</li>
<li><a href="http://css-tricks.com/tldr-on-vendor-prefix-drama/">tl;dr on vendor prefix drama</a> by Chris Coyier (CSS Tricks)</li>
</ol>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=rJ_v9xbUvsA:hzHDF7ZEQXI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=rJ_v9xbUvsA:hzHDF7ZEQXI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=rJ_v9xbUvsA:hzHDF7ZEQXI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=rJ_v9xbUvsA:hzHDF7ZEQXI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=rJ_v9xbUvsA:hzHDF7ZEQXI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=rJ_v9xbUvsA:hzHDF7ZEQXI:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/rJ_v9xbUvsA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2013/04/30/blink-and-the-end-of-vendor-prefixes/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://www.nczonline.net/blog/2013/04/30/blink-and-the-end-of-vendor-prefixes/</feedburner:origLink></item>
		<item>
		<title>Getting the URL of an iframe’s parent</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/fbiFfwoyMo0/</link>
		<comments>http://www.nczonline.net/blog/2013/04/16/getting-the-url-of-an-iframes-parent/#comments</comments>
		<pubDate>Tue, 16 Apr 2013 17:15:34 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[iframe]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[referrer]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=3402</guid>
		<description><![CDATA[Dealing with iframes is always a double-edged sword. On the one hand, you get sandboxing of content within another page, ensuring that JavaScript and CSS from one page won&#8217;t affect another. If the iframe is displayed a page from a different origin then you can also be assured that the page can&#8217;t do anything nefarious [...]]]></description>
				<content:encoded><![CDATA[<p>Dealing with iframes is always a double-edged sword. On the one hand, you get sandboxing of content within another page, ensuring that JavaScript and CSS from one page won&#8217;t affect another. If the iframe is displayed a page from a different origin then you can also be assured that the page can&#8217;t do anything nefarious to the containing page. On the other hand, iframes and their associated <code>window</code> objects are a mess of permissible and impermissible actions that you need to remember<sup>[1]</sup>. Working with iframes is frequently an exercise in frustration as you methodically move through what you&#8217;re allowed to do.</p>
<p>I was recently asked if there&#8217;s a way to get the URL of an iframe&#8217;s parent page, which is to say, the URL of the page with the <code>&lt;iframe&gt;</code> element. This seems like a simple enough task. For a regular page, you typically get the URL by using <code>window.location</code>. There are also <code>parent</code> to get the <code>window</code> object of the parent page and <code>top</code> to get the <code>window</code> object of the outermost page. You can then use <code>parent.location</code> or <code>top.location</code> to get a URL from the containing page depending on your needs. At least, that&#8217;s how you do it when both the iframe page and the containing page are from the same origin.</p>
<p>When the iframe page and containing page are from different origins, then you are completely cut off from the <code>parent.location</code> and <code>top.location</code>. This information is considered unsafe to share across origins. However, that doesn&#8217;t mean you can&#8217;t find out the URL of the containing page. To do so, you simply need to keep in mind what information the iframe owns and what information it does not.</p>
<p>To start, you should double-check that the page is actually in an iframe, which you can do with this code:</p>
<pre><code>var isInIframe = (parent !== window);</code></pre>
<p>When a page is running inside of an iframe, the <code>parent</code> object is different than the <code>window</code> object. You can still access <code>parent</code> from within an iframe even though you can&#8217;t access anything useful on it. This code will never cause an error even when crossing origins.</p>
<p>Once you know you&#8217;re in an iframe, you can take advantage of a little-known fact: the HTTP <code>Referer</code> header for a page inside of an iframe is always set to the containing page&#8217;s URL. That means a page embedded in an iframe on <code>http://www.nczonline.net</code> will have a <code>Referer</code> header equal to that URL. Knowing this fact, you need only use the oft-forgotten <code>document.referrer</code> property. As the name suggestions, this property contains the value of the <code>Referer</code> header for the given document. So you can get the URL of the iframe&#8217;s parent page like this:</p>
<pre><code>function getParentUrl() {
    var isInIframe = (parent !== window),
        parentUrl = null;

    if (isInIframe) {
        parentUrl = document.referrer;
    }

    return parentUrl;
}</code></pre>
<p>While this may look like a security issue, it&#8217;s really not. The <code>Referer</code> is already being sent to the server that is serving up the iframe page, so that information is already known by the web application. The <code>document.referrer</code> property is just exposing the information that the server already has. Since the <code>document</code> object is owned by the iframe <code>window</code>, you aren&#8217;t crossing the same-origin policy boundary.</p>
<p>Iframes are always a little bit hairy to deal with, especially when you throw JavaScript into the mix. The good news is that there&#8217;s usually a way to do something that makes sense and won&#8217;t put a user at risk, whether that be through <code>document.referrer</code> cross-document messaging, or some other means.</p>
<h2>References</h2>
<ol>
<li><a href="http://www.nczonline.net/blog/2009/09/15/iframes-onload-and-documentdomain/">Iframes, onload, and document.domain</a> by me (NCZOnline)</li>
</ol>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=fbiFfwoyMo0:ApIMQ7xCq2w:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=fbiFfwoyMo0:ApIMQ7xCq2w:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=fbiFfwoyMo0:ApIMQ7xCq2w:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=fbiFfwoyMo0:ApIMQ7xCq2w:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=fbiFfwoyMo0:ApIMQ7xCq2w:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=fbiFfwoyMo0:ApIMQ7xCq2w:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/fbiFfwoyMo0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2013/04/16/getting-the-url-of-an-iframes-parent/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://www.nczonline.net/blog/2013/04/16/getting-the-url-of-an-iframes-parent/</feedburner:origLink></item>
		<item>
		<title>Making accessible icon buttons</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/oohe8HLdmMI/</link>
		<comments>http://www.nczonline.net/blog/2013/04/01/making-accessible-icon-buttons/#comments</comments>
		<pubDate>Mon, 01 Apr 2013 14:30:48 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[ARIA]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Screen Readers]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=3391</guid>
		<description><![CDATA[Last week, Pamela Fox tweeted a question to me: @slicknet Do you know the best way to make a &#60;button&#62; that just has an icon accessible? title, aria-label, hidden text? &#8212; Pamela Fox (@pamelafox) March 26, 2013 As tends to happen on Twitter, we fruitlessly exchanged 140 character messages trying to get some resolution before [...]]]></description>
				<content:encoded><![CDATA[<p>Last week, Pamela Fox tweeted a question to me:</p>
<blockquote class="twitter-tweet"><p>@<a href="https://twitter.com/slicknet">slicknet</a> Do you know the best way to make a &lt;button&gt; that just has an icon accessible? title, aria-label, hidden text?</p>
<p>&mdash; Pamela Fox (@pamelafox) <a href="https://twitter.com/pamelafox/status/316692888538980353">March 26, 2013</a></p></blockquote>
<p><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p>As tends to happen on Twitter, we fruitlessly exchanged 140 character messages trying to get some resolution before I finally offered to write a blog post explaining my view. Along the way, I discovered that I had misunderstood the original question (yay 140 character responses) and needed to do a little research. And so here it is.</p>
<h2>Simple icon buttons</h2>
<p>In the beginning, there <code>&lt;input type="image"&gt;</code>. Many seem to have forgotten this part of HTML. Early on, web developers wanted to use images as submit buttons rather than the plain submit button and <code>&lt;input type="image"&gt;</code> allowed you to create an image that actually works like a button. Further, this type of image actually announces itself as a button in screen readers. Anytime you want the user to click on something and <em>not</em> navigate to another page, you&#8217;re looking for a button, and <code>&lt;input type="image"&gt;</code> gives you a nice compact way of doing that while supporting the same attributes as <code>&lt;img&gt;</code>. For example:</p>
<pre><code>&lt;input type="image" src="email.png" width="14" height="14" alt="Email"&gt;</code></pre>
<p>In this case, the major screen readers (JAWS, NVDA, VoiceOver) announce &#8220;Email button&#8221; in all major browsers, reading the <code>alt</code> text and identifying the image as a button. Part of the reason this pattern isn&#8217;t used much anymore is due to the ubiquity of CSS sprites. However, it&#8217;s still my favorite pattern, and with a little adjusting, works fine with sprites:</p>
<pre><code>&lt;style&gt;
    .email-btn {
        width: 14px;
        height: 14px;
        background: url(activities.png) 0 -85px no-repeat;
    }
&lt;/style&gt;

&lt;input type="image" src="pixel.gif" class="email-btn" alt="Email"&gt;</code></pre>
<p>This example uses a single transparent GIF as the <code>src</code> of the image. Doing so allows a background image to be applied and show through via the &#8220;email-btn&#8221; class. If the thought of having an extra download for an icon button is unpalatable to you, you can also use a data URI representing a single transparent pixel:</p>
<pre><code>data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==</code></pre>
<p>In either case, the major screen readers still announce &#8220;Email button&#8221; when focus is set to the button, which is exactly what you want.</p>
<h2>Using &lt;button&gt;</h2>
<p>The <code>&lt;button&gt;</code> element has becomes the element of choice for making non-text buttons in HTML. This makes complete sense because you can put whatever HTML you desire inside and it renders as a button. However, the end result is not the same as with the more traditional approach. First, consider a really simple example:</p>
<pre><code>&lt;button&gt;&lt;img src="email.png" width="14" height="14" alt="Email"&gt;&lt;/button&gt;</code></pre>
<p>This button produces some very different results in different browsers and different screen readers:</p>
<ul>
<li><strong>Chrome 25 (Win7/NVDA):</strong> &#8220;Button&#8221;</li>
<li><strong>Internet Explorer 9 (Win7/NVDA):</strong> &#8220;Button&#8221;</li>
<li><strong>Firefox 19 (Win7/NVDA):</strong> &#8220;Email graphic button&#8221;</li>
<li><strong>Chrome 25 (Win7/JAWS):</strong> &#8220;Email button&#8221;</li>
<li><strong>Internet Explorer 9 (Win7/JAWS):</strong> &#8220;Email button&#8221;</li>
<li><strong>Firefox 19 (Win7/JAWS):</strong> &#8220;Email button&#8221;</li>
<li><strong>Chrome 25 (Mac OS X/VoiceOver):</strong> &#8220;Email button&#8221;</li>
<li><strong>Safari 6 (Mac OS X/VoiceOver):</strong> &#8220;Button&#8221;</li>
<li><strong>Firefox 19 (Mac OS X/VoiceOver):</strong> &#8220;Email button&#8221;</li>
<li><strong>Mobile Safari (iOS 6/VoiceOver):</strong> &#8220;Button&#8221;</li>
</ul>
<p>So basically, using a <code>&lt;button&gt;</code> element introduces a barrier for most screen reader/browser combinations to figure out what the button is doing. It doesn&#8217;t matter if the <code>&lt;img&gt;</code> is used more traditionally or with a sprite, you don&#8217;t get much information in most places.</p>
<p>You can give screen readers a hint by using the <code>aria-label</code> attribute on the <code>&lt;button&gt;</code> element. Doing so means providing a plain-text label for the button as a whole:</p>
<pre><code>&lt;button aria-label="Email"&gt;&lt;img src="email.png" width="14" height="14" alt="Email"&gt;&lt;/button&gt;</code></pre>
<p>By adding an <code>aria-label</code>, the various screen readers and browsers respond as follows:</p>
<ul>
<li><strong>Chrome 25 (Win7/NVDA):</strong> &#8220;Email button&#8221;</li>
<li><strong>Internet Explorer 9 (Win7/NVDA):</strong> &#8220;Email button&#8221;</li>
<li><strong>Firefox 19 (Win7/NVDA):</strong> &#8220;Email graphic button&#8221;</li>
<li><strong>Chrome 25 (Win7/JAWS):</strong> &#8220;Email Button&#8221;</li>
<li><strong>Internet Explorer 9 (Win7/JAWS):</strong> &#8220;Email Button&#8221;</li>
<li><strong>Firefox 19 (Win7/JAWS):</strong> &#8220;Email button&#8221;</li>
<li><strong>Chrome 25 (Mac OS X/VoiceOver):</strong> &#8220;Email button&#8221;</li>
<li><strong>Safari 6 (Mac OS X/VoiceOver):</strong> &#8220;Email button&#8221;</li>
<li><strong>Firefox 19 (Mac OS X/VoiceOver):</strong> &#8220;Email button&#8221;</li>
<li><strong>Mobile Safari (iOS 6/VoiceOver):</strong> &#8220;Email button&#8221;</li>
</ul>
<p>So now you actually have a nice response from all of the major browsers and screen readers. You can use this same technique regardless of what you place inside of the <code>&lt;button&gt;</code> element.</p>
<h2>Font Awesome</h2>
<p>Part of what I missed from my original Twitter discussion with Pamela was that she was using Font Awesome<sup>[1]</sup>. For the uninitiated, Font Awesome is an icon font that contains numerous common icons for use in HTML. Instead of using separate image files or a sprite that you have to manage, you can use an icon font and reference the relevant icon by using a class name. The icon is inserted via CSS, so it has no negative accessibility concerns. This example is similar to the one Pamela brought up:</p>
<pre><code>&lt;button&gt;&lt;span class="icon-envelope"&gt;&lt;/span&gt;&lt;/button&gt;</code></pre>
<p>The question is, how do you add descriptive text to this? One way would be to add an <code>aria-label</code> attribute as in the previous section:</p>
<pre><code>&lt;button aria-label="Email"&gt;&lt;span class="icon-envelope"&gt;&lt;/span&gt;&lt;/button&gt;</code></pre>
<p>Since that always works for <code>&lt;button&gt;</code> elements, that&#8217;s the fastest and easiest way forward. The result in various screen readers:</p>
<ul>
<li><strong>Chrome 25 (Win7/NVDA):</strong> &#8220;Email button&#8221;</li>
<li><strong>Internet Explorer 9 (Win7/NVDA):</strong> &#8220;Email button&#8221;</li>
<li><strong>Firefox 19 (Win7/NVDA):</strong> &#8220;Email button&#8221;</li>
<li><strong>Chrome 25 (Win7/JAWS):</strong> &#8220;Email Button&#8221;</li>
<li><strong>Internet Explorer 9 (Win7/JAWS):</strong> &#8220;Email Button&#8221;</li>
<li><strong>Firefox 19 (Win7/JAWS):</strong> &#8220;Email button&#8221;</li>
<li><strong>Chrome 25 (Mac OS X/VoiceOver):</strong> &#8220;Email button&#8221;</li>
<li><strong>Safari 6 (Mac OS X/VoiceOver):</strong> &#8220;Email button&#8221;</li>
<li><strong>Firefox 19 (Mac OS X/VoiceOver):</strong> &#8220;Email button&#8221;</li>
<li><strong>Mobile Safari (iOS 6/VoiceOver):</strong> &#8220;Email button&#8221;</li>
</ul>
<p>I prefer this over the second (and often overused option) of hiding text off screen, in which case you would have code similar to this:</p>
<pre><code>&lt;button&gt;&lt;span class="icon-envelope"&gt;&lt;/span&gt;&lt;span class="hide-offscreen"&gt;Email&lt;/a&gt;&lt;/button&gt;</code></pre>
<p>The idea here is to position text far off in some direction such that it&#8217;s not visible to sighted users but is still read out for screen reader users. I&#8217;m not a huge fan of hiding text off screen, primarily because it feels very hacky&#8230;a bit like a sleight of hand trick. Additionally, each of the major ways of hiding text off screen comes with some sort of caveat. Using a big negative <code>text-indent</code> doesn&#8217;t work well with RTL languages, using a <code>height</code> of 0 means VoiceOver won&#8217;t announce the contents, and so on. Jonathan Snook put together a fantastic post<sup>[2]</sup> outlining the different approaches and the caveats to each.</p>
<p>The screen readers all end up announcing the same message as when using <code>aria-label</code>.</p>
<p>Do I use hiding text off screen periodically? Yes, but only as a measure of last resort when I&#8217;ve exhausted all other possibilities. I would encourage you to do the same.</p>
<p>One final note: don&#8217;t use <code>title</code> as your button label. Example:</p>
<pre><code>&lt;button title="Email"&gt;&lt;span class="icon-envelope"&gt;&lt;/span&gt;&lt;/button&gt;</code></pre>
<p>While it would be ideal if screen readers were able to use this value, the results are very uneven:</p>
<ul>
<li><strong>Chrome 25 (Win7/NVDA):</strong> &#8220;Email button&#8221;</li>
<li><strong>Internet Explorer 9 (Win7/NVDA):</strong> &#8220;Email button&#8221;</li>
<li><strong>Firefox 19 (Win7/NVDA):</strong> &#8220;Button email&#8221;</li>
<li><strong>Chrome 25 (Win7/JAWS):</strong> &#8220;Email Button&#8221;</li>
<li><strong>Internet Explorer 9 (Win7/JAWS):</strong> &#8220;Email Button&#8221;</li>
<li><strong>Firefox 19 (Win7/JAWS):</strong> &#8220;Email button&#8221;</li>
<li><strong>Chrome 25 (Mac OS X/VoiceOver):</strong> &#8220;Button&#8221;</li>
<li><strong>Safari 6 (Mac OS X/VoiceOver):</strong> &#8220;Button&#8221;</li>
<li><strong>Firefox 19 (Mac OS X/VoiceOver):</strong> &#8220;Email button&#8221;</li>
<li><strong>Mobile Safari (iOS 6/VoiceOver):</strong> &#8220;Email button&#8221;</li>
</ul>
<p>Even though the <code>title</code> attribute is helpful for sighted users as a hint, it doesn&#8217;t provide any real consistent benefit as far as screenreaders go.</p>
<h2>Update (07-April-2013)</h2>
<p>As several commenters mentioned, my recommendation results in an empty <code>&lt;button&gt;</code> element. I wasn&#8217;t too concerned about that at first, but as I thought about it more and more, the purist in me got a little bit upset. Yes, in an ideal world, you should be able to remove all JavaScript and CSS and the page still make sense. In this case, you&#8217;d be left with a button that has no descriptive text whatsoever. That turned my stomach and I went back to the drawing board to try and find a way to have text inside of the <code>&lt;button&gt;</code> element without hiding it offscreen. After some tinkering, here&#8217;s what I came up with:</p>
<pre><code>&lt;style&gt;
.btn-label {
    font-size: 0;
    height: 1px;
    overflow: hidden;
    display: block;
}
&lt;/style&gt;

&lt;button class="icon-envelope"&gt;&lt;span class="btn-label"&gt;Email&lt;/span&gt;&lt;/button&gt;
</code></pre>
<p>The idea is to have the descriptive text inside of the <code>&lt;button&gt;</code> element while placing the Font Awesome class on the <code>&lt;button&gt;</code> itself. This allows you to modify the inner <code>&lt;span&gt;</code> element separately from the <code>&lt;button&gt;</code>. The <code>&lt;span&gt;</code> is set to be practically invisible by using a <code>font-size</code> of 0, a <code>height</code> of one pixel (to make VoiceOver happy). The rest is used to ensure the <code>&lt;span&gt;</code> never grows any larger.</p>
<p>In all browsers and screenreaders mentioned in this post, the text &#8220;Email button&#8221; is announced using this pattern. The solution is something that makes the purist side of me very comfortable. You aren&#8217;t tempting fate by moving text offscreen yet the <code>&lt;button&gt;</code> element still has text inside of it. You don&#8217;t have to use ARIA to provide additional context for screen readers in this case.</p>
<h2>Conclusion</h2>
<p>I still prefer the old-school <code>&lt;input type="image"&gt;</code> element for creating clickable icons. However, in the case of using an icon font, that really doesn&#8217;t work. In that situation, <del>I prefer to use the <code>aria-label</code> attribute to provide additional text for screen readers. Doing so yields the most consistent treatment for buttons across major browsers and screenreaders.</del> I prefer to use some in-line hidden text to ensure the <code>&lt;button&gt;</code> element has actual text inside. As a bonus, you don&#8217;t have to worry too much about how position text off screen might affect other parts of the page. </p>
<h2>References</h2>
<ol>
<li><a href="http://fortawesome.github.com/Font-Awesome/">Font Awesome</a> (GitHub)
</li>
<li><a href="http://snook.ca/archives/html_and_css/hiding-content-for-accessibility">Hiding content for accessibility</a> by Jonathan Snook (snook.ca)</li>
</ol>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=oohe8HLdmMI:YeXG7EKfmeY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=oohe8HLdmMI:YeXG7EKfmeY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=oohe8HLdmMI:YeXG7EKfmeY:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=oohe8HLdmMI:YeXG7EKfmeY:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=oohe8HLdmMI:YeXG7EKfmeY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=oohe8HLdmMI:YeXG7EKfmeY:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/oohe8HLdmMI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2013/04/01/making-accessible-icon-buttons/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		<feedburner:origLink>http://www.nczonline.net/blog/2013/04/01/making-accessible-icon-buttons/</feedburner:origLink></item>
		<item>
		<title>Internet Explorer 11′s user-agent string: What does it mean?</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/BXH94zSEWB8/</link>
		<comments>http://www.nczonline.net/blog/2013/03/27/internet-explorer-11s-user-agent-string-what-does-it-mean/#comments</comments>
		<pubDate>Wed, 27 Mar 2013 14:30:34 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Browsers]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[User Agent String]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=3387</guid>
		<description><![CDATA[Over the past few days, people have been going a little crazy over the announcement of the Internet Explorer 11 user-agent string. User-agent string announcements are typically met with a keen eye as we are still horribly tied to user-agent sniffing on servers around the world. And so when some beta testers leaked an Internet [...]]]></description>
				<content:encoded><![CDATA[<p>Over the past few days, people have been going a little crazy over the announcement of the Internet Explorer 11 user-agent string. User-agent string announcements are typically met with a keen eye as we are still horribly tied to user-agent sniffing on servers around the world. And so when some beta testers leaked an Internet Explorer 11 user-agent string, people sat up and paid attention. The string in question, reported by Neowin<sup>[1]</sup>, looks like this:</p>
<pre><code>Mozilla/5.0 (IE 11.0; Windows NT 6.3; Trident/7.0; .NET4.0E; .NET4.0C; rv:11.0) like Gecko</code></pre>
<p>If you&#8217;ve read my <a href="http://www.nczonline.net/blog/2010/01/12/history-of-the-user-agent-string/">history of user-agent strings</a> post, then you&#8217;re aware of the sinister history of user-agent strings and how browsers try to trick servers into believing that they are other browsers. Internet Explorer 3 actually began the practice by using &#8220;Mozilla&#8221; in the user-agent string so it would be identified by servers trying to filter for Netscape.</p>
<p>If this user-agent string is the final one (Microsoft hasn&#8217;t confirmed or denied this is the user-agent string), then it shows how one can manipulate the user-agent string to get different results. For comparison, here are a few different user-agent strings:</p>
<pre><code>Internet Explorer 10
Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)

Firefox 19 (Windows 7)
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0

Safari 6
Mozilla/5.0 (Macintosh; Intel Mac OS X 1076) AppleWebKit/536.26.17 (KHTML like Gecko) Version/6.0.2 Safari/536.26.17

Chrome 25 (Windows 7)
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22</code></pre>
<p>In the past, it was easy to identify Internet Explorer by searching for the string &#8220;MSIE&#8221; in the user-agent string. If present, the browser is Internet Explorer. When Gecko was the embedded webview of choice, many simply looked for &#8220;Gecko&#8221; in the user-agent string to determine if it was a Gecko-powered browser (and therefore likely to behave as Firefox). That approach fell apart when Safari decided to add &#8220;like Gecko&#8221; into the middle of its user-agent string. Not long ago, WebKit overtook Gecko as the embeddable webview of choice, and so many started looking for &#8220;Firefox&#8221; in the user-agent string to specifically identify Firefox.</p>
<p>Chrome came along and wanted to be identified as Safari, so it pretty much copied the Safari user-agent string and added a &#8220;Chrome&#8221; identifier. Simple browser type detection based on user-agent string meant you would need to look for certain tokens in order:</p>
<ol>
<li>If &#8220;MSIE&#8221; is present, it&#8217;s Internet Explorer.</li>
<li>Else if &#8220;Firefox&#8221; is present, it&#8217;s Firefox.</li>
<li>Else if &#8220;Chrome&#8221; is present, it&#8217;s Chrome.</li>
<li>Else if &#8220;Safari&#8221; is present, it&#8217;s Safari.</li>
<li>Else if &#8220;WebKit&#8221; is present, it&#8217;s a WebKit-based browser.</li>
<li>Else if &#8220;Gecko&#8221; is present, it&#8217;s a Gecko-based browser.</li>
</ol>
<p>So if the Internet Explorer 11 user-agent string is the final one, it causes some interesting logic to happen in this case. In short, by removing &#8220;MSIE&#8221; in favor of &#8220;IE&#8221;, the browser is forcing itself to not be identified as Internet Explorer (step 1). By adding &#8220;like Gecko&#8221; at the end, it is self-selecting into the category of Gecko-based browsers (step 6).</p>
<p>Gecko- and WebKit-based browsers both are considered to have better standards support than Internet Explorer (generally well-deserved prior to IE10), so tricking servers into identifying IE11 as a Gecko-based browser could mean that the browser can handle the same content (JavaScript, CSS) as Firefox. Of course, that&#8217;s usually not the case, especially when it comes to vendor-prefixed functionality. Will IE11 support <code>moz</code>-prefixed functionality?</p>
<p>Is it wise for Internet Explorer 11 to try to hide its identity? I&#8217;m sure in some convoluted way it makes sense based on how web applications are serving up different content based on user-agent strings. I still have hope for a day when user-agent strings reflect the actual browser rather than trying to trick servers into serving the correct content, but for now, this is just a continuation of a long, sad browser user-agent lineage.</p>
<h2>References</h2>
<ol>
<li><a href="http://www.neowin.net/news/ie11-to-appear-as-firefox-to-avoid-legacy-ie-css">IE11 to appear as Firefox to avoid legacy IE CSS</a> (Neowin)</li>
</ol>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=BXH94zSEWB8:C9EjBIQRswo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=BXH94zSEWB8:C9EjBIQRswo:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=BXH94zSEWB8:C9EjBIQRswo:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=BXH94zSEWB8:C9EjBIQRswo:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=BXH94zSEWB8:C9EjBIQRswo:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=BXH94zSEWB8:C9EjBIQRswo:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/BXH94zSEWB8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2013/03/27/internet-explorer-11s-user-agent-string-what-does-it-mean/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://www.nczonline.net/blog/2013/03/27/internet-explorer-11s-user-agent-string-what-does-it-mean/</feedburner:origLink></item>
		<item>
		<title>What kind of a software engineer do you want to be known as?</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/DU3NcpSCy5Q/</link>
		<comments>http://www.nczonline.net/blog/2013/02/26/what-kind-of-a-software-engineer-do-you-want-to-be-known-as/#comments</comments>
		<pubDate>Tue, 26 Feb 2013 15:00:42 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=3332</guid>
		<description><![CDATA[Around this time every year, companies start doing their annual reviews. Coincidentally, software engineers start wondering what their peers and managers will be saying about them. Throughout my career I&#8217;ve always watched as colleagues worried about the results of their annual review. Will they get that promotion? Will they get that raise? Or will they [...]]]></description>
				<content:encoded><![CDATA[<p>Around this time every year, companies start doing their annual reviews. Coincidentally, software engineers start wondering what their peers and managers will be saying about them. Throughout my career I&#8217;ve always watched as colleagues worried about the results of their annual review. Will they get that promotion? Will they get that raise? Or will they be told that they are not performing up to expectations? All of this happens, like clockwork, once a year.</p>
<p>Annual reviews are a reminder that your reputation matters. For most of the year, software engineers don&#8217;t care at all what anybody else thinks as long as they&#8217;re getting the job done. Then annual reviews come along and we realize we might have rubbed some people the wrong way. I know software engineers who year over year always feel like their review is incorrect and unfair (though I&#8217;m sure other occupations have similar issues). What makes it more difficult for software engineers is that we deal so much with code that we sometimes forget how important it is to deal with people. The code isn&#8217;t going to give us a negative review so long as it works. Then again, you&#8217;re expected to write code that works, so your review only ever reflects when you don&#8217;t write code that works.</p>
<p>The rest of the review is based on what people say about you. They are your colleagues and your managers. And you probably didn&#8217;t even stop to think about that until around review time. If you&#8217;ve ever received a review that has been a complete shock to you, that means you didn&#8217;t spend enough time during the year to figure out what kind of the software engineer you want to be known as.</p>
<h2>Never be surprised again</h2>
<p>It&#8217;s been a long time since I had an annual review that surprised me. My last manager even came to expect it from me, as he would usually begin our conversations by saying, &#8220;I&#8217;m pretty sure you know what this is going to say.&#8221; He was right. It was very easy for me to predict what would show up on my annual review for one simple reason: I had already decided what I wanted to show up on the annual review the year before.</p>
<p>This is probably different than the way you&#8217;ve ever thought about annual reviews. Most of the time, you meet with your manager and set goals for the next year, and then your annual review is a checkpoint to see if you achieve those goals. Unfortunately, the goals are typically task oriented such as, &#8220;learn about Node.js&#8221;. It&#8217;s relatively easy to see if you&#8217;ve achieve those goals. What most people never stop and think about is what you would like to see on your annual review next year.</p>
<p>Stop and think about that. Decide right now what it is that you want your annual review to say next year and then take the steps necessary to make that happen. Keep in mind that your annual review typically reflects your reputation in addition to your technical work. The technical work takes care of itself but the reputation piece is one that you must actively work on.</p>
<h2>Your reputation</h2>
<p>Do you have any idea what your reputation at work is right now? If not, ask some colleagues that you trust to tell you how they view you as a coworker. Listen closely for adjectives because that&#8217;s what makes up your reputation. Then decide, is that a reputation that you want? Or is there one that would serve you better? What kind of a software engineer do you want to be known as?</p>
<p>Do you want to be known as the one who always shows up late and in a bad mood? Do you want to be known as the one who happily takes on complex problems? Do you want to be known as the one who smells badly? All of these things are within your control. You can create the reputation that you want for yourself, it just takes a little bit of planning. Everyone has a professional reputation but not everyone takes the steps to actively evolve that reputation. And believe it or not, as you get more experienced, your reputation starts to matter even more than your actual work.</p>
<p>If you stop and think about it, writing code is something that a lot of people do. You can hire someone cheaply out of college to write code and it may not be as good as an experienced software engineer, but if it&#8217;s close enough, that&#8217;s usually all you need. So if your programming acumen is the only thing that you focus on, you aren&#8217;t improving your position in the company. What matters far more are the soft skills that you have along the way. Do people enjoy working with you? Do you add something over and above your coding skill?</p>
<h2>An example</h2>
<p>The last time I stopped and thought about the kind of software engineer I wanted to be known as, I came up with a list of things that I wanted people to say about me on my annual review. These things reflected not necessarily what I was already doing, but what I would aspire to do in the next year. The things I wanted people to say about me on my annual review were:</p>
<ul>
<li>Nicholas is fun to work with.</li>
<li>Nicholas cares about the career development of his peers.</li>
<li>I trust Nicholas to work on important projects.</li>
<li>If Nicholas is working on something, I know that it will get done correctly.</li>
<li>Nicholas is capable of learning new things quickly.</li>
</ul>
<p>This is just a sampling of some of the things I wanted to see on my annual review at different points in time. Note that they all have to do with how others perceive me rather than the quality of the code that I wrote.</p>
<h2>Next steps</h2>
<p>Once you decide what you&#8217;d like to see on your annual review, the next step is to figure out how to make that happen. This is a little bit more difficult than other task-oriented goals because it relies on the opinions of other people. That being said, it&#8217;s certainly not impossible. You just need to stop and think about how your actions affect how other people see you.</p>
<p>Take the example of being fun to work with. Why would people say that about you? Well first and foremost, you have to be reliable. That means showing up on time, completing tasks that are assigned to you, and being a good team member. It&#8217;s not fun to work with someone who is unreliable. Assuming that you are reliable, then &#8220;fun&#8221; is achieved by having good relationships with those on your team. That means talking about things other than work, getting to know people outside of the code they write in the job that they do. It could also mean that you&#8217;re the one who starts Nerf gun wars or helps to plan team activities. The bottom line is that people enjoy working directly with you and would welcome the chance to do it again in the future.</p>
<p>You can take all of your reputation goals and break them down in that way. Almost all of them are reflections on how you interact with other people. As you go through the year, keep an eye out for interactions that run counter to your goals or strengthen them. For example, if you got into an argument with a colleague, how did that argument resolve? Did you both end up feeling resentful  and not wanting to work with the other person? Or were you able to reach an understanding that was mutually beneficial? Any time and interaction doesn&#8217;t quite go smoothly, that&#8217;s a good time to review your reputation goals and see how that interaction affects them.</p>
<h2>Conclusion</h2>
<p>Your reputation as a software engineer matters. It&#8217;s something that you should actively seek to develop throughout your career because that&#8217;s what sets you apart from everyone else who can write the same code that you do. As you get more experienced, your reputation matters more and more, and can be the reason that you either get or miss out on new opportunities. As software engineers, we spend so much time thinking about code that we often neglect personal relationships with our colleagues. Yet our colleagues are the ones who contribute to our annual reviews and ultimately to our success. Watch your interactions with others, try to establish personal relationships with people, and frequently review your reputation goals to see if you&#8217;re on track. Hopefully at this time next year, your annual review won&#8217;t be such a big surprise.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=DU3NcpSCy5Q:g3DuMttHi-M:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=DU3NcpSCy5Q:g3DuMttHi-M:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=DU3NcpSCy5Q:g3DuMttHi-M:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=DU3NcpSCy5Q:g3DuMttHi-M:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=DU3NcpSCy5Q:g3DuMttHi-M:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=DU3NcpSCy5Q:g3DuMttHi-M:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/DU3NcpSCy5Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2013/02/26/what-kind-of-a-software-engineer-do-you-want-to-be-known-as/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		<feedburner:origLink>http://www.nczonline.net/blog/2013/02/26/what-kind-of-a-software-engineer-do-you-want-to-be-known-as/</feedburner:origLink></item>
		<item>
		<title>On joining Box</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/rVrxTwlVgx8/</link>
		<comments>http://www.nczonline.net/blog/2013/02/21/on-joining-box/#comments</comments>
		<pubDate>Thu, 21 Feb 2013 17:47:21 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Front]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=3375</guid>
		<description><![CDATA[I left Yahoo a year and half ago in search of new challenges. I left to chase the dream of startup life with some friends while consulting to pay my bills. I had a lot of fun doing both, starting a new company completely from scratch and getting to work with some awesome companies as [...]]]></description>
				<content:encoded><![CDATA[<p>I left Yahoo a year and half ago in search of new challenges. I left to chase the dream of startup life with some friends while consulting to pay my bills. I had a lot of fun doing both, starting a new company completely from scratch and getting to work with some awesome companies as a consultant. The original plan was for me to do that for three months while we sought funding and then join the startup full time.</p>
<p>As so many startup founders know, the path to success consists of unexpected twists and turns, and rarely does anything go the way you plan. And so 18 months after I planned on consulting for 3 months, I was still consulting. The funding hadn&#8217;t materialized. It was time to for some soul searching.</p>
<p>Truth be told, though I had fun consulting, it left me feeling unfulfilled. I&#8217;ve always enjoyed working on products and never enjoyed hypothetical benchmarking or problem solving. I&#8217;ve always loved learning something really cool while working on a product and then sharing that information with the world. That&#8217;s what I enjoyed most about working at Yahoo, and I knew that was something I wanted again.</p>
<p>Also, I&#8217;ve discovered that my writing and speaking is incredibly important to me. These are more than just adjunct things I do from time to time, they are a vital driving force in my life. I love learning and I love teaching what I&#8217;ve learned to others.</p>
<p>Through a series of random interactions, I came to have a conversation with Sam Schillace at Box. If his name looks familiar, it&#8217;s because he was part of the team that created Writely (ultimately sold to Google and went on to become Google Docs). We had a really good initial conversation and then several followups.</p>
<p>As so often happens, once you know and like someone at a company, you start to consider working there. I did my due diligence and, after chatting a bit more with Sam, decided that Box would be a good fit.</p>
<p>There were a lot of things that attracted me to Box. First, it&#8217;s a small but not tiny company. Before Yahoo, I worked at several companies around this size and always felt that to be my sweet spot. I like working in a place where I can get to know everyone and have a big impact. Second, the company is growing like crazy, so there is a lot of interesting work to do. </p>
<p>But most of all, I&#8217;m excited about helping to define and grow a culture of front-end engineering excellence at Box. I&#8217;ll be working internally to make Box a hub of great front-end engineering practices and will continue to write and give talks (both related directly to Box and not).</p>
<p>I&#8217;m looking forward to this next step in my career and in working with a great group of engineers to make an already kickass product even better. In the short term, I may be a bit quieter than usual as I try to get up to speed at work, but long term you can still expect me to share my thoughts on a regular basis.</p>
<p>For now, I&#8217;ve got work to do.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=rVrxTwlVgx8:49uoewtekPE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=rVrxTwlVgx8:49uoewtekPE:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=rVrxTwlVgx8:49uoewtekPE:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=rVrxTwlVgx8:49uoewtekPE:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=rVrxTwlVgx8:49uoewtekPE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=rVrxTwlVgx8:49uoewtekPE:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/rVrxTwlVgx8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2013/02/21/on-joining-box/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		<feedburner:origLink>http://www.nczonline.net/blog/2013/02/21/on-joining-box/</feedburner:origLink></item>
		<item>
		<title>Making an accessible dialog box</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/3raGWl9wlPU/</link>
		<comments>http://www.nczonline.net/blog/2013/02/12/making-an-accessible-dialog-box/#comments</comments>
		<pubDate>Tue, 12 Feb 2013 15:00:58 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=3362</guid>
		<description><![CDATA[In today&#8217;s web applications, dialog boxes are about as common place as they are in desktop applications. It&#8217;s pretty easy to show or hide an element that is overlayed on the page using a little JavaScript and CSS but few take into account how this affects accessibility. In most cases, it&#8217;s an accessibility disaster. The [...]]]></description>
				<content:encoded><![CDATA[<p>In today&#8217;s web applications, dialog boxes are about as common place as they are in desktop applications. It&#8217;s pretty easy to show or hide an element that is overlayed on the page using a little JavaScript and CSS but few take into account how this affects accessibility. In most cases, it&#8217;s an accessibility disaster. The input focus isn&#8217;t handled correctly and screen readers aren&#8217;t able to tell that something is changed. In reality, it&#8217;s not all that difficult to make a dialog that&#8217;s fully accessible, you just need to understand the importance of a few lines of code.</p>
<h2>ARIA roles</h2>
<p>If you want screen reader users to be aware that a dialog has popped up, then you&#8217;ll need to learn a little bit about Accessible Rich Internet Applications (ARIA) roles. ARIA<sup>[1]</sup> roles supply additional semantic meaning to HTML elements that allow browsers to communicate with screen readers in a more descriptive way. There are a large number of roles that alter the way screen readers perceive different elements on the page. When it comes to dialogs, there are two of interest: <code>dialog</code> and <code>alertdialog</code>.</p>
<p>In most cases, <code>dialog</code> is the role to use. By setting this as the value of the <code>role</code> attribute on an element, you are informing the browser that the purpose of the element is as a dialog box.</p>
<pre><code>&lt;div id="my-dialog" role="dialog"&gt;
    &lt;-- Your dialog code here --&gt;
&lt;/div&gt;
</code></pre>
<p>When an element with a role of <code>dialog</code> is made visible, the browser tells the screen reader that a new dialog has been opened. That lets the screen reader user recognize that they are no longer in the regular flow of the page. </p>
<p>Dialogs are also expected to have labels. You can specify a label using either the <code>aria-label</code> attribute to indicate the label text or the <code>aria-labelledby</code> attribute to indicate the ID of the element that contains the label. Here are a couple of examples:</p>
<pre><code>&lt;div id="my-dialog" role="dialog" aria-label="New Message"&gt;
    &lt;-- Your dialog code here --&gt;
&lt;/div&gt;

&lt;div id="my-dialog" role="dialog" aria-labelledby="dialog-title"&gt;
    &lt;h3 id="dialog-title"&gt;New Message&lt;/h3&gt;
    &lt;-- Your dialog code here --&gt;
&lt;/div&gt;
</code></pre>
<p>In the first example, the <code>aria-label</code> attribute is used to specify a label that is only used by screen readers. You would want to do this when there is no visual label for the dialog. In the second example, the <code>aria-labelledby</code> attribute is used to specify the ID of the element containing the dialog label. Since the dialog has a visual label, it makes sense to reuse that information rather than duplicate it. Screen readers announce the dialog label when the dialog is displayed.</p>
<p>The role of <code>alertdialog</code> is a specialized type of dialog that is designed to get a user&#8217;s attention. Think of this as a confirmation dialog when you try to delete something. An <code>alertdialog</code> has very little interactivity. It&#8217;s primary purpose is to get the user&#8217;s attention so that an action is performed. Compare that to a <code>dialog</code>, which may be an area for the user to enter information, such as writing a new e-mail or instant message.</p>
<p>When an <code>alertdialog</code> is displayed, screen readers look for a description to read. It&#8217;s recommended to use the <code>aria-describedby</code> element to specify which text should be read. Similar to <code>aria-labelledby</code>, this attribute is the ID of an element containing the content to read. If <code>aria-describedby</code> is omitted, then the screen reader will attempt to figure out which text represents the description and will often choose the first piece of text content in the element. Here&#8217;s an example:</p>
<pre><code>&lt;div id="my-dialog" role="alertdialog" aria-describedby="dialog-desc"&gt;
    &lt;p id="dialog-desc"&gt;Are you sure you want to delete this message?&lt;/p&gt;
    &lt;-- Your dialog code here --&gt;
&lt;/div&gt;
</code></pre>
<p>This example uses an element to contain the description. Doing so ensures that the correct text will be read when the dialog is displayed.</p>
<p>Even if you omit the extra attributes and just use the appropriate <code>role</code> for your dialogs, the accessibility of the application improves tremendously.</p>
<h2>Setting focus to the dialog</h2>
<p>The next part of creating an accessible dialog is to manage focus. When a dialog is displayed, the focus should be placed inside of the dialog so users can continue to navigate with the keyboard. Exactly where inside the dialogue focus is set depends largely on the purpose of the dialogue itself. If you have a confirmation dialog with one button to continue in one button to cancel then you may want the default focus to be on the cancel button. If you have a dialog where the user is supposed to enter text, then you may want the focus to be on the text box by default. If you can&#8217;t figure out where to set focus, then a good starting point is to set focus to the element representing the dialog.</p>
<p>Since most of the time you will be using a <code>&lt;div&gt;</code> element to represent a dialog, you can&#8217;t set focus to it by default. Instead, you&#8217;ll need to enable focus on that element by setting the <code>tabIndex</code> property to -1. This allows you to set focus to the element using JavaScript but doesn&#8217;t insert the element into the normal tab order. That means users won&#8217;t be able to press tab to set focus to the dialog. You can either do this directly in HTML or in JavaScript. For HTML:</p>
<pre><code>&lt;div id="my-dialog" role="dialog" tabindex="-1" aria-labelledby="dialog-title"&gt;
    &lt;h3 id="dialog-title"&gt;New Message&lt;/h3&gt;
    &lt;-- Your dialog code here --&gt;
&lt;/div&gt;
</code></pre>
<p>For JavaScript:</p>
<pre><code>var div = document.getElementById("my-dialog");
div.tabIndex = -1;
div.focus();
</code></pre>
<p>Once <code>tabIndex</code> is set to -1, you can call <code>focus()</code> on the element just like any other focusable element. Then the user is able to press tab to navigate within the dialog.</p>
<h2>Trapping focus</h2>
<p>Another accessibility issue with dialogs is making sure that focus doesn&#8217;t go back outside of the dialog. In many cases, a dialog is considered to be modal and therefore focus shouldn&#8217;t be able to escape the dialog. That the dialog is open and pressing tab ends up setting focus behind the dialogue then it&#8217;s incredibly difficult for a keyboard user to get back to the dialogue. So, it&#8217;s best to prevent that from happening by using a little bit of JavaScript.</p>
<p>The basic idea behind this technique is to use event capturing to listen for the <code>focus</code> event, a technique popularized by Peter-Paul Koch<sup>[2]</sup> and now in use by most JavaScript libraries. Since <code>focus</code> doesn&#8217;t bubble, you can&#8217;t capture it on that side of the event flow. Instead, you can intercept all <code>focus</code> events on the page by using event capturing. Then, you need only determine if the element that received focus is in the dialog or not. If not, set the focus back to the dialog. The code is pretty simple:</p>
<pre><code>document.addEventListener("focus", function(event) {

    var dialog = document.getElementById("my-dialog");

    if (dialogOpen &#038;&#038; !dialog.contains(event.target)) {
        event.stopPropagation();
        dialog.focus();
    }

}, true);</code></pre>
<p>This code listens for the <code>focus</code> event on the document so as to intercept all such events before the target element receives them. Assume a <code>dialogOpen</code> variable is set to true when the dialog is open. When a <code>focus</code> event occurs, this function traps the event and checks to see if the dialog is open, and if so, if the element receiving focus is within the dialog. If both conditions are met, then focus is set back to the dialog. This has the effect of looping focus around from the bottom of the dialogue back to the top. The result is that you can&#8217;t tab out of the dialog and so it&#8217;s a lot harder for a keyboard user to get lost.</p>
<p>If you are using a JavaScript library, chances are that it has a way of delegating the <code>focus</code> event in such a way that you can achieve this same effect. If you need to support Internet Explorer 8 and earlier without a JavaScript library, then use the <code>focusin</code> event instead.</p>
<h2>Restoring focus</h2>
<p>The last part of the focus puzzle with dialog has to do with restoring focus to the main part of the page when the dialog is closed. The idea is simple: in order to open the dialog, the user probably activated a link or a button. The focus then shifted into the dialog, where the user accomplish some task and then dismissed the dialog. The focus should move back to the link or button that was clicked to open the dialog so that it&#8217;s possible to continue navigating the page. This is an often overlooked aspect of dialog in web applications, but it makes a huge difference.</p>
<p>As with the other sections, this requires very little code to work. All browsers support <code>document.activeElement</code>, which is the element that currently has focus. All you need to do is query this value before showing the dialog and then set focus back to that element when the dialog is closed. For example:</p>
<pre><code>var lastFocus = document.activeElement,
    dialog = document.getElementById("my-dialog");

dialog.className = "show";
dialog.focus();
</code></pre>
<p>The important part of this code is that it keeps track of the last focused element. That way, all you need to do when the dialog is closed is to set focus back to it:</p>
<pre><code>lastFocus.focus()</code></pre>
<p>In total, this adds to very short lines of code to what you probably have already for your dialog.</p>
<h2>Exiting the dialog</h2>
<p>The very last piece of the puzzle is to allow the user a quick and easy way to exit the dialog. The best way is to have the Esc key close the dialog. This is the way dialogs work in desktop applications and so it&#8217;s very familiar to users. Just listen for the Esc key to be pressed and then exit the dialog, such as:</p>
<pre><code>document.addEventListener("keydown", function(event) {
    if (dialogOpen &#038;&#038; event.keyCode == 27) {
        // close the dialog
    }
}, true);</code></pre>
<p>The <code>keyCode</code> value for the Esc key is 27, so you need only look for that during the <code>keydown</code> event. Once received, close the dialog and set focus back to the previously focused element.</p>
<h2>Conclusion</h2>
<p>As I hope is obvious from this post, it really doesn&#8217;t take a lot of extra code to create a dialog that is easily accessible both by screen readers and those who use only a keyboard. For just a few lines of code you can take your users from being incredibly frustrated to being incredibly happy. There are a lot of web applications out there that use pop-up dialogs but very few get all of these pieces correct. Going halfway leads to more frustration than anything else, so I hope this post has inspired you to make your dialogs as accessible as possible.</p>
<h2>References</h2>
<ol>
<li><a href="http://www.w3.org/WAI/intro/aria.php">WAI-ARIA</a> (W3C)</li>
<li><a href="http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html">Delegating the focus and blur events</a> by Peter-Paul Koch (Quirksmode)</li>
</ol>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=3raGWl9wlPU:6lxxeVWr0dA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=3raGWl9wlPU:6lxxeVWr0dA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=3raGWl9wlPU:6lxxeVWr0dA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=3raGWl9wlPU:6lxxeVWr0dA:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=3raGWl9wlPU:6lxxeVWr0dA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=3raGWl9wlPU:6lxxeVWr0dA:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/3raGWl9wlPU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2013/02/12/making-an-accessible-dialog-box/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		<feedburner:origLink>http://www.nczonline.net/blog/2013/02/12/making-an-accessible-dialog-box/</feedburner:origLink></item>
		<item>
		<title>What technical recruiters can learn from online dating</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/xWM1y6omQHY/</link>
		<comments>http://www.nczonline.net/blog/2013/02/05/what-technical-recruiters-can-learn-from-online-dating/#comments</comments>
		<pubDate>Tue, 05 Feb 2013 15:00:01 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
				<category><![CDATA[Social Interaction]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[Recruiters]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=3348</guid>
		<description><![CDATA[I&#8217;m on LinkedIn just like most people in the tech industry. If you&#8217;re like me, you probably get random messages through LinkedIn from technical recruiters several times a week. Their tactics run the gamut of deliberately ignorant to over-the-top obnoxious and rarely do I feel like I&#8217;m being treated as a human being. After watching [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;m on <a href="http://www.linkedin.com">LinkedIn</a> just like most people in the tech industry. If you&#8217;re like me, you probably get random messages through LinkedIn from technical recruiters several times a week. Their tactics run the gamut of deliberately ignorant to over-the-top obnoxious and rarely do I feel like I&#8217;m being treated as a human being. After watching the behavior of recruiters on LinkedIn (and also in real life), I&#8217;ve come to realize that the problem is very similar to online dating.</p>
<h2>Online dating</h2>
<p>Online dating is basically about supply and demand. There is a supply of single people and they are in demand by other single people. Fair or not, this is frequently set up as women being the supply and the men being the demand. This plays out in real life just as much as an online dating where women get into clubs for free and men have to pay. Men want to go where the women are and so getting the women there first is important.</p>
<p>This was a rude awakening for me the first time I tried online dating. I had been encouraged by a couple of my female friends to sign up and they virtually guaranteed I would be going out on dates immediately. So I filled out my profile and sat back and waited for the e-mails to start flowing in. After a week, without receiving a single e-mail, I wondered what was wrong. After all, they just signed up and immediately were getting 20 or more messages a day. But me? Nothing.</p>
<p>Putting discussions about my desirability or lack thereof aside, what they and I failed to realize is that online dating is a very different experience for men and women. Assuming that a man and a woman are roughly equally attractive and have the same personality, the woman will be contacted far more frequently than the man. In fact, I&#8217;ve heard numerous times from female friends that the day they sign up their inbox is flooded with messages. And no matter how many times I&#8217;ve tried online dating (handful over the past decade), I can go months without receiving a single message. Why is it that women don&#8217;t contact men as much?</p>
<p>The problem is that there is little incentive for women to search for and communicate with men. The demand is coming right to their front door. Surely there is someone worthwhile in the dozens of e-mails waiting in their inbox. Why search for more candidates when resumes are being hand-delivered to you?</p>
<p>Men, on the other hand, have little hope of meeting anyone without actively searching and contacting women. As a man on a dating site, if you sit by and wait for somebody to contact you, you may find weekend after weekend completely free. Additionally, once you do decide to contact women, your message is just one of the dozens that they&#8217;re going to see. </p>
<p>Recruiters on LinkedIn are like the men on online dating sites. They are hoping to meet someone to fill a position, and there are a lot of candidates out there. They need to search for and contact potential candidates in the hopes of getting a response. The problem is made a bit more difficult than online dating because not everyone on LinkedIn is actually looking for a job. Despite that difference, the question is the same: How do you make your message stand out from all the others?</p>
<h2>Strategies</h2>
<p>Men use several strategies for trying to get women to notice and respond to them online. From my female friends, I verified that these are generally the type of messages that they receive. On LinkedIn, if you aren&#8217;t a recruiter then you are the supply (equivalent of the women on an online dating site), so I am actually receiving the type of messages that I imagine women receive on dating sites. The thing I find interesting is that many of the dating site techniques are duplicated by recruiters on LinkedIn. See if any of these sound familiar.</p>
<h3>Copy-paste</h3>
<p>The first is the least amount of effort and also yields the worst return: sending the same message to everyone. You just come up with a really good message that you literally copy and paste into every message that you send to every girl. The plus side of this approach is that you&#8217;re not investing a lot of time and effort into an activity that has a very low rate of return. On the minus side is the fact that generic messages will generally get a lower response rate than personal ones, so the onus is on you to contact much more women in order to make up for that.</p>
<p>Messages of this nature look like the following:</p>
<blockquote><p>Hi there,
</p>
<p>I came across your profile and think we would be a great match! I love to surf and go camping, and I think that we would have a lot of fun together. Hope to hear from you soon.</p>
</blockquote>
<p>The message seems nice enough but you&#8217;ll note that there is nothing personal about it at all.  First, you obviously found the profile otherwise you wouldn&#8217;t be able to send a message, so that doesn&#8217;t really tell you anything. Of course the fact that you&#8217;re writing indicates that you think there is a match. There goes the entire first sentence. The next sentence is just about you and doesn&#8217;t really reveal much. The last sentence is just a way to wrap up the message.</p>
<p>This is also a favorite tool of recruiters. Since LinkedIn fills in the name of the person being contacted, there typically isn&#8217;t a generic greeting as there would be on an online dating site. Still, the basic pattern is the same. Here&#8217;s an actual message I received on LinkedIn from a recruiter:</p>
<blockquote>
<p>Hi Nicholas C., </p>
<p>Our team has reviewed your profile and are very impressed by your skills and experience. </p>
<p>We are working on emerging technologies for our next generation products at [redacted]. We are located in the heart of Palo Alto, CA. Amazing offices, super smart people and financially well funded.</p>
<p>Would you be open to speaking with us?</p>
<p>Thank you in advance for your kind reply.</p>
</blockquote>
<p>If you look closely, this is almost the exact same e-mail tailored to a professional environment. There is absolutely nothing about the message that is specific to me, my skills, or my experience. Here&#8217;s another:</p>
<blockquote><p>Nicholas C.,</p>
<p>I was reading through your background and I wanted to get in touch. I have two opportunities &#8211; one in Palo Alto and one in San Mateo that seem like you would be a fit for. Can you let me know if you are interested in hearing about new opportunities and when might be a good time to chat? </p>
</blockquote>
<p>I&#8217;m not even convinced this person has any idea what I do let alone what I would like to do for my next job.</p>
<h3>Half-hearted</h3>
<p>The half-hearted approach is an evolution of copy-paste. Instead of sending the exact same message to everyone, you just change the first line to be more specific to that person. The entire rest of the message is the same for everybody, so you&#8217;re not putting in a lot of extra effort, and changing the first sentence (the first one that someone reads) may be enough to get them to read the rest.</p>
<p>Messages using this approach tend to look like this:</p>
<blockquote><p>Hi SmartGirl456,</p>
<p>I love the hat in your profile picture, very cool. I love to surf and go camping, and I think that we would have a lot of fun together. Hope to hear from you soon.</p>
</blockquote>
<p>So the greeting is personalized and the first sentence is plausibly personal. The rest of the message is completely generic and obviously the person who wrote it didn&#8217;t want to put much effort into it. Instead of following up with another sentence about hats, the message digresses back into generic boilerplate.</p>
<p>Here&#8217;s an actual message I received on LinkedIn:</p>
<blockquote><p>Hi Nicholas C.,
</p>
<p>I saw your profile and I thought you may be interested in a full time Web Performance Engineer Opening we have in our San-Mateo office.<br />
This position will offer the opportunity to work on software that runs one of the largest distributed systems in the world. You will be an integral part of our aggressive growth strategy for creating highly inventive technology solutions for our customers, driving more and more traffic on the Internet. If you want to work on technology problems that are interesting and challenging, then this is the role for you.
</p>
<p>Please let me know if you are interested in discussing this opportunity in more detail.
</p>
</blockquote>
<p>This is a little bit better. The first sentence at least indicates that this recruiter did a cursory examination of my profile. I do talk about Web performance on my profile, so that first sentence is actually relevant to me. The rest of the message is definitely impersonal and just pasted in. As with the purely copy-paste approach, this one leaves me feeling like the recruiter probably sends a very similar e-mail to dozens of people. Here&#8217;s another:</p>
<blockquote><p>Nicholas &#8211; </p>
<p>Just stumbled on your profile and will first say &#8230; this message is indeed intended to recruit YOU! <img src='http://www.nczonline.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  I tend to be direct &#8230; </p>
<p>I work with Tier-1 VCs and early stage startups and I&#8217;m working with a company in SF that needs a Lead guy like you. They are a great story &#8230; almost profitable and only round of funding. They are going into a major growth phase and need top talent. </p>
<p>Environment is Python, but they don&#8217;t require that experience, even for a lead. They also need JS/HTML5/CSS3 and good, solid *people* on the team. </p>
<p>You interested in discussing?</p>
</blockquote>
<p>The relevant part of this message is the first sentence. I put on my LinkedIn profile that I only want to be contacted by recruiters that are interested in me specifically (and not me or someone I know &#8211; covered later in this post). So he put a personal first sentence and then copied and pasted the rest. There&#8217;s nothing about the rest of the message that&#8217;s unique to me at all.</p>
<h3>Information blast</h3>
<p>This approach encapsulates the attitude that the more you know about me, the more you will like me. So instead of mentioning much about the person you&#8217;re contacting, the approach is to give you a ton of information about the person writing the message. These e-mails tend to be a little bit longer as they act like many profiles. Here&#8217;s an example:</p>
<blockquote><p>Hi there,</p>
<p>Have you found that special someone yet? I haven&#8217;t yet, but I think we might be a good match. I am a recent graduate from business school who just moved to the area from the East Coast. I have a good job and make a good salary. I worked very hard and so when I&#8217;m not at work I like to blow off some steam. I love all outdoor sports but don&#8217;t mind staying in for a quiet evening either.</p>
<p>I noticed you also like outdoor sports, so I think we would have a good time together. If that sounds interesting to you, that I look forward to speaking with you.
</p>
</blockquote>
<p>Well, the person who wrote this message gets high grades for proper grammar and spelling, but not much else. This is probably duplicate information from the person&#8217;s profile which, if the woman was interested, she would probably go and read it anyway. Even though there&#8217;s nothing personal in this message, it has a personal feel to it because the writer is revealing information about himself. The last paragraph is a little bit personal because it mentions something from her profile. However, the likelihood that she got through everything about you (which looks boilerplate) just to get to the one sentence that indicates you&#8217;re writing to her specifically is pretty slim.</p>
<p>Here&#8217;s one from LinkedIn:</p>
<blockquote><p>Hi Nicholas C.,</p>
<p>I came across your profile while looking for folks interested in web development. My name is [redacted] and I&#8217;m part of the early team at [redacted], a funded startup in Berkeley. </p>
<p>We&#8217;re a team of mostly engineers building a discovery service that connects people with entertainment, people and products that appeal specifically to them. Our early tests have been very positive, and we&#8217;re gearing up for a product launch this summer. </p>
<p>We recently raised a new round of funding, and we&#8217;re growing quickly. Our engineering team has a strong passion for building great software, and based on your experience with Yahoo and your book for Wiley I thought you might be interested in hearing more about our team and opportunities for web development roles. </p>
<p>Please let me know if you&#8217;re up for chatting sometime about [redacted].
</p>
</blockquote>
<p>So I get blasted with information about a company I&#8217;ve never heard of before. There is a sentence in the third paragraph that is specific to me and my background, but I never got to that paragraph because the first two were just a blast of information about the company. Here&#8217;s another:</p>
<blockquote><p>Dear Nicholas C., </p>
<p>You are 3 steps from working at [redacted]! Our recruiting process is “fast” just like our [redacted] [URL redacted] check out our products, email me your resume, and let me know which ONE position fits best, when you can begin working onsite in San Francisco OR Sunnyvale, what is your ability to work legally for any employer in the USA, name several times over the next couple of working days when you can be in a quiet place for a 15 minute conversation with me, I will confirm one time via email to confirm</p>
<p>Our Research &#038; Development team is seeking talented system software developers ALL LEVELS, who are strong in C OR C++ OR Python. We are a Linux / Open Source environment and need programmers to create and support new version one products for the cloud.
</p>
</blockquote>
<p>This one is a real gem. Not only is there nothing about me personally in this message, but I&#8217;m blasted with all kinds of information about the company and the recruiting process and then I&#8217;m given a long list of things to do. There&#8217;s nothing in this message that even indicates the recruiter read my profile or has any idea what I do.</p>
<p>Once again, if the recipient of the message either on a dating site or on LinkedIn doesn&#8217;t feel like you were contacting them specifically, you will likely never hear back.</p>
<h3>Or someone you know</h3>
<p>This is actually one that doesn&#8217;t happen on online dating sites but does happen on LinkedIn quite frequently. The reason it doesn&#8217;t happen on dating sites is that everyone knows this isn&#8217;t the way to get a date. The approach is to act coy as if you&#8217;re not interested in the person who you contacted but rather somebody that they might know. Just to show you how silly this is, here&#8217;s what I imagine a message to a woman on a dating site would look like using this approach:</p>
<blockquote><p>Hi SmartGirl456,</p>
<p>I&#8217;m looking for a date this weekend and I was wondering if you or someone you know might want to go out with me? Even if you aren&#8217;t interested, judging by your profile, you probably know some other women who are. Can&#8217;t wait to hear back from you.</p>
</blockquote>
<p>It would be completely preposterous for a man to contact a woman with such a message. Yet, this is incredibly commonplace on LinkedIn. Here&#8217;s one that I received:</p>
<blockquote><p>Hi Nicholas, </p>
<p>I am looking to expand our social web development team at [redacted] and was wondering whether you or someone you may know would be interested in full time or consulting gigs?</p>
</blockquote>
<p>I always suspect that this is a passive aggressive way of asking if I would be interested in the job. As if I would say, &#8220;Actually, why do you want to speak to my friends? I&#8217;m the one that you want!&#8221; Here&#8217;s another:</p>
<blockquote><p>Hello,
</p>
<p>I am reaching out to obviously [sic] for your specific background or if anyone you may know may be interested in 2 great opportunities here in San Francisco. My company, [redacted], is looking for a Sr. PHP Developer/Front End Engineer and UI/UX Designer Developer for a well funded Green/Sustainable emerging technology company for the [redacted]. Please contact me directly or via email. I will of course share all the details and job descriptions with you. They are looking to meet immediately. Best regards for your help. </p>
</blockquote>
<p>This is one of the most insulting type of messages that I&#8217;ve received on LinkedIn. If I ever see &#8220;or someone you know&#8221; in the message, I delete it immediately. I honestly can&#8217;t believe recruiters think that would work.</p>
<h3>Harassment</h3>
<p>Any guy who has spent any amount of time on an online dating site learns pretty quickly that you don&#8217;t get anywhere by e-mailing a woman multiple times. If you e-mail once and she doesn&#8217;t respond, you don&#8217;t send another e-mail asking if she got the previous one. Yes, she got the previous one and she wasn&#8217;t interested, so let it go. Yes, it&#8217;s personal, she doesn&#8217;t like you. She also doesn&#8217;t know you, so who really cares? If you&#8217;re a man on an online dating site, you must accept that this form of passive rejection will happen frequently. You only solidify that you&#8217;re not  someone she&#8217;s interested in by continuing to pester her.</p>
<p>This is a lesson that recruiters don&#8217;t seem to get. When you continue to contact someone who isn&#8217;t interested in talking to you, that&#8217;s harassment. I can&#8217;t tell you how many times I have deleted an e-mail that a recruiter sends only to get a follow-up e-mail in two days asking if I got the previous e-mail. In some cases, I even have received a third e-mail asking if I got the previous two. </p>
<p>I know that in some delusional minds, this might come off as being complementary. Boy, this person thought enough of me to e-mail a second or third time! They must really be interested! But the opposite is true. It tells me that you have no respect for me or my time.</p>
<p>Whether you&#8217;re on a dating site or on LinkedIn, if you contact someone and they don&#8217;t respond, chances are it&#8217;s not because they just didn&#8217;t see your message. You are rejected, let it go.</p>
<h2>What works?</h2>
<p>So after all of that, what actually works? In my various attempts at online dating, the best results that I&#8217;ve ever had were with short, personal messages that showed I had actually read through her profile.  The most important thing is I made the messages about her and not about me. If she&#8217;s interested in me after reading it, she can always go to my profile. So messages such as this tend to go over better:</p>
<blockquote><p>Hi SmartGirl456,</p>
<p>I love that picture of you at Fenway Park! I&#8217;m also from Boston, so I know that this can seem like a strange alternate dimension where sports doesn&#8217;t matter so much. Are you still loyal to the hometown favorites even after seven years?</p>
</blockquote>
<p>Just about the only mention of me is that I&#8217;m also from Boston and that&#8217;s just to provide some context for the next couple of sentences. The message might seem simplistic, but it&#8217;s intensely personal and about her. Every sentence is related to her in some way in the entire message shows that I actually read your profile. I saw her photo and identified where it was taken, I noticed that she was from Boston, and I also noticed that she has been in California for seven years. In short, I approached her as someone who&#8217;s interested in learning more about her to see if we are a match rather than trying to get her to know more about me to see if we&#8217;re a match.</p>
<p>While I haven&#8217;t received a lot of messages that fit this mold, here&#8217;s one that comes close:</p>
<blockquote><p>Hi Nicholas C., </p>
<p>[redacted] is looking for a hands on development manager to lead a team of talented software engineers building a cutting edge, fast and interactive Web application that incorporates the best user experience patterns and technologies available. </p>
<p>As I reviewed your profile it appeared to me that you are particularly suited to define and implement a next generation UI architecture while ensuring continued functionality of the existing system. </p>
<p>I would welcome the opportunity to speak with you soon to discuss the possibility of your joining our team.</p>
<p>You can reach me at [redacted] at any time to get the ball rolling or by emailing me at [redacted]</p>
</blockquote>
<p>While I think the first paragraph isn&#8217;t all that necessary, the second paragraph is really good. It could be tightened up (obviously I know you looked over my profile) but has some really good parts to it. The recruiter clearly you read my profile and understands what&#8217;s important to me. He then explained how I could do that at the company and left it at that. Short, to the point, and personal. If I were actually looking for a job, I would consider replying to this type of message.</p>
<p>Notice that I said I would consider replying to this type of message, not that I would. Whether or not I actually respond has to do with what&#8217;s going on in my life. Do I have any better opportunities that I&#8217;m exploring right now? Do I think the commute is something I can live with? Do I think this is a company I would be happy working for? Writing a good, respectful message gets you into the &#8220;maybe&#8221; pile, just like it does on an online dating site.</p>
<p>If you are a recruiter, here are a bunch of tips that will get you into the &#8220;maybe&#8221; pile:</p>
<ul>
<li><strong>Start by talking about me.</strong> I don&#8217;t really care who you are, you&#8217;re obviously a recruiter for the company that shows up on your profile.  Say something that makes me realize you actually read my profile and understand what I do. Something like, &#8220;I noticed you have an expertise in web interface architecture, and that&#8217;s something [company name] has a need for right now.&#8221;</li>
<li><strong>Tell me a little about the position.</strong> One or two sentences about the position, where it&#8217;s located, what their responsibilities are, and how I would be making an impact. That&#8217;s about all I need to know to figure out if I have any interest.</li>
<li><strong>Provide links about the company and position.</strong> Rather than pasting in boilerplate information to a message, just provide links to the extra information. If you did a good job describing the positions distinctively, I want to go and read a longer job description as well as read more about the company.</li>
<li><strong>Your contact info.</strong> Give me your e-mail address to contact you if I&#8217;m interested. I will not be calling you on the phone so there&#8217;s no need to include your phone number.</li>
</ul>
<p>Just like a message on an online dating site, the goal isn&#8217;t to close the deal. The goal is to get the other person interested enough to want to learn more. Keep your messages short and to the point and make sure that they are personal. It takes a little more time than the other approaches, but you will get a much higher rate of return this way.</p>
<p>I know that there are really good recruiters out there, because I&#8217;m friends with some of them. The problem is that there are so many bad ones that the good ones end up being looped in with them. If you are a recruiter reading this, please take this as advice to help improve yourself. I would much rather get relevant, respectful messages from recruiters even if I&#8217;m not interested at the time then continue to get disrespectful, lazy messages that make me want to never read anything I receive through LinkedIn again.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=xWM1y6omQHY:wYitKtTVR9Y:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=xWM1y6omQHY:wYitKtTVR9Y:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=xWM1y6omQHY:wYitKtTVR9Y:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=xWM1y6omQHY:wYitKtTVR9Y:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=xWM1y6omQHY:wYitKtTVR9Y:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=xWM1y6omQHY:wYitKtTVR9Y:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/xWM1y6omQHY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2013/02/05/what-technical-recruiters-can-learn-from-online-dating/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		<feedburner:origLink>http://www.nczonline.net/blog/2013/02/05/what-technical-recruiters-can-learn-from-online-dating/</feedburner:origLink></item>
		<item>
		<title>You can’t create a button</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/7pdAVheqXBo/</link>
		<comments>http://www.nczonline.net/blog/2013/01/29/you-cant-create-a-button/#comments</comments>
		<pubDate>Tue, 29 Jan 2013 15:00:04 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[ARIA]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=3342</guid>
		<description><![CDATA[One of the most important aspects of accessibility is managing focus and user interaction. By default, all links and form controls can get focus. That allows you to use the tab key to navigate between them and, when one of the elements has focus, activate it by pressing the enter key. This paradigm works amazingly [...]]]></description>
				<content:encoded><![CDATA[<p>One of the most important aspects of accessibility is managing focus and user interaction. By default, all links and form controls can get focus. That allows you to use the tab key to navigate between them and, when one of the elements has focus, activate it by pressing the enter key. This paradigm works amazingly well regardless of the complexity of your web application. As long as a keyboard-only user is able to navigate between links and form controls then it&#8217;s possible to navigate the application.</p>
<p>Unfortunately, sometimes web developers try to get a bit too clever in creating their interfaces. What if I want something to look like a link but act like a button? Then you end up seeing a lot of code that looks like this:</p>
<pre><code>&lt;a href="#" onclick="doSomething()"&gt;I'm a button&lt;/a&gt;</code></pre>
<p>That code should turn your stomach a little bit. It&#8217;s a link that goes nowhere and does nothing. All it does is attach an <code>onclick</code> event handler to give it a purpose. Because the desired appearance for this element currently is link-like, the markup uses a link and JavaScript.</p>
<p>Those who are familiar with ARIA may &#8220;fix&#8221; the problem by using the following:</p>
<pre><code>&lt;a href="#" role="button" onclick="doSomething()"&gt;I'm a button&lt;/a&gt;</code></pre>
<p>By setting the ARIA role to button, you&#8217;re now telling the browser and screen readers that this link should be interpreted as a button (that does an action on the page) rather than a link (that navigates you away). This has the same problem as the previous code except that you&#8217;re trying to trick the browser into treating the link as if it were a button. In reality, it would be most appropriate to just use button:</p>
<pre><code>&lt;button onclick="doSomething()"&gt;I'm a button&lt;/button&gt;</code></pre>
<p>The markup to use should never be based on the appearance of a UI element. Instead, you should try to figure out the real purpose of that element and use the appropriate markup. You can always style button to look like a link or a link to look like a button, but those are purely visual distinctions that don&#8217;t change the action.</p>
<p>If these were the worst sins of web applications that I have seen, I would be pretty happy. However, there is another even more disturbing trend that I&#8217;m seeing. Some Web applications are actually trying to create their own buttons by mixing and matching different parts of HTML, CSS, and JavaScript. Here&#8217;s an example:</p>
<pre><code>&lt;div tabindex="0" role="button" onclick="doSomething()"&gt;I'm a button&lt;/div&gt;</code></pre>
<p>This is a valiant attempt at creating a button out of a <code>&lt;div&gt;</code>. By setting the <code>tabindex</code> attribute, the developer has assured that keyboard users can navigate to it by using the tab key. The value of 0 adds the elements into the normal tab order so it can receive focus just like any other link or button without affecting the overall tabbing order. The <code>role</code> informs the browser and screen readers that this element should be treated as a button and the <code>onclick</code> describes the behavior of the button. </p>
<p>To anyone using a mouse, assuming the styling is correct, there is no distinction between this element and an actual button. You move the mouse over and click down and an action happens. If you&#8217;re using a keyboard, however, there is a subtle but important difference between this and a regular button: almost all browsers will not fire the <code>click</code> event when the element has focus and the enter key is pressed. Internet Explorer, Chrome, Firefox, and Safari all ignore the enter key in this situation (Opera is the only one that fires <code>click</code>). </p>
<p>The enter key fires the <code>click</code> event when used on links and buttons by default. If you try to create your own button, as in the previous example, the enter key has no effect and therefore the user cannot perform that action. </p>
<p>This horrible pattern is found most frequently in Google products. Perhaps the most ironic usage is in Gmail. When you press the ? key, a dialog pops up showing you available keyboard shortcuts and allowing you to enable more advanced shortcuts.  </p>
<p><a href="http://www.nczonline.net/blog/wp-content/uploads/2013/01/gmail.png"><img src="http://www.nczonline.net/blog/wp-content/uploads/2013/01/gmail-300x153.png" alt="Gmail keyboard shortcuts dialog" width="300" height="153" class="alignnone size-medium wp-image-3344" /></a></p>
<p>It looks like the word &#8220;Enable&#8221; is a link, so you press tab a few times to give it focus and press enter. Nothing happens. Why? Because the link is actually  neither a linkage nor a button, it&#8217;s a <code>&lt;span&gt;</code>. Here&#8217;s the actual code:</p>
<pre><code>&lt;span id=":s7.pl" role="link" class="aoy" tabindex="1"&gt;Enable&lt;/span&gt;</code></pre>
<p>Almost exactly the problematic pattern mentioned earlier in this post. So basically in order to turn on keyboard shortcuts you need to be able to use a mouse. In fact, many of the buttons on Gmail are made in this way. If not for the keyboard shortcuts it would basically be unusable without a mouse.</p>
<p>Gmail isn&#8217;t the only Google site that uses this pattern. It can be found throughout the network of Google sites, including Google Groups and Google Analytics (which also hides focus rectangles). This alone makes Google products incredibly challenging to use for sighted users who don&#8217;t use pointing devices.</p>
<p>If you expect the user to interact with something, then you need to use either a link or button. These have the correct behaviors both in terms of getting focus and activating when the enter key is pressed. Links should be used whenever the action is a navigation (changes the URL) and buttons should be used for all other actions. You can easily styled these to create the visual effect that you want, but nothing can replace the  accessibility of the native links and buttons.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=7pdAVheqXBo:5BL0TuSZ7kM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=7pdAVheqXBo:5BL0TuSZ7kM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=7pdAVheqXBo:5BL0TuSZ7kM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=7pdAVheqXBo:5BL0TuSZ7kM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=7pdAVheqXBo:5BL0TuSZ7kM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=7pdAVheqXBo:5BL0TuSZ7kM:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/7pdAVheqXBo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2013/01/29/you-cant-create-a-button/feed/</wfw:commentRss>
		<slash:comments>34</slash:comments>
		<feedburner:origLink>http://www.nczonline.net/blog/2013/01/29/you-cant-create-a-button/</feedburner:origLink></item>
	</channel>
</rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Served from: nczonline.net @ 2013-05-21 09:01:37 -->
