<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>Jonathan T. Neal</title>
	<atom:link href="http://www.jonathantneal.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jonathantneal.com</link>
	<description>They see me codin&#039;.</description>
	<lastBuildDate>Sat, 09 Feb 2013 06:42:03 +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>
		<item>
		<title>Thoughts on Media Queries for Elements</title>
		<link>http://www.jonathantneal.com/blog/thoughts-on-media-queries-for-elements/</link>
		<comments>http://www.jonathantneal.com/blog/thoughts-on-media-queries-for-elements/#comments</comments>
		<pubDate>Thu, 07 Feb 2013 23:10:40 +0000</pubDate>
		<dc:creator>jonathantneal</dc:creator>
				<category><![CDATA[CSS]]></category>

		<guid isPermaLink="false">http://www.jonathantneal.com/?p=472</guid>
		<description><![CDATA[This post was inspired by my friend and co-creator of normalize.css, Nicolas Gallagher. We need native CSS media queries at the element/component/widget level, not just the viewport. Make it so, internetz. &#8212; @necolas So, without any fanfare, I want to ...]]></description>
				<content:encoded><![CDATA[<p>This post was inspired by my friend and co-creator of <a href="http://necolas.github.com/normalize.css/">normalize.css</a>, <a href="http://nicolasgallagher.com/">Nicolas Gallagher</a>.</p>
<blockquote><p>We need native CSS media queries at the element/component/widget level, not just the viewport. Make it so, internetz.<br />
<footer>&mdash; <a href="//twitter.com/necolas/status/299573744307941376">@necolas</a></footer>
</blockquote>
<p>So, without any fanfare, I want to share my thoughts on element media queries, and then open it up for discussion in the comments.</p>
<p><strong>Thought #1: What the Markup Would Be</strong></p>
<p>We would use a <a href="http://www.w3.org/TR/selectors/#selectors">pseudo class</a>, because we are targeting the state of an element. Some examples of pseudo classes are <a href="https://developer.mozilla.org/en-US/docs/CSS/:hover"><code>:hover</code></a>, <a href="https://developer.mozilla.org/en-US/docs/CSS/:focus"><code>:focus</code></a>, and <a href="https://developer.mozilla.org/en-US/docs/CSS/:checked"><code>:checked</code></a>.</p>
<p>We would not use a pseudo element, since we are not targeting a shadow element within the element. Some examples of pseudo elements are <a href="https://developer.mozilla.org/en-US/docs/CSS/::first-letter"><code>::first-letter</code></a>, <a href="https://developer.mozilla.org/en-US/docs/CSS/::before"><code>::before</code></a>, and <a href="https://developer.mozilla.org/en-US/docs/CSS/::after"><code>::after</code></a>. Don&#8217;t be fooled by IE7&#038;8, :before is not the correct syntax. In fact, if you are not supporting IE7&#038;8, you should start using the correct syntax to free yourself of this legacy inconsistency.</p>
<blockquote><p>[The] :: notation is introduced by the current document in order to establish a discrimination between pseudo-classes and pseudo-elements. For compatibility with existing style sheets, user agents must also accept the previous one-colon notation for pseudo-elements introduced in CSS levels 1 and 2 (namely, :first-line, :first-letter, :before and :after).</p>
<footer>&mdash; <a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215/#pseudo-elements">Selectors W3C Working Draft</a></footer>
</blockquote>
<p>We would name the pseudo class <code>media</code> after its predecessor, using parenthesis to wrap the queries, similar to <a href="https://developer.mozilla.org/en-US/docs/CSS/:not"><code>:not</code></a> and <a href="http://www.w3.org/TR/2009/PR-css3-selectors-20091215/#content-selectors"><code>:contains</code></a>.</p>
<pre class="brush: css; title: ; notranslate">
.widget:media(max-width: 30em) {
	color: tomato;
}
</pre>
<p>Multiple queries would require multiple parentheses.</p>
<pre class="brush: css; title: ; notranslate">
.widget:media((max-width: 30em) and (min-width: 30em)) {
	color: bisque;
}
</pre>
<p><strong>Thought #2: How Ems Would Work</strong></p>
<p>The size of an <code>em</code> would be relative to the font size of the element, just as it works with existing CSS values. The <code>rem</code> unit would be used to target the font size of the document.</p>
<pre class="brush: css; title: ; notranslate">
html {
	font-size: 16px;
}

.parent {
	font-size: 12px;
}

.parent &gt; *:media(max-width: 30em) {
	/* applied up to 360px */
} 

.parent &gt; *:media(max-width: 30rem) {
	/* applied up to 480px */
}
</pre>
<p>This brings up an issue with existing media queries. Presently, when we define the font size of <code>html</code> as 12px, does <code>@media (max-width: 30em)</code> evaluate to 360px or 480px? If we believe that @media &#8220;lives&#8221; on the <code>html</code> element, then the answer is 360px. On the other hand, if we believe that @media &#8220;lives&#8221; in some ether beyond <code>html</code>, then the answer is 480px. Sadly, most browsers agree with the later interpretation. Therefore, as a side benefit to this element media queries discussion, we should specify that the size of an em in a <code>@media</code> query should be relative to the font size of the <code>html</code> element.</p>
<p><strong>Thought #3: How Infinite Loops Would Be Handled</strong></p>
<p>Infinite loops would freeze at the offending block. While infinite loops are much more likely to happen with element media queries, this issue has been around since <code>:hover</code>. Therefore, a clear specification would be doubly useful.</p>
<pre class="brush: css; title: ; notranslate">
.widget {
	color: salmon;
	width: 100%;
}

.widget:media(max-width: 320px) {
	color: whitesmoke;
	width: 321px;
} /* the infinite loop is stopped, .widget is whitesmoke with a width of 321px */
</pre>
<p>Similarly, this would address classic CSS looping issues.</p>
<pre class="brush: css; title: ; notranslate">
.widget {
	color: plum;
}

.widget:hover {
	color: orange;
	display: none;
} /* the infinite loop is stopped, .widget is not displayed, but is otherwise orange */
</pre>
<p><strong>Q&#038;A</strong></p>
<blockquote><p>Should element media queries be able to target the page, like <code>.widget:media(page-max-width: 30em)</code> and <code>.widget:media(device-max-width: 30em)</code>?</p></blockquote>
<p>Yes, taking advantage of the syntax like this could really improve the readability of stylesheets. I could imagine a lot of developers preferring these kinds of <code>:media</code> pseudo class queries over traditional <code>@media</code> queries. In fact, a lot of developers are already trying to do things like this with nesting in <a href="http://sass-lang.com/">SASS</a>.</p>
<blockquote><p>Should the number of queries in the <code>:media</code> pseudo class add to the selector weight, so that <code>.widget:media((min-width: 2em) and (max-width: 30em))</code> wins over <code>.widget:media(max-width: 30em)</code>?</p></blockquote>
<p>No, because <code>@media</code> queries are not selectors and therefore do not have any weight. In contrast, <code>*:not(#foo)</code> has more weight than <code>*:not(.foo)</code> because the pseudo class is evaluating selectors, and selectors always add weight. On the other hand, <code>@media (min-width: 5em) and (max-width: 500em)</code> does not have more weight than <code>@media (max-width: 500em)</code>.</p>
<p><strong>Inspirations</strong></p>
<p><a href="//twitter.com/necolas/status/299573744307941376">Necolas&#8217; Tweet</a>, <a href="http://css-tricks.com/specifics-on-css-specificity/">Chris Coyier on CSS Specificity</a>, <a href="https://github.com/jonathantneal/MediaClass">MediaClass</a> (polyfills element media queries), and a great conversation with <a href="http://ln.hixie.ch/">Ian Hickson</a>, who taught me the difference between <code>:</code> and <code>::</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonathantneal.com/blog/thoughts-on-media-queries-for-elements/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Understand the Favicon</title>
		<link>http://www.jonathantneal.com/blog/understand-the-favicon/</link>
		<comments>http://www.jonathantneal.com/blog/understand-the-favicon/#comments</comments>
		<pubDate>Wed, 16 Jan 2013 20:19:21 +0000</pubDate>
		<dc:creator>jonathantneal</dc:creator>
				<category><![CDATA[HTML5]]></category>

		<guid isPermaLink="false">http://www.jonathantneal.com/?p=339</guid>
		<description><![CDATA[When Alec Rust asked the HTML5 Boilerplate project to switch to a HiDPI favicon, I realized how little I knew about favorite icons, touch icons, and tile icons. When I decided to dive in a little deeper, things got interesting. ...]]></description>
				<content:encoded><![CDATA[<p>When <a target="_blank" title="Alec Rust" href="https://twitter.com/AlecRust">Alec Rust</a> asked the <a target="_blank" href="http://html5boilerplate.com/">HTML5 Boilerplate</a> project to <a target="_blank" href="https://github.com/h5bp/html5-boilerplate/issues/1285">switch to a HiDPI favicon</a>, I realized how little I knew about <a target="_blank" href="http://www.w3.org/2005/10/howto-favicon">favorite icons</a>, <a target="_blank" href="http://developer.apple.com/library/ios/#documentation/AppleApplications/Reference/SafariWebContent/ConfiguringWebApplications/ConfiguringWebApplications.html">touch icons</a>, and <a target="_blank" href="http://blogs.msdn.com/b/ie/archive/2012/06/08/high-quality-visuals-for-pinned-sites-in-windows-8.aspx">tile icons</a>. When I decided to dive in a little deeper, things got interesting.</p>
<p>Since they were first introduced by Internet Explorer in 1999, almost nothing about favicons has changed. They have almost-always been <a target="_blank" href="http://en.wikipedia.org/wiki/ICO_(file_format)">ICO files</a>, either nested in the root of the domain as <code>/favicon.ico</code>, or organized by a CMS into a theme or images directory and displayed with:</p>
<pre class="brush: xml; title: ; notranslate">&lt;link rel=&quot;shortcut icon&quot; href=&quot;/path/to/favicon.ico&quot;&gt;</pre>
<p><img alt="16x16 favicon" src="http://www.jonathantneal.com/wp-content/uploads/2013/01/favicon-16.png"> <img alt="32x32 favicon" src="http://www.jonathantneal.com/wp-content/uploads/2013/01/favicon-32.png"></p>
<p>The classic favicon.ico is a 16&#215;16 ICO file, often served in either 16-color or 24bit alpha-transparency format. More recently, favicons have been served as 32&#215;32, which is appropriately scaled down in all major and popular-legacy browsers. In IE10 Metro, the 32&#215;32 icon is used in the address bar.</p>
<p><img alt="IE10 address bar" src="http://www.jonathantneal.com/wp-content/uploads/2013/01/ie10-address-bar.png"></p>
<p>The <strong>rel</strong> attribute of a favicon is a product of evolution. Internet Explorer 5 intended <code>shortcut icon</code> to represent the relationship between the page and the icon, but when <a target="_blank" href="http://tools.ietf.org/html/rfc5988">the specification</a> separated relationships by space, this theoretically created two relationships, <code>shortcut</code> and <code>icon</code>. It wasn&#8217;t until 2010 when the HTML5 specification declared <code>icon</code> alone to be the standard identifier. In non-IE browsers, favicons can be served without the <code>shortcut</code> property.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!-- IE6-10 --&gt;
&lt;link rel=&quot;shortcut icon&quot; href=&quot;path/to/favicon.ico&quot;&gt;

&lt;!-- Everybody else --&gt;
&lt;link rel=&quot;icon&quot; href=&quot;path/to/favicon.ico&quot;&gt;
</pre>
<p>The <strong>type</strong> attribute of a favicon is about as useful as <a target="_blank" href="http://www.w3.org/html/wg/drafts/html/master/scripting-1.html#attr-script-type">the type attribute of a <strong>&lt;script&gt;</strong></a>. As of Janaury 16, 2013, <a target="_blank" href="http://en.wikipedia.org/wiki/Favicon">Wikipedia</a> hints that the <a target="_blank" href="http://en.wikipedia.org/wiki/Favicon#How_to_use">favicon&#8217;s type attribute</a> may effect whether or not Internet Explorer will correctly display it. In reality, Internet Explorer only cares about the server mime for the ICO file, and otherwise ignores the type attribute. The type attribute can be anything, and it can be nothing.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!-- Still works in IE6+ --&gt;
&lt;link rel=&quot;shortcut icon&quot; href=&quot;path/to/favicon.ico&quot; type=&quot;image/vnd.microsoft.icon&quot;&gt;

&lt;!-- Still works in IE6+ --&gt;
&lt;link rel=&quot;shortcut icon&quot; href=&quot;path/to/favicon.ico&quot; type=&quot;image/x-icon&quot;&gt;

&lt;!-- Still works in IE6+ --&gt;
&lt;link rel=&quot;shortcut icon&quot; href=&quot;path/to/favicon.ico&quot;&gt;
</pre>
<blockquote><p>
<img alt="Doctor Happysworth" src="//www.jonathantneal.com/wp-content/uploads/2013/01/happy-doctor.png" class="alignleft"> Good news, everyone! Good browsers can use PNG favicons.</p>
<div style="clear:both;"></div>
</blockquote>
<blockquote><p>
<img alt="Doctor Sadsworth" src="//www.jonathantneal.com/wp-content/uploads/2013/01/sad-doctor.png" class="alignleft"> Bad news, everyone! Chrome and Safari will use the ICO favicons anyway.</p>
<div style="clear:both;"></div>
</blockquote>
<p>This really depresses me, because Chrome, Firefox, Opera 7+, and Safari 4+ all accept the PNG favicon, but Chrome and Safari will opt to use the ICO favicon when both are presented, regardless of the order in which they are declared. On the other hand, Internet Explorer does not support PNG favicons, but it will ignore the PNG favicon and use the ICO favicon, regardless of the order in which they are declared.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!-- Chrome, Safari, IE --&gt;
&lt;link rel=&quot;shortcut icon&quot; href=&quot;path/to/favicon.ico&quot;&gt;

&lt;!-- Firefox, Opera (Chrome and Safari say thanks but no thanks) --&gt;
&lt;link rel=&quot;icon&quot; href=&quot;path/to/favicon.png&quot;&gt;
</pre>
<p>Since PNG favicon files do not include multiple resolutions like ICO favicons, we can write out several favicon declarations and use the <strong>sizes</strong> attribute to target each resolution.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;link rel=&quot;icon&quot; href=&quot;favicon-16.png&quot; sizes=&quot;16x16&quot;&gt;
&lt;link rel=&quot;icon&quot; href=&quot;favicon-32.png&quot; sizes=&quot;32x32&quot;&gt;
&lt;link rel=&quot;icon&quot; href=&quot;favicon-48.png&quot; sizes=&quot;48x48&quot;&gt;
&lt;link rel=&quot;icon&quot; href=&quot;favicon-64.png&quot; sizes=&quot;64x64&quot;&gt;
&lt;link rel=&quot;icon&quot; href=&quot;favicon-128.png&quot; sizes=&quot;128x128&quot;&gt;
</pre>
<p>How do these PNG-favicon-compatible browsers determine which favicon should be used? Firefox and Safari will use the favicon that comes last. Chrome for Mac will use whichever favicon is ICO formatted, otherwise the 32&#215;32 favicon. Chrome for Windows will use the favicon that comes first if it is 16&#215;16, otherwise the ICO. If none of the aforementioned options are available, both Chromes will use whichever favicon comes first, exactly the opposite of Firefox and Safari. Indeed, Chrome for Mac will ignore the 16&#215;16 favicon and use the 32&#215;32 version if only to scale it back down to 16&#215;16 on non-retina devices. Opera, not wanting to take sides, will choose from any of the available icons at complete random. I love that Opera does this.</p>
<p>And that&#8217;s just the beginning. Now it&#8217;s time to learn about the Internet Explorer caveats.</p>
<p><img alt="IE can be a troll" src="http://i.imgur.com/lqIAj.jpg" class="alignleft" style="max-width:100px;"> While IE8-10 will display the favicon on first load of the page, IE7 will skip the first load and display the favicon during repeat visits. Worse yet, IE6 will only display the favicon once the site has been bookmarked and reopened in the browser. IE6 will also drop the favicon whenever the browser cache is cleared, and it will not display the favicon again until the site is either re-bookmarked, or the favicon is somehow reloaded. If IE6 and favicons mean a lot to you, you can force this reload with a little JavaScript snippet, preferably wrapped in a conditional comment.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!-- I &quot;support&quot; IE6 --&gt;
&lt;!--[if IE 6]&gt;&lt;script&gt;(new Image).src=&quot;path/to/favicon.ico&quot;&lt;/script&gt;&lt;![endif]--&gt;
</pre>
<p><a target="_blank" href="http://jonneal.bandcamp.com/track/bye-bye-hacker"><img alt="IE is hacked" src="http://i.imgur.com/YVKiF.png" style="max-width:100%;"></a></p>
<hr />
<p>Back to <strong>HiDPI</strong>; have you asked yourself this question yet?</p>
<blockquote><p><i>If all good browsers support PNG favicons, and IE browsers need ICO favicons, but ICO favicons throw off Chrome and Safari, why not wrap the ICO favicon in IE conditional commments?</i></p></blockquote>
<p>That is a great question, and it leads to a great idea. PNG files are a fraction the size of ICO files. We could serve a classic 32&#215;32 ICO favicon to IE, and a super sleek 96&#215;96 PNG favicon to everybody else.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!-- Just IE? --&gt;
&lt;!--[if IE]&gt;&lt;link rel=&quot;shortcut icon&quot; href=&quot;path/to/favicon.ico&quot;&gt;&lt;![endif]--&gt;

&lt;!-- Everybody else? --&gt;
&lt;link rel=&quot;icon&quot; href=&quot;path/to/favicon.png&quot;&gt;
</pre>
<p>One. Big. Problem. <a target="_blank" href="http://www.sitepoint.com/microsoft-drop-ie10-conditional-comments/">IE10 <strong>does not</strong> support conditional comments</a>, <em>and</em> it <strong>does not</strong> support PNG favicons. Yes, with the code above, legacy IE would get a better experience than Microsoft&#8217;s brightest flagship.</p>
<blockquote><p><i>Hey, hey &mdash; what if we stick the ICO favicon in the root directory and use <code>&lt;link rel="icon"&gt;</code> to assign the PNG favicon?</i></p></blockquote>
<p>You. Win. The Internet! Given the limitations of Chrome, Safari, and IE, this method will give every browser the best favicon experience. IE will ignore the <code>&lt;link rel="icon"&gt;</code> and use the ICO favicon found in the root of the domain as <code>/favicon.ico</code>. All other browsers will use the PNG favicon displayed with:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;link rel=&quot;icon&quot; href=&quot;path/to/favicon.png&quot;&gt;
</pre>
<blockquote><p><i>But what if I want multiple favicons or my CMS doesn&#8217;t like to do things this way? Is there &#8230; another way?</i></p></blockquote>
<p>Yea, but you&#8217;re not gonna like it.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!-- I &quot;support&quot; IE --&gt;
&lt;script&gt;
navigator.appName == &quot;Microsoft Internet Explorer&quot; &amp;&amp; (function (i, d, s, l) {
	i.src = &quot;favicon.ico&quot;;
	s = d.getElementsByTagName(&quot;script&quot;)[0];
	l = s.parentNode.insertBefore(d.createElement(&quot;link&quot;), s);
	l.rel = &quot;shortcut icon&quot;;
	l.href = i.src;
})(new Image, document);
&lt;/script&gt;

&lt;!-- Everybody else --&gt;
&lt;link rel=&quot;icon&quot; href=&quot;path/to/favicon.png&quot;&gt;
</pre>
<p>Unsatisfied with either solution? All is not lost. IE10 users are mostly Windows 8 users <a target="_blank" href="http://windows.microsoft.com/en-US/internet-explorer/ie-10-release-preview">for now</a>, and Windows 8 introduces a new kind of display icon for websites &mdash; <strong>tile icons</strong>.</p>
<p><img alt="Tile Icon" src="http://www.jonathantneal.com/wp-content/uploads/2013/01/tile-icon.png"></p>
<p>With IE10 Metro we can display a unique tile icon when the visitor <em>pins</em> our site to their Start screen. These tile icons are 144&#215;144 PNG files, and for best results they use a transparent background. A background tile color can be specified using a hex RGB color (using the six-character #RRGGBB notation), a CSS color name, or the CSS rgb() function. The markup is pretty simple.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;meta name=&quot;msapplication-TileColor&quot; content=&quot;#D83434&quot;&gt;
&lt;meta name=&quot;msapplication-TileImage&quot; content=&quot;path/to/tileicon.png&quot;&gt;
</pre>
<p><img alt="Pinning with a Tile Icon" src="http://www.jonathantneal.com/wp-content/uploads/2013/01/tile-icon-pinnning.png"></p>
<p>Okay, so let&#8217;s put it all together, accepting the potential limitation of IE10, and keeping the sane parts of everything else.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;link rel=&quot;apple-touch-icon&quot; href=&quot;path/to/touchicon.png&quot;&gt;
&lt;link rel=&quot;icon&quot; href=&quot;path/to/favicon.png&quot;&gt;
&lt;!--[if IE]&gt;&lt;link rel=&quot;shortcut icon&quot; href=&quot;path/to/favicon.ico&quot;&gt;&lt;![endif]--&gt;
&lt;!-- or, set /favicon.ico for IE10 win --&gt;
&lt;meta name=&quot;msapplication-TileColor&quot; content=&quot;#D83434&quot;&gt;
&lt;meta name=&quot;msapplication-TileImage&quot; content=&quot;path/to/tileicon.png&quot;&gt;
</pre>
<p>It&#8217;s a start, at least.</p>
<p>If you want to learn more about creating favicons, I recommend <a target="_blank" href="http://www.netmagazine.com/features/create-perfect-favicon">Create the perfect favicon</a> from Jon Hicks&#8217; <a target="_blank" href="http://www.fivesimplesteps.com/products/the-icon-handbook">The Icon Handbook</a>, and <a target="_blank" href="http://snook.ca/archives/design/making_a_good_favicon">Making a good favicon</a> by Jonathan Snook. Also, I want to thank <a target="_blank" href="//twitter.com/alrra">@alrra</a> for telling me about tile icons.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonathantneal.com/blog/understand-the-favicon/feed/</wfw:commentRss>
		<slash:comments>91</slash:comments>
		</item>
		<item>
		<title>The HTML5 Invoice</title>
		<link>http://www.jonathantneal.com/blog/the-html5-invoice/</link>
		<comments>http://www.jonathantneal.com/blog/the-html5-invoice/#comments</comments>
		<pubDate>Mon, 25 Jun 2012 19:16:31 +0000</pubDate>
		<dc:creator>jonathantneal</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.jonathantneal.com/?p=274</guid>
		<description><![CDATA[One of my favorite developers to follow is Chris Coyier. His posts and tutorials at CSS-Tricks are a delight to read. Of his many innovations, one of my favorite is the handy, lightweight HTML Invoice. After using it myself, I ...]]></description>
				<content:encoded><![CDATA[<p>One of my favorite developers to follow is <a href="https://twitter.com/chriscoyier">Chris Coyier</a>. His posts and tutorials at <a href="http://css-tricks.com/">CSS-Tricks</a> are a delight to read. Of his many innovations, one of my favorite is the handy, lightweight <a href="http://css-tricks.com/html-invoice/">HTML Invoice</a>. After using it myself, I thought I would share my own tribute to his work.</p>
<p>So here it is, <a href="/examples/invoice/">HTML5 Invoice</a>, a tool that helps you create invoices on the fly, anywhere, without any additional software. Pages are printed perfectly to 8.5&#215;11 standard sheets.</p>
<p><img src="/wp-content/uploads/2012/06/invoice-ratio.png" alt="Invoice" title="Invoice" style="border: 1px solid #CCC; border-radius: 6px;"></p>
<p>The output is precise. The CSS <code>-webkit-print-color-adjust</code> property is used to ensure the print is exactly what one would expect. The <code>@page</code> rule is used to normalize margins across printers. The markup is short and sweet. Validators, lifeless or living can appreciate the semantic usage of old and new HTML elements. The page is easily and fully customizable. Content editable is employed to update labels and values as the balance calculations refresh and beautify themselves through JavaScript. Branding can be modified with a click on the picture, or my simply dragging and dropping a new one onto the existing image.</p>
<p><a href="/examples/invoice/">Use it now</a>, or <a href="/examples/invoice/invoice.zip">download the source</a> to give it a new style.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonathantneal.com/blog/the-html5-invoice/feed/</wfw:commentRss>
		<slash:comments>49</slash:comments>
		</item>
		<item>
		<title>Simple Stacks and Panels</title>
		<link>http://www.jonathantneal.com/blog/simple-stacks-and-panels/</link>
		<comments>http://www.jonathantneal.com/blog/simple-stacks-and-panels/#comments</comments>
		<pubDate>Thu, 21 Jun 2012 10:00:43 +0000</pubDate>
		<dc:creator>jonathantneal</dc:creator>
				<category><![CDATA[CSS]]></category>

		<guid isPermaLink="false">http://www.jonathantneal.com/?p=199</guid>
		<description><![CDATA[Layout frameworks should be simple, not complicated. The CSS and HTML source should be concise, yet compact. The selector chains should be shallow or non-existant. Naming conventions, clear and conformed. We should step back, relax, and consider how easy it ...]]></description>
				<content:encoded><![CDATA[<p>Layout frameworks should be simple, not complicated. The CSS and HTML source should be concise, yet compact. The selector chains should be shallow or non-existant. Naming conventions, clear and conformed.</p>
<p>We should step back, relax, and consider how easy it should be. Here is everything you need to start building elegant layouts.</p>
<pre class="brush: css; title: ; notranslate">
.stack, .panel { display: inline-block; vertical-align: top; width: 100%; }
.stack { font-size: 0; text-align: justify; }
.stack:after { content: &quot;&quot;; display: inline-block; width: 100%; }
.panel { font-size: 16px; font-size: 1rem; text-align: left; }
</pre>
<p>And here is everything you need to use them.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;div class=&quot;stack s1&quot;&gt;
	&lt;div class=&quot;panel p1&quot;&gt;&lt;/div&gt;
	&lt;div class=&quot;stack s2&quot;&gt;
		&lt;div class=&quot;panel p2&quot;&gt;&lt;/div&gt;
		&lt;div class=&quot;panel p3&quot;&gt;&lt;/div&gt;
		&lt;div class=&quot;panel p4&quot;&gt;&lt;/div&gt;
	&lt;/div&gt;
	&lt;div class=&quot;panel p5&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
</pre>
<p>Just create a stack and add panels to it. If you want, you can add stacks inside stacks too. Layouts are as mild or as flexible as you need them to be. Panels snap to the left and right sides perfectly. Every stack and panel can be styled individually, using small, readable classnames. Responsive designs are a breeze.</p>
<pre class="brush: css; title: ; notranslate">
/* Default / Tablet Portrait View */

.p2, .p3, .p4 { width: 33.3333%; }

/* Handheld Portrait View */

@media screen and (max-width: 479px) {
	.stack, .panel { width: 100%; }
}

/* Handheld Landscape View */

@media screen and (min-width: 480px) and (max-width: 719px) {
	.stack, .panel { width: 100%; }
	.p2, .p3 { width: 50%; }
}

/* Tablet Landscape / Desktop View */

@media screen and (min-width: 960px) {
	.stack, .panel { width: 100%; }
	.s1 { max-width: 1200px; }
	.p1, .s2 { width: 50%; }
	.p2 { width: 66.6665%; }
	.p3 { width: 33.3333%; }
}
</pre>
<p><iframe id="fiddle1" style="border-bottom: 1px solid #CCC; width: 100%; height: 300px" src="http://jsfiddle.net/tEDrV/7/embedded/result/" allowfullscreen="allowfullscreen" frameborder="0"></iframe></p>
<p style="font-size:80%;margin-top:-2em;text-align:right;"><a href="http://jsfiddle.net/tEDrV/7/">Open in JSFiddle</a></p>
<p>Support is superb. This technique will work in Opera 9+, Firefox 3+, Safari 5+, Chrome 4+, and IE8+. IE6 &#038; IE7 support is available for the price of a couple lines of unsightly CSS.</p>
<pre class="brush: css; title: ; notranslate">
.stack, .panel { *display: inline; *zoom: 1; } .iestack { *letter-spacing: -10px; } .iestack .panel { *letter-spacing: 0; }
.stack { *-ms-stack: expression(this.firstChild.className!=&quot;iestack&quot;&amp;amp;&amp;amp;this.appendChild((function(c,e,i){e.className=&quot;iestack&quot;;while(c.length)e.appendChild(c[0]);return e})(this.childNodes,document.createElement(&quot;div&quot;),0))); }
</pre>
<p>Need <a href="http://960.gs/">Nine-Sixty</a> layouts? No problem.</p>
<pre class="brush: css; title: ; notranslate">
/* Default / Tablet Portrait View */

.stack, .panel { width: 720px; }

.p2, .p3, .p4 { width: 240px; }

/* Handheld Portrait View */

@media screen and (max-width: 479px) {
	.stack, .panel { width: 320px; }
}

/* Handheld Landscape View */

@media screen and (min-width: 480px) and (max-width: 719px) {
	.stack, .panel { width: 480px; }
	.p2, .p3 { width: 240px; }
}

/* Tablet Landscape / Desktop View */

@media screen and (min-width: 960px) {
	.stack, .panel { width: 960px; }
	.p1, .s2, .p4 { width: 480px; }
	.p2, .p3 { width: 240px; }
}
</pre>
<p><iframe id="fiddle1" style="border-bottom: 1px solid #CCC; width: 100%; height: 300px;" src="http://jsfiddle.net/555Ye/3/embedded/result/" allowfullscreen="allowfullscreen" frameborder="0"></iframe></p>
<p style="font-size:80%;margin-top:-2em;text-align:right;"><a href="http://jsfiddle.net/555Ye/3/">Open in JSFiddle</a></p>
<p>Have fun. Build. Here&#8217;s a refresher on the conventions.</p>
<dl>
<dt>Stack</dt>
<dd>A container of panels and other stacks.</dd>
<dt>Panel</dt>
<dd>A container of anything else.</dd>
<dt>sX</dt>
<dd>A unique class for each stack. <strong>s</strong> stands for Stack. <strong>X</strong> can be anything.</dd>
<dt>pX</dt>
<dd>A unique class for each panel. <strong>p</strong> stands for Panel. <strong>X</strong> can be anything.</dd>
</dl>
]]></content:encoded>
			<wfw:commentRss>http://www.jonathantneal.com/blog/simple-stacks-and-panels/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Faking the Future</title>
		<link>http://www.jonathantneal.com/blog/faking-the-future/</link>
		<comments>http://www.jonathantneal.com/blog/faking-the-future/#comments</comments>
		<pubDate>Wed, 20 Jun 2012 10:00:13 +0000</pubDate>
		<dc:creator>jonathantneal</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.jonathantneal.com/?p=134</guid>
		<description><![CDATA[Ah, querySelector, the native answer to the best part of jQuery, or rather Sizzle.querySelector returns the first matching element descended from the element on which it is used. When used as querySelectorAll, it returns the entire list of matching descendant ...]]></description>
				<content:encoded><![CDATA[<p>Ah, <code>querySelector</code>, the native answer to the best part of <a href="http://jquery.com/">jQuery</a>, or rather <a href="http://sizzlejs.com/">Sizzle</a>.<code>querySelector</code> returns the first matching element descended from the element on which it is used. When used as <code>querySelectorAll</code>, it returns the entire list of matching descendant elements. It is elegant, and yet so useful. It&#8217;s proof that JavaScript just keeps getting better and better.</p>
<pre class="brush: jscript; title: ; notranslate">
document.getElementsByTagName('h1')[0]; // the old way

document.querySelector('h1'); // the new way

someElement.getElementsByClassName('foo'); // the old way, which never worked until IE9

someElement.querySelectorAll('.foo'); // the new way, which even works in IE8
</pre>
<aside>Regarding <code>querySelector</code> performance: <code>getElementsByTagName</code> appears <a href="http://jsperf.com/queryselectorall-vs-getelementsbytagname#bs-results">lightyears faster</a> because it returns a dynamic <code>NodeList</code>, effectively an empty object. Once the NodeList is actually used, speeds becomes <a href="http://jsperf.com/queryselectorall-vs-getelementsbytagname/26#bs-results">very comparable</a>.</aside>
<p>What bums me out about <code>querySelector</code> is that it implies some other APIs that are missing. For example, if we wanted to check whether an element is matched by a selector, we would use <code>matchesSelector</code>. That kind of functionality would be especially useful in event delegation where the returning target is unknown. Unfortunately, <code>matchesSelector</code> is unavailable in IE8, Safari 4, and, as of mid-2012 <a href="http://caniuse.com/matchesselector">exclusively vendor prefixed</a> while the <a href="http://dev.w3.org/2006/webapi/selectors-api2/#matchtesting">Selectors API 2</a> remains a draft.</p>
<pre class="brush: jscript; title: ; notranslate">
document.addEventListener('click', function (e) {
	var matches = e.target.matchesSelector('a[rel=&quot;external&quot;]'); // doesn't work anywhere in 2012.

	if (matches) {
		// cancel the default action
		e.preventDefault();

		// do something special, like open the anchor in a new window
		open(e.target, '_blank');
	}

	// (moz|ms|o|webkit)MatchesSelector all work though.
});
</pre>
<p>One way around this almost-standard API is to <a href="http://www.jonathantneal.com/blog/polyfills-and-prototypes/">polyfill</a> the eventual implementation with either the vendor version or something original. This is faking the future.</p>
<pre class="brush: jscript; title: ; notranslate">
this.Element &amp;&amp; (function (ElementPrototype) {
	ElementPrototype.matchesSelector = ElementPrototype.matchesSelector ||
	ElementPrototype.mozMatchesSelector ||
	ElementPrototype.msMatchesSelector ||
	ElementPrototype.oMatchesSelector ||
	ElementPrototype.webkitMatchesSelector ||
	function matchesSelector(selector) {
		var
		results = this.parentNode.querySelectorAll(selector),
		resultsIndex = -1;

		while (results[++resultsIndex] &amp;&amp; results[resultsIndex] != this) {}

		return !!results[resultsIndex];
	};
})(Element.prototype);
</pre>
<aside><strong>UPDATE:</strong>: A previous version of this article used <code>Array.prototype.indexOf</code>, to polyfill <code>matchesSelector</code> which was then also polyfilled for Internet Explorer 8. Unfortunately, doing this would make <code>indexOf</code> enumerable on all arrays, and that would be super annoying.</aside>
<p>With <code>matchesSelector</code> polyfilled, we can check whether an element matches a selector. Using <code>querySelector</code> we can return a descendant matching a selector. Now, what if we wanted to get an ancestor that matched a selector, similar to jQuery&#8217;s <a href="http://api.jquery.com/closest/"><code>closest()</code></a> method? we would need an <code>ancestorQuerySelector</code> method. <code>ancestorQuerySelector</code> would return the first matching ancestor of the element on which it is used. When used as <code>ancestorQuerySelectorAll</code>, it would return the entire list of matching ancestor elements.</p>
<pre class="brush: jscript; title: ; notranslate">
document.addEventListener('click', function (e) {
	var
	// set the selector
	selector = 'a[rel=&quot;external&quot;]',

	// get the closest matching element
	closestElement = e.target.matchesSelector(selector) ? e.target : e.target.ancestorQuerySelector(selector);

	if (closestElement) {
		// cancel the default action
		e.preventDefault();

		// do something special, like open the anchor in a new window
		open(e.target, '_blank');
	}
});
</pre>
<p>Unfortunately, <code>ancestorQuerySelector</code> doesn&#8217;t have a native implementation in any browser. So, if we were to add it? And what if we were to check for native or vendor-prefixed functionality first? Is that still polyfilling? Can a developer make such a suggestion without writing a selector draft? Are we faking the future or fauxing the future?</p>
<pre class="brush: jscript; title: ; notranslate">
this.Element &amp;&amp; (function (ElementPrototype, polyfill) {
	function NodeList() { [polyfill] }
	NodeList.prototype.length = ArrayPrototype.length;

	ElementPrototype.ancestorQuerySelectorAll = ElementPrototype.ancestorQuerySelectorAll ||
	ElementPrototype.mozAncestorQuerySelectorAll ||
	ElementPrototype.msAncestorQuerySelectorAll ||
	ElementPrototype.oAncestorQuerySelectorAll ||
	ElementPrototype.webkitAncestorQuerySelectorAll ||
	function ancestorQuerySelectorAll(selector) {
		for (var cite = this, newNodeList = new NodeList; cite = cite.parentElement;) {
			if (cite.matchesSelector(selector)) ArrayPrototype.push.call(newNodeList, cite);
		}

		return newNodeList;
	};

	ElementPrototype.ancestorQuerySelector = ElementPrototype.ancestorQuerySelector ||
	ElementPrototype.mozAncestorQuerySelector ||
	ElementPrototype.msAncestorQuerySelector ||
	ElementPrototype.oAncestorQuerySelector ||
	ElementPrototype.webkitAncestorQuerySelector ||
	function ancestorQuerySelector(selector) {
		return this.ancestorQuerySelectorAll(selector)[0] || null;
	};
})(Element.prototype);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.jonathantneal.com/blog/faking-the-future/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A Close Shiv</title>
		<link>http://www.jonathantneal.com/blog/a-close-shiv/</link>
		<comments>http://www.jonathantneal.com/blog/a-close-shiv/#comments</comments>
		<pubDate>Tue, 19 Jun 2012 10:00:07 +0000</pubDate>
		<dc:creator>jonathantneal</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.jonathantneal.com/?p=62</guid>
		<description><![CDATA[As some history books of the www read, I am more than a little obsessed with the legacy of HTML5, particularly with the legacy browsers. The fixation runs deep, and I find my lamentations becoming songs about Internet Explorer 6. Most of ...]]></description>
				<content:encoded><![CDATA[<p>As some <a href="http://paulirish.com/2011/the-history-of-the-html5-shiv/">history books of the www</a> read, I am more than a little obsessed with the legacy of HTML5, particularly with the legacy <em>browsers</em>. The fixation runs deep, and I find my lamentations becoming <a href="http://jonneal.bandcamp.com/track/ie6">songs about Internet Explorer 6</a>. Most of my real contributions to HTML5 &#8220;legacy&#8221; have landed themselves in a script known as <a href="http://code.google.com/p/html5shiv/">HTML5Shiv</a>, maintained by <a href="https://github.com/aFarkas">Alexander Farkas</a>, <a href="https://twitter.com/jdalton">John-David Dalton</a>, and myself.</p>
<p>A shiv works by running the <code>createElement</code> method on a document, which, in IE, triggers support for the element in the document tree.</p>
<pre class="brush: jscript; title: ; notranslate">
document.body.innerHTML = 'Mark &lt;mark&gt;my words&lt;/mark&gt;.'; // &lt;mark&gt; fails to render correctly.
document.createElement('mark'); // shivs &lt;mark&gt;.
document.body.innerHTML = 'Mark &lt;mark&gt;my words&lt;/mark&gt;.'; // &lt;mark&gt; renders correctly.
</pre>
<p>Of course, not all HTML is added directly to the document. Many times, HTML is added to detached elements, which also must be shivved.</p>
<pre class="brush: jscript; title: ; notranslate">
document.createElement('mark'); // shivs &lt;mark&gt;

var p = document.createElement('p');
p.innerHTML = 'Mark &lt;mark&gt;my words&lt;/mark&gt;.'; // &lt;mark&gt; fails to render correctly.
p.document.createElement('mark'); // shivs &lt;mark&gt; on &lt;p&gt;'s internal document.
p.innerHTML = 'Mark &lt;mark&gt;my words&lt;/mark&gt;.'; // &lt;mark&gt; renders correctly.
</pre>
<p>The work adds up, and HTML5Shiv handles all of this.  HTML5Shiv enables Internet Explorer to properly render about 23 HTML5 sectioning elements, providing default styles for them and ensuring that they print successfully.</p>
<p>HTML5Shiv has been integrated into almost every CMS and JavaScript DOM library out there. That&#8217;s not surprising, considering that <a href="http://www.binvisions.com/articles/how-many-percentage-web-sites-using-html5/">30% of the popular web</a> is using HTML5 despite Internet Explorer 6, 7, and 8 <a href="http://html5doctor.com/how-to-get-html5-working-in-ie-and-firefox-2/">completely disregarding HTML5 elements</a>. The situation is compounded by IE&#8217;s 20%-50% browser market share, depending upon who is asked. These statistics do not change one imperative reality: HTML5Shiv is a surrogate, a crutch, destined to wither away with each passing of Internet Explorer, until the day it accompanies IE8 into the sunset, and flights of angels sing them to their rest.</p>
<p>For developers, desperate to drop any and all of these old<strong><em>ie</em></strong>s, the time ticks too slowly.  But now, <a href="http://www.computerworld.com/s/article/9217279/Google_to_dump_support_for_Microsoft_s_IE7">Google</a>,  <a href="http://thenextweb.com/facebook/2011/12/30/not-a-fan-of-timeline-on-facebook-use-ie7-facebook-stopped-supporting-it/">Facebook</a>, and even <a href="http://windowsteamblog.com/ie/b/ie/archive/2011/12/15/ie-to-start-automatic-upgrades-across-windows-xp-windows-vista-and-windows-7.aspx">Microsoft</a> have made heavy-handed moves to raise the bar of browser expectations. They are dropping support for IE6 and IE7, and leaving IE8 as the new low in browser compatibility.  With this change, the browser compatibility clock is moved forward 8 years.</p>
<p>In a world where IE6 and IE7 step aside, IE8 would then offer new approaches to the same HTML5 incompatibilities. One approach would be to drop the list of sectioning elements in lieu of a defineProperty listener, hijacking the innerHTML setter, and shivving support for new elements responsively.</p>
<pre class="brush: jscript; title: ; notranslate">
document.documentMode == 8 &amp;&amp; this.Element &amp;&amp; (function (document, innerHTMLPropertyDescriptor) {
	Object.defineProperty(Element.prototype, 'innerHTML', {
		set: function (content) {
			var cite = this;

			innerHTMLPropertyDescriptor.set.call(cite, content.replace(/&lt;(\w+)/g, function (m, m1) {
				cite.document.createElement(m1);

				return m;
			}));
		}
	});

	document.attachEvent('onreadystatechange', function () {
		document.body &amp;&amp; (document.body.innerHTML = document.body.innerHTML);
	});
})(document, Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML'));
</pre>
<p>There are issues to consider, like redeclaring the entire body of HTML (oh, you noticed that). Also, the <code>cloneNode</code> method would still break HTML5 elements, although there may be a solution to that as well, using <a href="http://www.jonathantneal.com/blog/polyfills-and-prototypes/">protyping</a>.</p>
<pre class="brush: plain; title: ; notranslate">
document.documentMode == 8 &amp;&amp; this.Element &amp;&amp; (Element.prototype.cloneNode = function (deep) {
	var cite = this, element = document.createElement(cite.parentNode.nodeName);

	element.innerHTML = deep ? cite.outerHTML : cite.outerHTML.replace(/&lt;(\w+)([^&gt;]*)&gt;[\W\w]*$/, '&lt;$1$2&gt;&lt;/$1&gt;');

	return element.removeChild(element.firstChild);
});
</pre>
<p>This back and forth could go on, further feeding my fixation, but the point is clear. The higher the browser bar is raised, the better the band-aids get. Now, if you don&#8217;t mind, I&#8217;ll be <a href="http://jonneal.bandcamp.com/track/writing-a-program">writing a program</a>. See you next time.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonathantneal.com/blog/a-close-shiv/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Polyfills and Prototypes</title>
		<link>http://www.jonathantneal.com/blog/polyfills-and-prototypes/</link>
		<comments>http://www.jonathantneal.com/blog/polyfills-and-prototypes/#comments</comments>
		<pubDate>Mon, 18 Jun 2012 10:00:08 +0000</pubDate>
		<dc:creator>jonathantneal</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.jonathantneal.com/?p=1</guid>
		<description><![CDATA[Polyfills are a welcome step forward for the www, allowing web developers to write their best code for today&#8217;s browsers without sacrificing the experience of those visitors still running the older stuff. A polyfill is code that fills in missing gaps ...]]></description>
				<content:encoded><![CDATA[<p>Polyfills are a welcome step forward for the www, allowing web developers to write their best code for today&#8217;s browsers without sacrificing the experience of those visitors still running the older stuff. A polyfill is code that fills in missing gaps of functionality in a web browser. Browsers that already have the functionality ignore the polyfill. As a result, all browsers get the same functionality, and developers spend less time debugging individual browsers and more time creating great experiences. Think of polyfills as a set of reading glasses for aging browsers.</p>
<blockquote><p>A polyfill, or polyfiller, is a piece of code (or plugin) that provides the technology that you, the developer, expect the browser to provide <em>natively</em>. Flattening the API landscape if you will.</p>
<footer><cite><a href="//twitter.com/rem">Remy Sharp</a></cite>, <a href="//remysharp.com/2010/10/08/what-is-a-polyfill/">What is a Polyfill?</a></footer>
</blockquote>
<p>Most polyfilling on the web is done through JavaScript prototyping.  In JavaScript, a prototype is an object that other objects inherit, and prototyping refers to the process of modifying the prototype object.  For example, if the <code>String</code> prototype was given a <code>trim</code> function which removed white-space from both ends of a string, then all strings would have this functionality.</p>
<pre class="brush: jscript; title: ; notranslate">
String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/g, '');
};

' Hello World '.trim(); // becomes 'Hello World'
</pre>
<p>What makes polyfilling unique from prototyping is the intention or expectation of some browsers to handle the functionality without any assistance. Good polyfilling does not overwrite existing functionality.  For example, if a <code>trim</code> function already existed on the <code>String</code> prototype (which, in many browsers, <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/Trim">it does</a>), then prototyping would only occur if and when the native functionality was not already present.</p>
<pre class="brush: jscript; title: ; notranslate">
!String.prototype.trim &amp;&amp; (String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/g, '');
});
</pre>
<p>A good polyfill is also distinguished by its ability to mimic native functionality as closely as possible.  For example, an <a href="https://developer.mozilla.org/en/DOM/element.addEventListener"><code>addEventListener</code></a> polyfill for IE8 would not only pass events to <a href="http://msdn.microsoft.com/en-us/library/ms536343(VS.85).aspx"><code>attachEvent</code></a>, but it would also mimic the <a href="https://developer.mozilla.org/en/DOM/event"><code>Event</code></a> object passed into the listener, imitating the <code>target</code> and <code>currentTarget</code> properties, as well as the <code>preventDefault</code> and <code>stopPropagation</code> methods. Good polyfills are meticulous.</p>
<pre class="brush: jscript; title: ; notranslate">
// EventListener | @jon_neal | //github.com/jonathantneal/EventListener

!this.addEventListener &amp;&amp; this.Element &amp;&amp; (function () {
	function addToPrototype(name, method) {
		Window.prototype[name] = HTMLDocument.prototype[name] = Element.prototype[name] = method;
	}

	var registry = [];

	addToPrototype(&quot;addEventListener&quot;, function (type, listener) {
		var target = this;

		registry.unshift({
			__listener: function (event) {
				event.currentTarget = target;
				event.pageX = event.clientX + document.documentElement.scrollLeft;
				event.pageY = event.clientY + document.documentElement.scrollTop;
				event.preventDefault = function () { event.returnValue = false };
				event.relatedTarget = event.fromElement || null;
				event.stopPropagation = function () { event.cancelBubble = true };
				event.relatedTarget = event.fromElement || null;
				event.target = event.srcElement || target;
				event.timeStamp = +new Date;

				listener.call(target, event);
			},
			listener: listener,
			target: target,
			type: type
		});

		this.attachEvent(&quot;on&quot; + type, registry[0].__listener);
	});

	addToPrototype(&quot;removeEventListener&quot;, function (type, listener) {
		for (var index = 0, length = registry.length; index &lt; length; ++index) {
			if (registry[index].target == this &amp;&amp; registry[index].type == type &amp;&amp; registry[index].listener == listener) {
				return this.detachEvent(&quot;on&quot; + type, registry.splice(index, 1)[0].__listener);
			}
		}
	});

	addToPrototype(&quot;dispatchEvent&quot;, function (eventObject) {
		try {
			return this.fireEvent(&quot;on&quot; + eventObject.type, eventObject);
		} catch (error) {
			for (var index = 0, length = registry.length; index &lt; length; ++index) {
				if (registry[index].target == this &amp;&amp; registry[index].type == eventObject.type) {
					registry[index].call(this, eventObject);
				}
			}
		}
	});
})();
</pre>
<p>To better understand how and when to polyfill JavaScript, surf and study <a href="https://developer.mozilla.org/en/JavaScript/Reference/">Mozilla&#8217;s JavaScript Reference</a> and <a href="http://kangax.github.com/es5-compat-table/">Kangax&#8217;s ECMAScript 5 Compatibility Table</a>, or drink from the firehose at <a href="http://www.ecmascript.org/">the official ECMAScript website</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonathantneal.com/blog/polyfills-and-prototypes/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
