<?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>User Agent Man</title>
	<atom:link href="http://www.useragentman.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.useragentman.com/blog</link>
	<description>A Blog about Client Side Web Technology</description>
	<lastBuildDate>Thu, 02 Sep 2010 21:26:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>How to Make ClearType, @font-face Fonts and CSS Visual Filters Play Nicely Together</title>
		<link>http://www.useragentman.com/blog/2010/09/02/how-to-make-cleartype-font-face-fonts-and-css-visual-filters-play-nicely-together/</link>
		<comments>http://www.useragentman.com/blog/2010/09/02/how-to-make-cleartype-font-face-fonts-and-css-visual-filters-play-nicely-together/#comments</comments>
		<pubDate>Thu, 02 Sep 2010 20:49:51 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[ClearType]]></category>
		<category><![CDATA[Fonts]]></category>
		<category><![CDATA[anti-aliased text]]></category>
		<category><![CDATA[blocky text]]></category>
		<category><![CDATA[cleartype]]></category>
		<category><![CDATA[CSS Filters]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[ie filters]]></category>
		<category><![CDATA[Internet Explorers]]></category>
		<category><![CDATA[matrix]]></category>
		<category><![CDATA[opacity]]></category>
		<category><![CDATA[Visual Filters]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=1526</guid>
		<description><![CDATA[Ever had a problem with using IE's Alpha Visual Filter and getting blocky text? A solution has been found, and it doesn't use JavaScript.  I expect to hear a sigh of relief from many developers.]]></description>
			<content:encoded><![CDATA[<p>The modern web developer wants to be able to use a variety of CSS3 effects together, but sometimes doing this in IE can be challenging, especially if you don&#8217;t want to use JavaScript.  Let&#8217;s take a look a common problem with IE: blocky text in IE when using IE Visual filters on a block of text.  For example, if you&#8217;ve ever tried to do <a href="http://davidwalsh.name/css-opacity">the cross-browser CSS opacity trick</a> to implement opacity in IE6, this problem manifests itself when the <strong>text is styled with no background color</strong>.  A developer uses this well-known cross browser CSS-foo to make this work:</p>
<blockquote class="code">
<pre>
#badAntiAliasing {
	opacity: 0.5;
	filter: progid:DXImageTransform.Microsoft.Alpha(opacity=50);
	-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=50)";
}
</pre>
</blockquote>
<p>And it looks great in every browser, but <strong>it looks like crap in Internet Explorer 6 with ClearType turned on.</strong>  It is especially pronounced when using @font-face embedding with fonts that assume that some sort of anti-aliasing technology is being used.  The example below uses <a href="http://www.fonts.info/info/press/free-fonts-for-font-face-embedding.htm">Graublau Sans Web</a> with the Alpha filter to illustrate the issue:</p>
<table class="dataTable" style="margin-top: 1em">
<thead>
<tr>
<th>Opacity Solution in IE</th>
<th>Opacity Solution in every other browser</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/09/firefoxAntiAlias.png"><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/09/firefoxAntiAlias.png" alt="" title="firefoxAntiAlias" width="360" height="50" class="alignnone size-full wp-image-1529" /></a></td>
<td><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/09/ieBadAntiAlias.png"><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/09/ieBadAntiAlias.png" alt="" title="ieBadAntiAlias" width="361" height="58" class="alignnone size-full wp-image-1530" /></a></td>
</tr>
</tbody>
</table>
<p>This has been a known problem with IE ever since 2006 when ClearType&#8217;s product manager, Peter Gurevich, <a href="http://blogs.msdn.com/b/ie/archive/2006/08/31/730887.aspx">announced on the IEBlog their decision to disable ClearType on elements that use any Visual Filter</a>.  If you read the comments on this blog article, you will see many upset developers.  I was one of them, since this not only affects the <a href="http://msdn.microsoft.com/en-us/library/ms532967%28v=VS.85%29.aspx">Alpha Filter</a>, but all of <a href="http://msdn.microsoft.com/en-us/library/ms532849%28v=VS.85%29.aspx">IE&#8217;s Visual Filters</a>, some of which I use in cssSandpaper to get IE to support CSS3 properties like <code>transform</code>.</p>
<p>Today, however, we can rejoice.  There is a <strong>usable workaround that will make ClearType rendered fonts look nice when using Visual Filters</strong>.  In our example above, here is what needs to be done:</p>
<blockquote class="code">
<pre>
body.ie6 #goodAntiAliasing,
body.ie7 #goodAntiAliasing,
body.ie8 #goodAntiAliasing {
	background-color: <span class="hilite">white</span>;
}

#goodAntiAliasing {
	opacity: 0.5;
	filter: progid:DXImageTransform.Microsoft.Chroma(<span class="hilite">color='white'</span>),
		    progid:DXImageTransform.Microsoft.Alpha(opacity=50);
	-ms-filter: "progid:DXImageTransform.Microsoft.Chroma(<span class="hilite">color='white'</span>)",
		    "progid:DXImageTransform.Microsoft.Alpha(opacity=50)";
}
</pre>
</blockquote>
<p>What is going on here?</p>
<ol>
<li>The first rule sets the background color of the container to a color that is represents the color of the majority of the background image on the page.  <strong>Note that this rule uses <a href="http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/">Paul Irish&#8217;s Conditional CSS Pattern</a> to serve it only to IE.</strong></li>
<li>The second rule executes two of IE&#8217;s Visual Filters:
<ul>
<li>the Chroma Visual Filter, which tells IE &#8220;Please make this color transparent&#8221;.  The color we choose to make transparent is the one we selected in the first rule.</li>
<li>the Alpha Visual Filter, which does the opacity trick</li>
</ul>
</ol>
<table class="dataTable">
<thead>
<tr>
<th>New Opacity Solution in IE</th>
<th>New Opacity Solution in every other browser</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/09/ieBadAntiAlias.png"><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/09/ieBadAntiAlias.png" alt="" title="ieBadAntiAlias" width="361" height="58" class="alignnone size-full wp-image-1530" /></a></td>
<td><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/09/ieBadAntiAlias.png"><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/09/ieGoodAntiAlias.png" alt="" title="ieBadAntiAlias" width="361" height="58" class="alignnone size-full wp-image-1530" /></a></td>
</tr>
</tbody>
</table>
<p><strong>These filters must be in the order given</strong>, and not the other way around.  Note also that care must be given that <strong>the color chosen to be transparent should be the average color of what is behind the text being styled</strong>, otherwise you will get less than optimal results.  If this background is a complex image, just use the colour that&#8217;s used most often.</p>
<p>This fixes not only the IE opacity problem, but also issues with other Visual Filters, such as <code>Matrix</code>.  I will be updating cssSandpaper to use this trick so that transformed objects in IE won&#8217;t look so blocky.</p>
<p><a class="exampleLink" href="/tests/fontFacePlusFilter/">Take a look at the solution in action (make sure you look at it in IE in order to get the full effect)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2010/09/02/how-to-make-cleartype-font-face-fonts-and-css-visual-filters-play-nicely-together/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Coding Colors Easily Using CSS3 hsl() Notation</title>
		<link>http://www.useragentman.com/blog/2010/08/28/coding-colors-easily-using-css3-hsl-notation/</link>
		<comments>http://www.useragentman.com/blog/2010/08/28/coding-colors-easily-using-css3-hsl-notation/#comments</comments>
		<pubDate>Sat, 28 Aug 2010 12:11:59 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[CSS3]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=1443</guid>
		<description><![CDATA[The seemingly impossible task of coming up with color codes off the top of your head can be done easily using CSS3's <code>hsl</code> color notation.  Read how you can use this "human-friendly" and how it can work in the few browsers that don't support it natively.]]></description>
			<content:encoded><![CDATA[<div >
<dl id="attachment_822" class="wp-caption alignleft" style="width: 267px;">
<dt class="wp-caption-dt"><img class="size-full wp-image-822 " title="CSS3 Cube Layout Example" src="http://www.useragentman.com/blog/wp-content/uploads/2010/08/colorWheel.jpg" alt="" width="257" /></dt>
<dd class="wp-caption-dd">
<div>A remix of <a href="http://commons.wikimedia.org/wiki/File:Bezold_Farbentafel_1874.jpg">Wilhelm von Bezold&#8217;s Farbentafel Color Wheel</a>.</div>
</dd>
</dl>
</div>
<p>I have heard stories about <strong>&#8220;<em>those</em> people&#8221;</strong> that see a color and can immediately calculate the RGB hex code in their head, without any tool whatsoever. Since I have never actually met one of <strong>&#8220;<em>those</em> people&#8221;</strong>, I don&#8217;t think they really exist.  However, it <strong>would</strong> be a nice skill to have, especially when presenting a new design to a client and they say &#8220;Perfect!  But can make that box a brighter orange, and that do-hickey a less pronounced purple?  And can you show us how it would look <strong>right now?</strong>&#8221;   </p>
<p>This seemingly impossible task of coming up with color codes off the top of your head can be done using CSS3&#8242;s <code>hsl</code> color notation.  <strong>HSL is a much more &#8220;human-friendly&#8221; notation than RGB</strong>, and with it you can code colors in your head easily <strong>without using The GIMP&#8217;s or Photoshop&#8217;s color-wheel</strong>.</p>
<p>Don&#8217;t believe me?  Read on and I&#8217;ll show you.  You&#8217;ll never want to go back to RGB again.  And even though IE 6-8 doesn&#8217;t support HSL natively, we will cover how support can be added.</p>
<h2>Notation</h2>
<p>An HSL color code uses the following CSS3 notation:</p>
<blockquote class="code"><pre>#myObject {
    background: <span class="hilite">hsl(120, 50%, 50%);</span>
}
</pre>
</blockquote>
<p>The first number is the <strong>hue</strong>, the second number is the <strong>saturation</strong>, and the third is the <strong>lightness</strong>.  These three terms are what HSL stand for.  But how does one manipulate these numbers?  Easily.</p>
<h2>Step 1: &#8220;Young Guys Can Be Messy Rascals&#8221;</h2>
<div id="colorwheel">
<div class="testBlock"  id="o1">
				<span><strong>R</strong>ed: 360&deg;</span>
			</div>
<div class="testBlock"  id="o2">
				<span><strong>Y</strong>ellow: 60&deg;</span>
			</div>
<div class="testBlock"  id="o3">
				<span><strong>G</strong>reen: 120&deg;</span>
			</div>
<div class="testBlock"  id="o4">
				<span><strong>C</strong>yan: 180&deg;</span>
			</div>
<div class="testBlock"  id="o5">
				<span><strong>B</strong>lue: 240&deg;</span>
			</div>
<div class="testBlock"  id="o6">
				<span><strong>M</strong>agenta: 300&deg;</span>
			</div>
<p>This diagram is not an image.  It was generated with HTML using <a href="/blog/2010/03/09/cross-browser-css-transforms-even-in-ie/">CSS3 <code>transform</code> functions</a> and <code>hsl()</code> color notation, and cssSandpaper for browsers that don&#8217;t support it.</p>
</p></div>
<p><strong>Memorize this sentence.</strong>  If you do, you will be to remember the six major colors in the HSV color wheel: Yellow, Green, Cyan, Blue, Magenta and Red.  <strong>These colors are spaced out by angles of 60 degrees.</strong>  If you follow the mnemonic, you should be able to remember the diagram on the left very easily.</p>
<p>So, if you want to pick green, you would code:</p>
<blockquote class="code smaller"><pre>hsl(<span class="hilite">120</span>, 100%, 50%)</pre>
</blockquote>
<p>(Don&#8217;t worry about the second and third parameters for now &#8230; we will get to that in a second).</p>
<p>Blue would be:</p>
<blockquote class="code smaller"><pre>hsl(<span class="hilite">240</span>, 100%, 50%)</pre>
</blockquote>
<p>Let&#8217;s say you wanted a color that is not on the wheel, like purple.  Purple is halfway between blue (240&deg;) and magenta (300&deg;) so we should pick something in between:</p>
<div class="example purple">background-color: hsl(270, 100%, 50%)</div>
<p>Think it should be more blue?  Choose an angle closer to blue!</p>
<div class="example bluePurple">background-color: hsl(255, 100%, 50%);</div>
<p>Want more magenta instead?  Then choose angle closer to magenta:</p>
<div class="example magentaPurple">background-color: hsl(285, 100%, 50%);</div>
<p>Note that you do not put use the <code>deg</code> keyword link in CSS3 Transforms.  It seems a little inconsistent, but at least it&#8217;s less typing. </p>
<h2>Step 2: Choose Your Intensity</h2>
<p>The second parameter is the colorfulness, or <a href="http://en.wikipedia.org/wiki/Colorfulness">saturation</a>.  The larger the percentage, the more &#8220;colorful&#8221; this color is.  Let&#8217;s take a look at what happens when we change green&#8217;s (120&deg;) colorfulness:</p>
<table id="colorfulnessTable" class="dataTable">
<thead>
<tr>
<th>hsl(120, 0%, 50%)</th>
<th>hsl(120, 25%, 50%)</th>
<th>hsl(120, 50%, 50%)</th>
<th>hsl(120, 75%, 50%)</th>
<th>hsl(120, 100%, 50%)</th>
</tr>
</thead>
<tbody>
<tr>
<td class="c1"></td>
<td class="c2"></td>
<td class="c3"></td>
<td class="c4"></td>
<td class="c5"></td>
</tr>
</table>
<p>The more the saturation percentage, the less &#8220;gray&#8221; it is.</p>
<h2>Step 3: Lighten it up</h2>
<p>The final step is to lighten up the color to the right level.  That can be done with the final parameter: </p>
<table id="brightnessTable" class="dataTable">
<thead>
<tr>
<th>hsl(120, 50%, 0%)</th>
<th>hsl(120, 50%, 25%)</th>
<th>hsl(120, 50%, 50%)</th>
<th>hsl(120, 50%, 75%)</th>
<th>hsl(120, 50%, 100%)</th>
</tr>
</thead>
<tbody>
<tr>
<td class="c1"></td>
<td class="c2"></td>
<td class="c3"></td>
<td class="c4"></td>
<td class="c5"></td>
</tr>
</table>
<h2>That&#8217;s It!</h2>
<p>Try it when you are using color on your next project.  <strong>You&#8217;ll find using the HSL color-space is <em>much</em> easier than using RGB</strong></p>
<h2>Browser Support</h2>
<p>HSL is supported in almost all the major browsers: Firefox 3.0+, Safari 3.0+, Chrome 5.0+, Opera 10+ and Explorer 9.0+.  <strong>For the browsers that don&#8217;t support it, I have updated <a href="/blog/2010/03/09/cross-browser-css-transforms-even-in-ie/">cssSandpaper</a> to implement HSL with the CSS <code>color</code> property</strong>, as well as the <code>border</code>, <code>background</code> family of properties (i.e. <code>border-right</code>, <code>background-color</code>, etc).</p>
<p>Also supported by cssSandpaper is HSLA, which is to HSL, as RGBA is to RGB.  It contains a fourth element, the alpha channel, that is a number from 0 to 1.  To illustrate how this works, let&#8217;s say an HTML element has a grid as a background image.  How can you shade that background image so that it looks, say, more green?</p>
<table id="alphaTable" class="dataTable">
<thead>
<tr>
<th>hsla(120, 50%, 50%, 0.25)</th>
<th>hsla(120, 50%, 50%, 0.5)</th>
<th>hsla(120, 50%, 50%, 0.75)</th>
<th>hsla(120, 50%, 50%, 1)</th>
</tr>
</thead>
<tbody>
<tr>
<td class="c2"></td>
<td class="c3"></td>
<td class="c4"></td>
<td class="c5"></td>
</tr>
</table>
<p>The table above is not an image &mdash; it is a real example of <code>hsla()</code> in action. Pretty neat, huh?  You can also use HSL and HSLA color in gradients.  The <a href="/blog/2010/03/09/cross-browser-css-transforms-even-in-ie/">cssSandpaper</a> library has supported WebKit style gradients with it&#8217;s own <code>-sand-gradient</code> property.  Now it supports HSLA gradients, like this 80% opaque yellow to 20% opaque blue linear gradient:</p>
<table id="gradientTable" class="dataTable">
<thead>
<tr>
<th>	-sand-gradient(linear, center top, center bottom, from(hsla(60, 100%, 50%, 0.8)), to(hsla(255, 100%, 50%, 0.2)));
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="c1"></td>
</tr>
</tbody>
</table>
<p>Unfortunately, cssSandpaper only supports HSLA for background coloring only, not border or text coloring, but one would just use progressive enhancement to take care of that edge case, since what it does support, in my humble opinion, is rather cool.  Download the latest version from the link below and use HSL and HSLA color notation now!  You&#8217;ll impress your developer friends with your off-the-top-of-your-head color-coding skillz.  :-)</p>
<p><a class="exampleLink" href="/blog/2010/03/09/cross-browser-css-transforms-even-in-ie/">Get the latest version of cssSandpaper from the official documentation page</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2010/08/28/coding-colors-easily-using-css3-hsl-notation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating Cross Browser HTML5 Forms Now, Using modernizr, webforms2 and html5Widgets</title>
		<link>http://www.useragentman.com/blog/2010/07/27/cross-browser-html5-forms-using-modernizr-webforms2-and-html5widgets/</link>
		<comments>http://www.useragentman.com/blog/2010/07/27/cross-browser-html5-forms-using-modernizr-webforms2-and-html5widgets/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 03:50:06 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[Forms]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=1110</guid>
		<description><![CDATA[Next generation web forms using HTML5 is hard to do today due to spotty browser support.  I demonstrate how a suite of JavaScript libraries can be used to help us use HTML5 Forms <strong>today</strong>.]]></description>
			<content:encoded><![CDATA[<div class="importantNotes">
<h3>Update (Aug. 6, 2010)</h3>
<p>This article has been <a href="http://nz.pe.kr/wordpress/?p=547">translated into Korean</a>
</div>
<div class="wp-caption alignright" style="width: 298px; border: solid 3px black;">
<div class="size-full wp-image-1387" style="width: 288px">
<form action="javascript:void(0)">
<table class="html5ExampleTable">
<tr>
<th>Range:</th>
<td>
<input type="range" /></td>
</tr>
<tr>
<th>Placeholder:</th>
<td>
<input type="text" placeholder="This is a test" /></td>
</tr>
<tr>
<th>Color:</th>
<td>
<input type="color" /></td>
</tr>
</table>
</form>
</div>
<p class="wp-caption-text" style="width: 288px;">Working example HTML5 Form using <a href="http://www.modernizr.com">Modernizr</a>, <a href="http://code.google.com/p/webforms2/">webforms2</a> and my new script, html5Widgets.  Go ahead &#8230; try them out.  You know you wanna!</p>
</div>
<p>Calendars, colour swatches, sliding widgets, client side validation: this is the nirvana that the HTML5 forms module promises. Some would say &#8220;So what? I&#8217;ve seen this on the web for years!&#8221;, and they&#8217;d be right. There have been some really brilliant people coding some really interesting widget and validation frameworks, so why should we change?</p>
<ul>
<li><strong>Ease the markup learning curve:</strong> HTML5 form widgets and validation have been built to be as dead simple to markup as a select box with no JavaScript knowledge required</li>
<li><strong>It&#8217;s a W3C standard:</strong> so you know that it&#8217;ll work for years to come and if you have problems, you could always ask almost anyone in the web development community for help.</li>
<li><strong>Cellular phone support:</strong> HTML5 form fields will have optimized user interfaces appropriate for the type of device.  <a href="http://devblog.blackberry.com/2010/03/use-html5-in-your-blackberry-web-content/">Blackberry already has optimized versions of the date/time and color widgets</a> and, according to <a href="http://diveintohtml5.org/">Mark Pilgrim&#8217;s</a> article <a href="http://diveintohtml5.org/forms.html">A Form of Madness</a>, the virtual keyboards that appear when using HTML5 form fields are optimized for the data being input.</li>
<li><strong>Web development tools will have to support it:</strong> It&#8217;s a safe bet that Aptana, Dreamweaver, and all the other IDEs out there will have HTML5 support.</li>
<li><strong>It&#8217;s HTML5:</strong> when you tell your non-techie co-workers that you use it, you will be the envy of all &mdash; after all, it <strong>must</strong> be five times better than regular HTML, right?  Your boss will be so impressed that you are now a guru in this futuristic technology with a cool numbered acronym that he or she will give you a big fat raise!!!
<p>(Okay, okay.  Don&#8217;t try to laugh too hard &#8230; your co-workers will start to worry).</li>
</ul>
<h2>The Support Dilemma</h2>
<p>Unfortunately, today&#8217;s support for the HTML5 Form Module is spotty with each browser supporting different parts of the specification.  Take a look at Wikipedia&#8217;s<a href="http://en.wikipedia.org/wiki/Comparison_of_layout_engines_%28HTML5%29"> HTML5 Forms comparison chart</a>.  You&#8217;ll see each browser supporting a different set of features, but the lowest common denominator they all support is rather small.</p>
<h2>But I Want To Use It <strong>Now!!!</strong></h2>
<p>HTML5 Forms started off as <a href="http://www.whatwg.org/specs/web-forms/2004-06-27-call-for-comments/">WebForms 2.0 back in 2004</a>, so I wasn&#8217;t surprised to see that a few developers had already coded some JavaScript implementations.  Weston Ruter&#8217;s cross browser library, <code>webforms2.js</code>, implements a huge chunk of it, including parts that didn&#8217;t make the transition from WebForms 2.0 to HTML5 forms (e.g. <a href="http://www.whatwg.org/specs/web-forms/current-work/#repeatingFormControls">Webform 2.0&#8242;s Repetition Model</a>).</p>
<p>Since widgets weren&#8217;t implemented in <code>webforms2</code>, I created <code>html5Widgets.js</code>.  This interface library is independent of <code>webforms2</code> &#8211; if all you want is a cross-browser HTML5 form with validation, then all you need is the original <code>webforms2.js</code>.  If you want special widgets that are not available for all browsers, include <code>html5Widgets.js</code>.  Since I did not want to re-invent the wheel by creating widgets from scratch, <code>html5Widgets.js</code> uses some really nice third party JavaScript libraries to create them (more on that below).  It also uses <code><a href="http://www.modernizr.com">Modernizr</a></code> to detect if there is native support for each of the HTML5 form widgets &#8211; if not, <code>html5Widgets</code> steps in to put the right widget in place.  To save bandwidth, developers only need to include the third party libraries for the widgets they need.</p>
<p>In the rest of this article, I will go over different parts of the HTML5 specification and show how you can use them in your applications today, step-by-step.  Each section will state which browser natively supports that part of the specification, and what is needed for browsers that don&#8217;t.  Eventually, when the browser manufacturers catch up with the standard, you won&#8217;t need to use any JavaScript at all.</p>
<h2>Form Validation Using the <code>required</code> and <code>pattern</code> Attributes</h2>
<p>The <code>required</code> attribute makes an input field mandatory and forces the user to enter in a value in order to submit the form data.  The markup is simple</p>
<blockquote class="code">
<pre>&lt;input type="text" name="firstName" value="" required="required" /&gt;
</pre>
</blockquote>
<p>(<strong>Note:</strong>, you can also just use <code>required</code> on its own if you aren&#8217;t trying to be XHTML compliant.)</p>
<p>The <code>pattern</code> attribute forces the user to enter in a value using a specified format.  It uses <a href="http://en.wikipedia.org/wiki/Regular_expressions">regular expressions</a> to define this format. For example, if you want to force the user to input a U.S. Zip Code inside a form field, you would use the following markup.</p>
<blockquote class="code">
<pre>&lt;--
     zip code regular expression from
     <a href="http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256F6B005294C2">http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256F6B005294C2</a>
--&gt;
&lt;input type="text" name="zipCode" value=""
   pattern="\d{5}([\-]\d{4})?" required="required"  /&gt;
</pre>
</blockquote>
<p>Note that <code>required</code> and <code>pattern</code> are independent from each other.  You can have a <code>pattern</code> set on a form field without it being <code>mandatory</code>  (i.e. the pattern would only be checked if the user enters in data into the field).</p>
<p>Opera 10+ (mobile and desktop editions) is the only browser that supports the validation routines natively.  To use this in all other browsers, all you need is to include the following script tags in the <code>head</code> of your document.</p>
<blockquote class="code">
<pre>&lt;script type="text/javascript" src="/path/to/archive/js/weston.ruter.net/webforms2/webforms2_src.js"&gt;
&lt;/script&gt;
</pre>
</blockquote>
<p>Let&#8217;s take a look at how this looks visually:</p>
<table class="screenshots">
<thead>
<tr>
<th>Opera 10+ Windows</th>
<th>Firefox 3.6 with webforms2.js</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<a href="/tests/html5Widgets/patternRequired.html"><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/07/validityOpera.png" alt="[Screenshot of HTML5 Validation using Opera]" title="Screenshot of HTML5 Validation using Opera"  class="alignnone size-full wp-image-1282" /></a>
</td>
<td>
<a href="/tests/html5Widgets/patternRequired.html"><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/07/validityFirefoxWithHTML5Widgets.png" alt="[Screenshot of HTML5 Validation using Firefox and webforms2.js]" title="Screenshot of HTML5 Validation using Firefox and webforms2.js"  class="alignnone size-full wp-image-1282" /></a>
</td>
</tr>
</tbody>
</table>
<p>Note the &#8220;starred&#8221; style of the form field &mdash; this is not the default look and feel of the <code>required</code> fields, but something I added with a simple amount of CSS:</p>
<blockquote class="code">
<pre>input[required], select[required] {
	background: #ffffee url("../images/asterix.gif")  no-repeat left 2px;
	padding-left: 1.5em;
	width: 13.5em !important;
}
</pre>
</blockquote>
<p>(<strong>This CSS does <em>not</em> work in Internet Explorer 6.</strong>  Given that <strong>everything else in this article does</strong>, I hope the reader will overlook this one oversight considering that this browser should have entered retirement years ago (and have its driving license taken away, and shipped off to some really horrible nursing home watching really crappy talk shows all day and eating bad food &#8230;)</p>
<p><a class="exampleLink" href="/tests/html5Widgets/patternRequired.html">See an example of <code>pattern</code> and <code>required</code> in action.</a></p>
<p>Note that the same validation framework checks the values of inputs of type <code>email</code>, <code>url</code> and <code>number</code> to ensure that the values are in their respective valid formats.  As an added bonus, if you are using the iPhone or iPad version of Safari, the virtual keyboard that appears will be optimized for these type of form fields (e.g. when editing a <code>number</code> field, the keyboard that appears contains only digits and the &#8220;+&#8221;, &#8220;-&#8221;, and &#8220;.&#8221; keys.  This is native behaviour for iOS, and I hope other mobile browsers, such the Android&#8217;s, follow suit.</p>
<h2>The <code>autofocus</code> Attribute</h2>
<p>The <code>autofocus</code> attribute allows developers to choose which element has focus when the page is loaded.  The Google front page has done this via JavaScript, and now, 12 years later, there is finally an HTML attribute to easily handle this.</p>
<blockquote class="code">
<pre>&lt;input type="text" name="fullName" value=""
  required="required" autofocus="autofocus" /&gt;
</pre>
</blockquote>
<p>Safari, Chrome and Opera support it natively.  To make it work in other browsers, include the <code>webforms2.js</code> library, as we did in the <code>required</code> and  <code>pattern</code> examples.</p>
<p><a class="exampleLink" href="/tests/html5Widgets/autofocus.html">See an example of <code>autofocus</code> in action</a></p>
<h2>The <code>placeholder</code> Attribute</h2>
<p>A placeholder is a great visual cue to communicate any special information about a field (e.g. a description<br />
of the data to be input, if the field is required, etc). </p>
<div id="attachment_1317" class="wp-caption aligncenter" style="width: 397px"><a href="/tests/html5Widgets/placeholder.html"><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/07/placeholder.png" alt="An example of placeholder text.  The text disappears when the field has focus or if the user types information into the field." title="placeholder" width="387" height="94" class="size-full wp-image-1317" /></a><p class="wp-caption-text">An example of placeholder text.  The text disappears when the field has focus or if the user types information into the field.</p></div>
<p>Syntax is simple:</p>
<blockquote class="code">
<pre>&lt;input type="text" name="fullName" value="" required="required"
   placeholder="Required information" /&gt;
</pre>
</blockquote>
<p>Safari, Chrome and Firefox support this attribute natively.  To make it work in other browsers, it is necessary to load the html5Widgets library, with the necessary supporting libraries:</p>
<blockquote class="code">
<pre>&lt;script type="text/javascript"
   src="/path/to/shared/js/modernizr.com/modernizr-1.5.min.js"&gt;
&lt;/script&gt;

&lt;script type="text/javascript" src="/path/to/shared/js/EventHelpers.js"&gt;
&lt;/script&gt;

&lt;script type="text/javascript" src="/path/to/shared/js/html5Widgets.js"&gt;
&lt;/script&gt;
</pre>
</blockquote>
<p>What do these libraries do?</p>
<ul>
<li><a href="http://modernizr.com"><code>modernizr</code></a> is used to detect which HTML5 attributes and tags are supported by the users&#8217; browser</li>
<li><code>html5Widgets</code> is what actually does the placeholder logic, with <code>EventHelpers.js</code> providing cross-browser event-handling routines.</li>
</ul>
<p><a class="exampleLink" href="/tests/html5Widgets/placeholder.html">See an example of the HTML5 <code>placeholder</code><br />
tag in action.</a></p>
<h2>The <code>range</code> Input Type and <code>output</code> Tag</h2>
<p>Easily my favourite of the HTML5 widgets, <code>range</code> gives developers a sliding control to put inside their forms.  </p>
<p>The syntax is simple:</p>
<blockquote class="code">
<pre>&lt;input type="range"  name="rangeEl" value="" min="0" max="150" step="1" /&gt;
</pre>
</blockquote>
<p>The <code>min</code> and <code>max</code> attributes contain the minimum and maximum values, and <code>step</code> denotes by what increments the range slider increments by when moved.  Note that you can use these attributes with the <code>number</code> input type as well, but instead of having the fancy interface, it will use the validation engine to ensure the value follows what these attributes dictate.</p>
<p>At the time of this writing, Opera and WebKit based browsers (like Safari and Chrome), support it natively, and html5Widgets uses <a href="http://www.frequency-decoder.com/demo/slider-revisited/">the Frequency Decoder Slider Widget</a> to implement it in unsupported browsers.  To ensure cross-browser HTML5 range element goodness, place the following script tags in your document:</p>
<blockquote class="code">
<pre>&lt;!-- Needed for Range Element --&gt;
&lt;link type="text/css" rel="stylesheet" href="/path/to/shared/css/slider.css"&gt;

&lt;!--[if lte IE 6]&gt;
&lt;link type="text/css" rel="stylesheet" href="/path/to/shared/css/slider_ie.css" /&gt;
&lt;![endif]--&gt;

&lt;script type="text/javascript" src="/path/to/shared/js/frequency-decoder.com/slider.js"&gt;
&lt;/script&gt;

&lt;!-- Needed for Validation --&gt;
&lt;script type="text/javascript" src="/path/to/shared/js/weston.ruter.net/webforms2/webforms2_src.js"&gt;
&lt;/script&gt;

&lt;!-- Need for HTML5Widgets --&gt;
&lt;script type="text/javascript"
  src="/path/to/shared/js/modernizr.com/modernizr-1.5.min.js"&gt;
&lt;/script&gt;

&lt;script type="text/javascript" src="/path/to/shared/js/html5.js"&gt;
&lt;/script&gt;
&lt;script type="text/javascript" src="/path/to/shared/js/EventHelpers.js"&gt;
&lt;/script&gt;

&lt;script type="text/javascript" src="/path/to/shared/js/html5Widgets.js"&gt;
&lt;/script&gt;</pre>
</blockquote>
<p>Take a look at the screenshots below.  You will see that the way a <code>range</code> field varies among the browsers that natively support it, and even in some of the browsers that use html5Widgets:</p>
<table class="screenshots">
<thead>
<tr>
<th></th>
<th>Explorer 6.x+<br />
(html5Widgets support)</th>
<th>Firefox 3.5+<br />
(html5Widgets support)</th>
<th>Safari 4.0+<br />
(native support)</th>
<th>Chrome 3.0+<br />
(native support)</th>
<th>Opera 10.0+<br />
(native support)</th>
</tr>
</thead>
<tbody>
<tr>
<th>Windows</th>
<td><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/05/rangeExplorerWindows.png"><img title="Screenshot of range field for Internet Explorer 6" src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/rangeExplorerWindows.png" alt="Screenshot of range field for Internet Explorer 6" width="120" height="68" /></a></td>
<td><img title="Screenshot of range field for Windows Firefox" src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/rangeFirefoxWindows.png" alt="Screenshot of range field for Windows Firefox" width="120" height="68" /></td>
<td><img title="Screenshot of range field for Windows Safari" src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/rangeSafariWindows.png" alt="Screenshot of range field for Windows Safari " width="120" height="68" /></td>
<td><img title="Screenshot of range field for Chrome Windows" src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/rangeChromeWindows.png" alt="Screenshot of range field for Chrome Windows" width="120" height="68" /></td>
<td><img title="Screenshot of range field for Windows Opera" src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/rangeOperaWindows.png" alt="Screenshot of range field for Windows Opera" width="120" height="68" /></td>
</tr>
<tr>
<th>Mac</th>
<td>Not Applicable</td>
<td><img title="Screenshot of range field for Mac Firefox" src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/rangeFirefoxMac.png" alt="Screenshot of range field for Mac Firefox" width="120" height="68" /></td>
<td><img title="Screenshot of range field for Mac Safari" src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/rangeSafariMac.png" alt="Screenshot of range field for Mac Safari " width="120" height="68" /></td>
<td><img title="Screenshot of range field for Chrome Mac" src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/rangeChromeMac.png" alt="Screenshot of range field for Chrome Mac" width="120" height="68" /></td>
<td><img title="Screenshot of range field for Mac Opera" src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/rangeOperaMac.png" alt="Screenshot of range field for Mac Opera" width="120" height="68" /></td>
</tr>
<tr>
<th>Linux</th>
<td>Not Applicable</td>
<td><img title="Screenshot of range field for Linux Firefox" src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/rangeFirefoxUbuntu.png" alt="Screenshot of range field for Linux Firefox" width="120" height="68" /></td>
<td>Not Applicable</td>
<td><img title="Screenshot of range field for Linux Chrome" src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/rangeChromeUbuntu.png" alt="Screenshot of range field for Linux Chrome" width="120" height="68" /></td>
<td><img title="Screenshot of range field for Linux Opera" src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/rangeOperaUbuntu.png" alt="Screenshot of range field for Linux Opera" width="120" height="68" /></td>
</tr>
</tbody>
</table>
<p>The <code>output</code> tag can be used to show the value of a field, or the result of an operation performed on a number of fields, using JavaScript expressions.  Although the <code>output</code> tag may calculate fomulas referencing <em>any</em> form fields, it is useful especially for the <code>range</code> input type so users can see what value the range element is pointing to:</p>
<blockquote class="code">
<pre><span class="hilite">&lt;output onforminput="this.value = rangeEl.value"&gt;-&lt;/output&gt;</span>
&lt;input type="range"  name="rangeEl" value="" min="0" max="150" step="1" /&gt;
</pre>
</blockquote>
<p>The contents of the <code>output</code> tag is the default value.  Note the <code>this.value</code> syntax &#8211; I am not sure why the W3C HTML5 working group decided it was needed (why not just have the formula?), but it is.  If there are other types of expressions supported in the final specification, they are not supported by <code>html5Widgets</code> at this time.  Note that in order to apply CSS to the <code>output</code> tag in IE, it is necessary to use <a href="http://remysharp.com/2009/01/07/html5-enabling-script/">Remy Sharp&#8217;s HTML5 Enabling Script</a>.</p>
<p><a class="exampleLink" href="/tests/html5Widgets/range.html">See an example of the <code>range</code> input being used with the <code>output</code> tag.</a></p>
<p><a class="exampleLink" href="/tests/html5Widgets/output.html">See an example of the <code>output</code> tag being used <em>without</em> a <code>range</code> field.</a></p>
<h2>The <code>datetime</code>, <code>datetime-local</code>, <code>date</code>, <code>week</code> and <code>week</code> Input Types</h2>
<p>At the time of this writing, Opera is the only desktop browser that supports HTML5 date fields.  To support the other browsers, html5Widgets uses a slightly modified version of <a href="http://www.dynarch.com/">DynArch.com</a>&#8216;s <a href="http://www.dynarch.com/projects/calendar/old/">Ex-&#8221;Coolest&#8221; DHTML Calendar</a> (I decided not to use <a href="http://www.dynarch.com/projects/calendar/">the coolest one</a> because the Ex-Coolest has a more permissive license and it works really well). Now all browsers can support the <code>datetime</code>, <code>datetime-local</code>, <code>date</code>, <code>month</code> and <code>week</code> input fields, and submit these values in a consistent format.</p>
<p>Here are the scripts needed for the browsers that need it:</p>
<blockquote class="code">
<pre>
&lt;!-- Needed for Date/Time Elements --&gt;
&lt;link type="text/css" rel="stylesheet" href="/path/to/shared/js/jscalendar-1.0/calendar-win2k-1.css" /&gt;
&lt;script type="text/javascript" src="/path/to/shared/js/jscalendar-1.0/calendar.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="/path/to/shared/js/jscalendar-1.0/lang/calendar-en.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="/path/to/shared/js/jscalendar-1.0/calendar-setup.js"&gt;&lt;/script&gt;

&lt;!-- Needed for Validation --&gt;
&lt;script type="text/javascript" src="/path/to/shared/js/weston.ruter.net/webforms2/webforms2_src.js"&gt;
&lt;/script&gt;

&lt;!-- What glues all the above together --&gt;

&lt;script type="text/javascript" src="/path/to/shared/js/modernizr.com/modernizr-1.5.min.js"&gt;
&lt;/script&gt;
&lt;script type="text/javascript" src="/path/to/shared/js/EventHelpers.js"&gt;
&lt;/script&gt;
&lt;script type="text/javascript" src="/path/to/shared/js/html5Widgets.js"&gt;
&lt;/script&gt;
</pre>
</blockquote>
<p>Note that the calendar widget uses language packs and that I am using the English one (<code>calendar-en.js</code>.  Other language packs are included.</p>
<p>Below is a comparison between Opera&#8217;s native date widget vs. the one provided by the DynArch/HTML5Widget combo:</p>
<table class="screenshots">
<thead>
<tr>
<th></th>
<th>DateTime Widget</th>
<th>Month Widget</th>
</tr>
<tr>
<th>Opera Windows</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/dateTimeOperaWindows.png" /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/monthOperaWindows.png" /></td>
</tr>
<tr>
<th>Opera Mac</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/dateTimeOperaMac.png" /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/monthOperaMac.png" /></td>
</tr>
<tr>
<th>Firefox 3.5+ Windows<br />
(html5Widgets support)</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/datetimeFirefoxWithHTML5Widgets.png" /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/monthFirefoxWithHTML5Widgets.png" /></td>
</tr>
</table>
<p>It looks like the native calendar for Opera for Mac is a smaller than the Windows version &#8211; hopefully this is just on my copy of the browser.</p>
<p>The display formats, and they values that they submit to the server, are pretty much the same</p>
<table class="screenshots">
<thead>
<tr>
<th>Input type</th>
<th>Format displayed on page</th>
<th>Format sent to server</th>
</tr>
</thead>
<tbody>
<tr>
<td>datetime</td>
<td><em>yyyy-mm-dd HH:MM</em></td>
<td><em>yyyy-mm-dd</em>T<em>HH:MM</em>Z</td>
</tr>
<tr>
<td>datetime-local</td>
<td><em>yyyy-mm-dd HH:MM</em></td>
<td><em>yyyy-mm-dd</em>T<em>HH:MM</em></td>
</tr>
<tr>
<td>date</td>
<td><em>yyyy-mm-dd</em></td>
<td><em>yyyy-mm-dd</em></td>
</tr>
<tr>
<td>month</td>
<td><em>yyyy-mm</em></td>
<td><em>yyyy-mm</em></td>
</tr>
<tr>
<td>week</td>
<td><em>yyyy-mm</em>W</td>
<td><em>yyyy-mm</em>W</td>
</tr>
</tbody>
</table>
<p><a class="exampleLink" href="/tests/html5Widgets/dateTime.html">See the HTML5 <code>date</code> widgets in action.</a></p>
<p><strong>Note:</strong> In this example, The Opera Mobile Windows Emulator incorrectly displays the <code>datetime</code> and <code>datetime-local</code> calendars in the upper left-hand corner of the screen, but <strong>not</strong> the other ones.  Since this is Opera&#8217;s own calendar widget, and not html5Widgets&#8217;, this bug will have to fixed by Opera.  </p>
<div id="attachment_1269" class="wp-caption aligncenter" style="width: 501px"><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/07/operaMobileDateTimeBug.png"><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/07/operaMobileDateTimeBug.png" alt="Screenshot of Opera Mobile bug" title="operaMobileDateTimeBug" width="491" height="768" class="size-full wp-image-1269" /></a><p class="wp-caption-text">Screenshot of Opera Mobile bug</p></div>
<h2>The <code>color</code> Input Type</h2>
<p>Currently <strong>none</strong> of the desktop browser manufacturers support the <code>color</code> input type (although the new WebKit based <a href="http://devblog.blackberry.com/2010/03/use-html5-in-your-blackberry-web-content">Blackberry browser seems to have a neat implementation</a>). While we wait to see how the major browser manufacturers decide to implement <code>color</code>, you can use html5Widgets&#8217; implementation which uses <a href="http://www.softwareishard.com">Jan Odvarko</a>&#8216;s <a href="http://jscolor.com">jscolor</a>.  The script has been configured to allow only allow lower case hexadecimal rgb values to be entered, and that a blank value not be allowed, as per the W3C spec.</p>
<p>Here are the script tags needed to implement this in all browsers:</p>
<blockquote class="code"><pre>&lt;!-- Needed for Color Element --&gt;
&lt;script type="text/javascript" src="../../shared/js/jscolor/jscolor.js"&gt;
&lt;/script&gt;

&lt;!-- What glues all the above together --&gt;
&lt;script type="text/javascript" src="../../shared/js/modernizr.com/modernizr-1.5.min.js"&gt;
&lt;/script&gt;

&lt;script type="text/javascript" src="../../shared/js/EventHelpers.js"&gt;
&lt;/script&gt;

&lt;script type="text/javascript" src="../../shared/js/html5Widgets.js"&gt;
&lt;/script&gt;
</pre>
</blockquote>
<p>Below is a comparison between the Blackberry&#8217;s implementation (grabbed from <a href="http://devblog.blackberry.com/">the Blackberry Development Blog</a>) and HTML5Widget/jscolor&#8217;s. </p>
<table class="screenshot">
<thead>
<tr>
<th>Blackberry Web Browser</th>
<th>Firefox 3.5 with html5Widgets.js</th>
</thead>
<tbody>
<tr>
<td>
<a href="http://www.useragentman.com/blog/wp-content/uploads/2010/07/html5-color-input.jpg"><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/07/html5-color-input.jpg" alt="HTML5 Color form field, Blackberry" title="html5-color-input"  class="alignnone size-full wp-image-1292" /></a>
</td>
<td><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/07/jscolor.png"><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/07/jscolor.png" alt="HTML5 color input field with html5Widgets and jscolor." title="jscolor"  class="alignnone size-full wp-image-1291" /></a>
</td>
</tr>
</tbody>
</table>
<p><a class="exampleLink" href="/tests/html5Widgets/color.html">See HTML5Widget&#8217;s implementation of the<br />
<code>color</code> input type.</a></p>
<p><strong>Note:</strong> Like other HTML syntax, <code>color</code> uses the unfortunate American spelling instead of the Queen&#8217;s Proper English (i.e. colour). Ensure you spell it incorrectly in order to make this work.  ;-)</p>
<h2>How Well Do These Libraries Handle the Official Specification?</h2>
<p>I have done some testing on some existing examples that use HTML5 forms to ensure that it works the way developers expect.  Here are a few examples that I have taken, with the necessary JavaScript added:</p>
<ul>
<li><a href="/tests/html5Widgets/24ways.org/index.html"><strong>A cool looking payment form</strong></a> by <a href="http://yaili.com/">Inayaili de León</a> (originally from<a href="http://24ways.org/2009/have-a-field-day-with-html5-forms"> her HTML5 forms tutorial</a>)</li>
<li><a href="/tests/html5Widgets/bradshawenterprises.com/index.html"><strong>An HTML5 Form Demo</strong></a> by <a href="http://www.bradshawenterprises.com/">Richard Bradshaw</a> (originally from his <a href="http://www.bradshawenterprises.com/blog/2010/fancy-forms-html5-css3-js/"><em>Fancy Forms: HTML5 + CSS3 – JS</em></a> article)</li>
<li><a href="/tests/html5Widgets/dev.opera.com"><strong>Another cool Example</strong></a> by <a href="http://annevankesteren.nl/">Anne van Kesteren</a> (originally from his article <a href="http://dev.opera.com/articles/view/improve-your-forms-using-html5/"><em>Improve your forms using HTML5!</em></a> on the <a href="http://dev.opera.com">The Opera Developer Community Website</a>).</li>
</ul>
<p>However, the HTML5 Forms specification is large, and unfortunately, the <code>webforms2</code> and <code>html5Widgets</code> libraries don&#8217;t implement everything &#8230; <strong>yet!!!!</strong>  Since I am really motivated with what HTML5 forms can do, I am committed to completing support to most, if not all, of the HTML5 Forms specification.  The version of <code>webforms2</code> in this blog post has been modified from Weston Ruter&#8217;s original verison, but it will be merged with the official Google Code version in the next week or so and will include compressed versions of all the library. The <code>html5Widgets</code> library will also have a permanent home there.</p>
<p>Things that I will be working on in the near future are:</p>
<ul>
<li><strong>Support for other HTML5 form elements</strong>, among other things, <code>datalist</code>, <code>number</code>, <code>keygen</code>, <code>progress</code>, <code>time</code> and <code>meter</code></li>
<li><strong>Support for CSS styling of HTML5 form widgets</strong> as well as the ability to style form fields according to their validation state (e.g. <code>:valid</code> and <code>:invalid</code> psudo-classes).  Opera seems to be the only browser currently supporting this.</li>
<li><strong>Default styling for some of the new input types</strong>, like <code>tel</code>, <code>email</code>, <code>url</code>.  Opera for Mac and Opera Mobile are the only browsers I know of that support this for <code>email</code> and <code>url</code>.
<p><div id="attachment_1298" class="wp-caption aligncenter" style="width: 340px"><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/07/operaMacURLandEmail.png"><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/07/operaMacURLandEmail.png" alt="email and url form fields in Opera Mac" title="" width="330" height="156" class="size-full wp-image-1298" /></a><p class="wp-caption-text"><code>email</code> and <code>url</code> form fields in Opera Mac</p></div></li>
<li><strong>Support for customizing the validation look and feel.</strong>  This is one I would love to do, since I&#8217;m sure a lot of developers would want to change how validation errors appear on the screen.  Unfortunately, the HTML5 specification doesn&#8217;t describe a standard way of doing this.  It will be interesting to see how the browser manufacturers deal with this issue (<em><strong>To any browser developer reading this is working on the display form validation errors:</strong> I would love to know how you are doing this if you are willing to share.  <strong>Hint, HINT! ;-)</strong></em>)</li>
<li><strong>In Internet Explorer 7 and lower, the ability to style input types it doesn&#8217;t support natively</strong> with CSS code like <code>input[type="range"]</code></li>
<li><strong>Enabling HTML5 forms validation on the server side</strong> to ensure data integrity for browser that don&#8217;t support HTML5 forms that have JavaScript disabled.</li>
<li><strong>Support for internationalization of the error messages used in <code>webforms2</code>.</strong>  If anyone wants to help in the translation of these error messages, please drop me a line &mdash; I need help!</li>
</ul>
<p>Below is a modified version of the Wikipedia&#8217;s HTML5 forms compatibility table and see what how things the support situation stands today.</p>
<table class="screenshots">
<thead>
<tr>
<th></th>
<th>Trident</th>
<th>Gecko</th>
<th>WebKit</th>
<th>Presto</th>
</tr>
</thead>
<tbody>
<tr>
<th colspan="5">Attributes</th>
</tr>
<tr>
<th><code>autocomplete</code></th>
<td class="table-yes">Yes</td>
<td class="table-yes">Yes</td>
<td class="table-yes">Yes</td>
<td class="table-yes">2.0</td>
</tr>
<tr>
<th><code>list</code></th>
<td class="table-no">No</td>
<td class="table-no">No</td>
<td class="table-no">No</td>
<td class="table-yes">2.0</td>
</tr>
<tr>
<th><code>required</code></th>
<td class="table-yesWithWebforms2">Yes (with webforms2)</td>
<td class="table-yesWithWebforms2">Yes (with webforms2)</td>
<td class="table-yesWithWebforms2">Yes (with webforms2)</td>
<td class="table-yes">2.0</td>
</tr>
<tr>
<th><code>multiple</code></th>
<td class="table-no">No</td>
<td class="table-yes">1.9.2</td>
<td class="table-yes">526</td>
<td class="table-no">No</td>
</tr>
<tr>
<th><code>pattern</code></th>
<td class="table-yesWithWebforms2">Yes (with webforms2)</td>
<td class="table-yesWithWebforms2">Yes (with webforms2)</td>
<td class="nightly table-yesWithWebforms2 table-nightly">Yes (with webforms2, and natively in Nightly build)</td>
<td class="table-yes">2.0</td>
</tr>
<tr>
<th><code>min</code>, <code>max</code></th>
<td class="table-yesWithWebforms2">Yes (with webforms2)</td>
<td class="table-yesWithWebforms2">Yes (with webforms2)</td>
<td class="table-yesWithWebforms2">Yes (with webforms2)</td>
<td class="table-yes">2.0</td>
</tr>
<tr>
<th><code>step</code></th>
<td class="table-yesWithWebforms2">Yes (with webforms2)</td>
<td class="table-yesWithWebforms2">Yes (with webforms2)</td>
<td class="nightly table-nightly table-yesWithWebforms2">Yes (with webforms2 and Nightly build natively)</td>
<td class="table-yes">2.0</td>
</tr>
<tr>
<th><code>placeholder</code></th>
<td class="table-yesWithWebforms2">Yes (with webforms2)</td>
<td class="nightly table-nightly">1.9.3</td>
<td class="table-yes">Yes</td>
<td class="table-yesWithWebforms2">Yes (with webforms2)</td>
</tr>
<tr>
<th><code>form</code></th>
<td class="table-no">No</td>
<td class="nightly table-nightly">1.9.3</td>
<td class="table-no">No</td>
<td class="table-yes">2.0</td>
</tr>
<tr>
<th><code>autofocus</code></th>
<td class="table-yesWithhtml5Widgets">Yes (with html5Widgets)</td>
<td class="nightly table-nightly">1.9.3</td>
<td class="nightly table-nightly table-yesWithhtml5Widgets">Yes (with html5Widgets and Nightly build natively)</td>
<td class="table-yes">2.0</td>
</tr>
<tr>
<th><code>maxlength</code></th>
<td class="table-no">No</td>
<td class="nightly table-nightly">1.9.3</td>
<td class="nightly table-nightly">Nightly build</td>
<td class="table-yes">2.0</td>
</tr>
<tr>
<th><code>novalidate</code></th>
<td class="table-no">No</td>
<td class="table-no">No</td>
<td class="nightly table-nightly">Nightly build</td>
<td class="table-no">No</td>
</tr>
<tr>
<th><code>control</code></th>
<td class="table-no">No</td>
<td class="nightly table-nightly">1.9.3</td>
<td class="table-no">No</td>
<td class="table-no">No</td>
</tr>
<tr>
<th><code>accept</code></th>
<td class="table-no">No</td>
<td class="nightly table-nightly">1.9.3</td>
<td class="table-no">No</td>
<td class="table-no">No</td>
</tr>
<tr>
<th><code>formtarget</code></th>
<td class="table-no">No</td>
<td class="table-no">No</td>
<td class="table-no">No</td>
<td class="table-no">No</td>
</tr>
<tr>
<th><code>formaction</code></th>
<td class="table-no">No</td>
<td class="table-no">No</td>
<td class="table-no">No</td>
<td class="table-no">No</td>
</tr>
<tr>
<th colspan="5">Elements</th>
</tr>
<tr>
<th><code>datalist</code></th>
<td class="table-no">No</td>
<td class="table-no">No</td>
<td class="table-no">No</td>
<td class="table-yes">2.0</td>
</tr>
<tr>
<th><code>keygen</code></th>
<td class="table-no">No</td>
<td class="incorrect">1.0</td>
<td class="table-yes">125</td>
<td class="table-yes">1.0</td>
</tr>
<tr>
<th><code>output</code></th>
<td class="table-no">No</td>
<td class="nightly table-nightly">1.9.3</td>
<td class="table-no">No</td>
<td class="table-yes">2.0</td>
</tr>
<tr>
<th><code>progress</code></th>
<td class="table-no">No</td>
<td class="table-no">No</td>
<td class="nightly table-nightly">Nightly build</td>
<td class="table-no">No</td>
</tr>
<tr>
<th><code>meter</code></th>
<td class="table-no">No</td>
<td class="table-no">No</td>
<td class="table-no">No</td>
<td class="table-no">No</td>
</tr>
<tr>
<th colspan="5">Input types</th>
</tr>
<tr>
<th><code>search</code></th>
<td class="table-no">No</td>
<td class="nightly table-nightly">1.9.3</td>
<td class="table-yes">312</td>
<td class="table-no">No</td>
</tr>
<tr>
<th><code>tel</code></th>
<td class="table-no">No</td>
<td class="nightly table-nightly">1.9.3</td>
<td class="nightly table-nightly">Nightly build</td>
<td class="table-no">No</td>
</tr>
<tr>
<th><code>url</code></th>
<td class="table-no">No</td>
<td class="table-no">No</td>
<td class="nightly table-nightly">Nightly build</td>
<td class="table-yes">2.0</td>
</tr>
<tr>
<th><code>email</code></th>
<td class="table-no">No</td>
<td class="table-no">No</td>
<td class="nightly table-nightly">Nightly build</td>
<td class="table-yes">2.0</td>
</tr>
<tr>
<th><code>datetime</code></th>
<td class="table-yesWithhtml5Widgets" rowspan="6">Yes (with html5Widgets)</td>
<td class="table-yesWithhtml5Widgets" rowspan="6">Yes (with html5Widgets)</td>
<td class="nightly table-nightly table-yesWithhtml5Widgets" rowspan="6">Yes (with html5Widgets and Nightly build natively)</td>
<td class="table-yes" rowspan="6">2.0</td>
</tr>
<tr>
<th><code>date</code></th>
</tr>
<tr>
<th><code>month</code></th>
</tr>
<tr>
<th><code>week</code></th>
</tr>
<tr>
<th><code>time</code></th>
</tr>
<tr>
<th><code>datetime-local</code></th>
</tr>
<tr>
<th><code>number</code></th>
<td class="table-no">No</td>
<td class="table-no">No</td>
<td class="nightly table-nightly">Nightly build</td>
<td class="table-yes">2.0</td>
</tr>
<tr>
<th><code>range</code></th>
<td class="table-yesWithhtml5Widgets">Yes (with html5Widgets)</td>
<td class="table-yesWithhtml5Widgets">Yes (with html5Widgets)</td>
<td class="table-yes">Yes</td>
<td class="table-yes">2.0</td>
</tr>
<tr>
<th><code>color</code></th>
<td class="table-yesWithhtml5Widgets">Yes (with html5Widgets)</td>
<td class="table-yesWithhtml5Widgets">Yes (with html5Widgets)</td>
<td class="nightly table-nightly table-yesWithhtml5Widgets">Yes (with html5Widgets and Nightly build natively)</td>
<td class="table-yesWithhtml5Widgets">Yes (with html5Widgets)</td>
</tr>
</tbody>
</table>
<h2>Integrating With <code>visibleIf</code> To Make Even <strong>Cooler</strong> Looking Forms</h2>
<p>The <code>webforms2</code> and <code>html5Widgets</code> libraries are designed to co-exist well with <code><a href="http://www.useragentman.com/blog/2010/06/20/visibleif-html5-custom-data-attributes-with-javascript-make-dynamic-interactive-forms/">visibleIf</a></code> to create interactive forms with fields that only validate the ones that visibleIf is displaying.</p>
<p><a class="exampleLink" href="/tests/html5Widgets/patternRequiredWithVisibleIf.html">See an example of HTML5 validation working with the <code>visibleIf</code> JavaScript library</a></p>
<h2>Acknowledgments, Shout-outs and Kudos</h2>
<ul>
<li><strong><a href="http://farukat.es/">Faruk Ates</a> and <a href="http://paulirish.com/">Paul Irish</a></strong> for <em>the</em> definitive HTML5 and CSS3 feature detector, <a href="http://www.modernizr.com/">modernizr</a>.</li>
<li><strong><a href="http://weston.ruter.net/">Weston Ruter</a></strong> for doing the insane amount of work on <a href="http://code.google.com/p/webforms2/">webforms2</a> <em>years ago</em>.</li>
<li><strong><a href="http://www.frequency-decoder.com/">Brian McAllister:</a></strong> for making the excellent <a href="http://www.frequency-decoder.com/2008/08/01/unobtrusive-slider-control-v2">Unobtrusive slider control</a> which I used for the range element.</li>
<li><strong><a href="http://www.dynarch.com/">Mihai Bazon</a></strong> for keeping the <a href="http://www.dynarch.com/projects/calendar/old/">The Ex-“Coolest” DHTML Calendar</a> around even though he has a paid product.</li>
<li><strong><a href="http://www.softwareishard.com">Jan Odvárko</a></strong> for his rocking <a href="http://jscolor.com/">jscolor</a> widget.</li>
<li><strong><a href="http://remysharp.com/">Remy Sharp</a></strong> for his fine <a href="<a href="http://remysharp.com/2009/01/07/html5-enabling-script/">HTML5 Enabling Script</a> so we can force IE to style things like the <code>output</code> tag.</li>
<li><strong><a href="http://yaili.com/">Inayaili de Leon</a>, <a href="http://annevankesteren.nl/">Anne van Kesteren</a> and <a href="http://www.bradshawenterprises.com/">Richard Bradshaw</a></strong> for allowing me to show how easy it is to make their original HTML5 Form demos work with html5Widgets.</li>
</ul>
<h2>Further Reading</h2>
<ul>
<li><strong><a href="http://www.w3.org/TR/html5/forms.htm">The W3C HTML5 Forms Specification Working Draft:</a></strong> The Working Draft is in &#8220;Last call for comments&#8221; status, so there may be some last minute changes.</li>
<li><strong><a href="http://diveintohtml5.org/forms.html">A Form of Madness:</a></strong> Chapter 10 of Mark Pilgrim&#8217;s great reference on HTML5.</li>
<li><strong><a href="http://www.whatwg.org/specs/web-forms/current-work/">Web Forms 2.0 Working Draft:</a></strong> The WHATWG spec that the W3C spec is based on.  It includes the repetition model which didn&#8217;t make it into the W3C spec</li>
<li><strong><a href="http://code.google.com/p/webforms2/">webforms2 -Web Forms 2.0 Cross-Browser Implementation:</a></strong> Weston Ruter&#8217;s original script on Google Code.  In the next few weeks, this will be the contain the updated script presented here, and will be the official home for html5Widgets.</li>
</ul>
<h2>Download</h2>
<p>This archive is the temporary home for <code>html5Widgets</code>.  It will soon be hosted at the <a href="http://code.google.com/p/webforms2/"><code>webforms2</code> Google Code page</a>.</p>
<p><a href="/downloads/html5Widgets-1.0.zip" class="exampleLink"><code>html5Widgets</code> v. 1.0 and example code (zip format)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2010/07/27/cross-browser-html5-forms-using-modernizr-webforms2-and-html5widgets/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>visibleIf – Dynamic and Complex Interactive Forms Using HTML5 Custom Data Attributes</title>
		<link>http://www.useragentman.com/blog/2010/06/20/visibleif-html5-custom-data-attributes-with-javascript-make-dynamic-interactive-forms/</link>
		<comments>http://www.useragentman.com/blog/2010/06/20/visibleif-html5-custom-data-attributes-with-javascript-make-dynamic-interactive-forms/#comments</comments>
		<pubDate>Mon, 21 Jun 2010 00:49:36 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=1251</guid>
		<description><![CDATA[One thing HTML5 forms can't do is dynamically show and hide form elements according to the data that the user has already entered.  My new library, <code>visibleIf</code> gives you a very easy way to do this using the HTML5 <code>data-</code> attributes.]]></description>
			<content:encoded><![CDATA[<div class="importantNotes">
<h3>Update (July 28, 2010):</h3>
<p>I have fixed a minor bug in this script to ensure compatibility with webforms2, part of <a href="http://www.useragentman.com/blog/2010/07/27/cross-browser-html5-forms-using-modernizr-webforms2-and-html5widgets/">a suite of scripts that implement cross-browser compatibility with the HTML5 forms specification</a>.</p>
</div>
<p>I have been following the progression of the HTML5 Forms standard with great interest.  It promises a whole slew of new visual and usability goodness to existing HTML forms (e.g. slider and calendar widgets), a client-side validation framework, and so much more.  One of the things I was disappointed with, though, was that <strong>HTML5 cannot hide and show form elements depending on what the user has input into the form so far.</strong>  To give a very simple example of what I am talking about, select a country of origin in the form below:</p>
<form>
<table class="formTable">
<tbody>
<tr>
<th>Country of Origin: </th>
<td>
<select name="country">
<option> Select One&#8230; </option>
<option value="Canada"> Canada </option>
<option value="United States"> United States </option>
</select>
</td>
</tr>
<tr class="visibleIf" data-visibleif-rule=" country == 'Canada'">
<th>Postal Code: </th>
<td>
<input name="postalCode" type="text" /></td>
</tr>
<tr class="visibleIf" data-visibleif-rule=" country == 'United States'">
<th>Zip Code: </th>
<td>
<input name="zipCode" type="text" /></td>
</tr>
</tbody>
</table>
</form>
<p>In HTML5, there is no way for a developer to tell the browser <em>&#8220;only show me this block of HTML if </em><code>country == 'Canada'</code><em>&#8220;</em>.  This is not a criticism of HTML5 or its authors &mdash; HTML5 forms has a lot of awesomeness in it (some of which I will blog about in my next article) and we can&#8217;t expect it to do everything. However, I have been using custom JavaScript to do this kind of stuff all the time, and wouldn&#8217;t it be great if the JavaScript challenged could do so?  In the ideal world graphic designers, J2EE programmers with minimal front-end experience, and even my 75-year-old mom should be able to do this.</p>
<p>As a result, I present a JavaScript library, <code>visibleIf</code>, which allows web developers to use <a href="http://ejohn.org/blog/html-5-data-attributes/">HTML5 custom data attributes</a> to define when blocks of HTML should be visible or invisible.  <strong>Even if you are not a JavaScript genius, you will be able to make cool looking dynamic forms with very simple markup.</strong>  For example, let&#8217;s take a look at the HTML of the example above:</p>
<blockquote class="code">
<pre>&lt;form&gt;
    &lt;table class="formTable"&gt;
        &lt;tr&gt;
            &lt;th&gt;Country of Origin&lt;/th&gt;

            &lt;td&gt;&lt;select name="country"&gt;
                &lt;option value=""&gt;
                    Select One...
                &lt;/option&gt;

                &lt;option value="Canada"&gt;
                    Canada
                &lt;/option&gt;

                &lt;option value="United States"&gt;
                    United States
                &lt;/option&gt;
            &lt;/select&gt; &lt;/td&gt;
        &lt;/tr&gt;

        &lt;tr <span class="hilite">class="visibleIf" data-visibleif-rule="country == 'Canada'"</span>&gt;
            &lt;th&gt;Postal Code&lt;/th&gt;

            &lt;td&gt;&lt;input type="text" name="postalCode"
            value="" /&gt; &lt;/td&gt;
        &lt;/tr&gt;

        &lt;tr <span class="hilite">class="visibleIf" data-visibleif-rule="country == 'United States'"</span>&gt;
            &lt;th&gt;Zip Code&lt;/th&gt;

            &lt;td&gt;&lt;input type="text" name="zipCode"
            value="" /&gt; &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/table&gt;
&lt;/form&gt;
</pre>
</blockquote>
<p>This example is rather simple: the Postal Code form field is shown when <code>country == 'Canada'</code> and Zip Code is shown when <code>country == 'United States'</code>.  Note that in order to hide and show a block of HTML, you must set two attributes inside the containing tag:</p>
<ul>
<li><strong><code>class="visibleIf"</code>:</strong> which lets the visibleIf.js script know that this block of HTML is to be hidden or shown according to the <code>data-visibleif-rule</code></li>
<li><strong><code>data-visibleif-rule='<em>rule expression'</em></code>:</strong> which contains the visibility rule.  The rule variables are form element names, like <code>country</code> is in the above example. You can do simple equality rules like this, or complex ones like:<br />
<blockquote class="code"><pre>
&lt;div class="visibleIf"
   data-visibleif-rule="country == 'Canada' &#038;&#038; (city == 'Toronto' || city == 'Vancouver')"&gt;
  ...
&lt;/div&gt;
</pre>
</blockquote>
<p>If you know a little bit of JavaScript, you will note that you can use JavaScript functions to do interesting rules like:</p>
<blockquote class="code"><pre>
&lt;div class="visibleIf" data-visibleif-rule="parseInt(total) &gt; 100"&gt;
  ...
&lt;/div&gt;
</pre>
</blockquote>
</li>
</ul>
<p>Note that the above examples have visibleIf rules inside a <code>tr</code> tag, <strong>they can be used in any tag inside an HTML form</strong>. </p>
<p>Although the above example is quite simple, you can use visibleIf to make really complex forms &mdash; you can even put visibleIf blocks inside of visibleIf blocks.  To illustrate this I have created <a href="/tests/visibleIf/example1.html">a more interesting form</a> that shows what can be done using visibleIf.</p>
<p><a href="/tests/visibleIf/example1.html" class="exampleLink">See a more complex visibleIf form example</a></p>
<h2>Hidden Fields &#8211; To Clear Or Not To Clear</h2>
<p>If the user does something that hides some form fields (e.g. clicks on a checkbox) and then reverses that action (in this case clicking on the same checkbox), the fields will reappear with any previously filled-in data erased. Developers can override this default behavior by setting the class of the fields that shouldn&#8217;t be erased to <code>visibleIf-doNotReset</code>.  To illustrate this, I have created a page with two identical forms on it &mdash; one that erases the values inside hidden fields, and one that doesn&#8217;t.  Play with the example and you&#8217;ll see what I mean.</p>
<p><a class="exampleLink" href="/tests/visibleIf/example2-dotNotReset.html">See an example of a form with and without <code>visibleIf-doNotReset</code> fields.</a></p>
<h2>Hidden Fields &#8211; Submit To The Server, Or Not?</h2>
<p>Also note that by default, only the visible form elements are submitted to the server (this is because when a form element is hidden by <code>visibleIf</code>, its <code>disabled</code> attribute is set to <code>true</code> when the form is submitted).  If developers wants to override this behavior, they can simply set the form&#8217;s <code>class</code> to <code>visibleIf-submitInvisibleData</code>.</p>
<p><a  class="exampleLink"  href="/tests/visibleIf/example2-submitInvisibleData.html">See an example of a form with and without <code>visibleIf-submitInvisibleData</code> class set.</a></p>
<h2>The Quick &#8220;How-To&#8221; Guide&#8221;</h2>
<p>Setting up your existing forms to use visibleIf is a quick, three-step process:</p>
<ol>
<li>Download the source from the visibleIf Project Page</li>
<li>Include the visibleIf.css stylesheet, EventHelpers.js and visibleIf.js JavaScript files into your web page:<br />
<blockquote class="code">
<pre>&lt;link rel="stylesheet" href="/path/to/visibleIf.css" type="text/css" /&gt;

&lt;script type="text/javascript" src="/path/to/EventHelpers.js"&gt;
&lt;/script&gt;
&lt;script type="text/javascript" src="/path/to/visibleIf.js"&gt;
&lt;/script&gt;
</pre>
</blockquote>
</li>
<li>Use the visibleIf rules as seen in the example above.  Note that <code>&amp;&amp;</code>, <code>||</code> and other logical operators are allowed in the expressions, as are JavaScript functions (e.g. parseInt, parseFloat, etc).</li>
</ol>
<h2>A Note On The Use Of Custom Data Attributes</h2>
<p>Why did I bother with custom data attributes when making <code>visibleIf</code>?  Why did I just use the attribute <code>data-visibleif-rule</code> instead of just <code>visibleif-rule</code> or just <code>rule</code> to place the visibility rule? Wouldn&#8217;t that be simpler?</p>
<ul>
<li><strong><code>data-</code> attributes are HTML compliant: </strong>.  Their use ensure that <code>visibleIf</code> will be compatible with future versions of HTML since <strong><code>data-</code> attributes are reserved to be used for JavaScript libraries</strong>.  As long as you use the <a href="http://dev.w3.org/html5/spec/syntax.html#the-doctype">HTML5 DOCTYPE</a>, your forms should also validate.</li>
<li><strong>The <code>data-visibleif-</code> prefix will not collide with attributes used in other JavaScript libraries. </strong> There is a high chance that <code>data-rule</code> could be used by another library.  Using the name of the library in the attribute significantly reduces that possibility.
</ul>
<h2>Download</h2>
<p><a href="/downloads/visibleIf-2.1.zip" class="exampleLink"><code>visibleIf.js</code> v. 2.1 and example code (zip format)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2010/06/20/visibleif-html5-custom-data-attributes-with-javascript-make-dynamic-interactive-forms/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>cssSandpaper Now Supports transform: translate() and rgba() Gradients</title>
		<link>http://www.useragentman.com/blog/2010/05/06/csssandpaper-now-supports-transform-translate-and-rgba-gradients/</link>
		<comments>http://www.useragentman.com/blog/2010/05/06/csssandpaper-now-supports-transform-translate-and-rgba-gradients/#comments</comments>
		<pubDate>Thu, 06 May 2010 22:01:22 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=1060</guid>
		<description><![CDATA[In the first in a planned series of posts, I update cssSandpaper with new features.  This week I add IE support for <code>translate()</code> support to CSS transforms and alpha channel support to linear gradients.  ]]></description>
			<content:encoded><![CDATA[<p>I have been really happy with the great feedback I&#8217;ve been getting about <a href="http://www.useragentman.com/blog/csssandpaper-a-css3-javascript-library/">cssSandpaper</a>. <strong> CSS3 gives web developers  some great design tools to work with</strong> and it is my hope that this library will encourage more developers to use the <strong>use of these new features today</strong>, even if they have to code <strong>in older browsers.</strong> Even though Internet Explorer 9 will be supporting a few of these features, <strong>it will be quite a while before the number of users of IE8 will be at an ignorable level</strong> and we won&#8217;t need cssSandpaper any longer.  Until then, I will work hard to make cssSandpaper better.</p>
<p><a href="http://www.useragentman.com/blog/2010/03/09/cross-browser-css-transforms-even-in-ie/">When I released cssSandpaper</a> a few months ago, I was disappointed that I couldn&#8217;t support CSS3 transform&#8217;s <code>translate()</code> function in IE due to a limitation in the <a href="http://msdn.microsoft.com/en-us/library/ms533014%28VS.85%29.aspx"><code>DXImageTransform.Microsoft.Matrix</code> CSS <code>filter</code></a>.  However, with the gracious help of <a href="http://www.nicolarizzo.com/">Nicola Rizzo</a> (who has already used his Matrix filter skills coding <a href="http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/html/tests/test_style-html.html">a really cool dojox transformation plugin</a>) and Tomasz Tunik, we now have a version of cssSandpaper that supports it.  I also got a few requests to have IE support for CSS3 gradients that can use <a href="http://www.css3.info/preview/rgba/">the <code>rgba()</code> color space</a>, and with the help of information on <a href="http://css3please.com">CSS3 Please</a>, it was easily added.</p>
<h2>transform: translate</h2>
<p>The CSS <code>transform</code> property allows for 2D translations of a box.  What this means is, no matter which way you want to rotate or skew the object, you can move the object horizontally and vertically from the object&#8217;s perspective.  Some of you may ask &#8220;How is this different from changing the object&#8217;s  <code>top</code> and <code>left</code> properties?  Let&#8217;s take a look at an example below to see how it differs:</p>
<div id="attachment_1063" class="wp-caption aligncenter" style="width: 478px"><a href="http://www.useragentman.com/tests/cssSandpaper/simpleTranslate.html"><img class="size-full wp-image-1063" title="translateExample1" src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/translateExample1.png" alt="" width="468" height="458" /></a><p class="wp-caption-text">An example of CSS3 transform: translate() using cssSandpaper (click the image above to see it in action)</p></div>
<p>In the example above you&#8217;ll see two white boxes, one without any transforms performed, and the other translated 200 pixels to the right.  Just what you would expect.  Now take a look at the two red boxes &#8230; they are both rotated 45 degrees, but the second one is then<strong> translated 200 pixels to the right from the object&#8217;s perspective</strong>.</p>
<p>The translations are done with some very simple CSS:</p>
<blockquote class="code">
<pre>/*
 * This object is rotated 45 degrees and then translated 200 pixels to the
 * right and 100 pixels down, with respect to the object's perspective
 */

#o2 {
	-sand-transform: translate(200px, 100px);
}</pre>
</blockquote>
<p><code>translate()</code> takes two parameters, the x and y translation offsets (currently, cssSandpaper only supports <code>px</code> units for these offsets).  There are also <code>translateX()</code> and <code>translateY()</code> if a developer only wants to translate in one direction.</p>
<h2>rgba() Gradients</h2>
<p>The rgba color space adds alpha channeling to the rgb color space you know and love.  When using it in gradients, developers can make parts of an elements background-color semi-transparent.  The two examples below illustrate the effects that be done with <code>rgba()</code>.</p>
<table>
<tbody>
<tr>
<td>
<p><div id="attachment_1073" class="wp-caption aligncenter" style="width: 244px"><a href="/tests/cssSandpaper/rgbaGradientTest.html"><img class="size-full wp-image-1073 " title="gradients" src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/gradients.png" alt="" width="234" height="330" /></a><p class="wp-caption-text">A few rgba() gradients on top of each other to demonstrate their semi-transparency.</p></div></td>
<td>
<p><div id="attachment_1072" class="wp-caption aligncenter" style="width: 244px"><a href="/tests/cssSandpaper/rgbaGradient.html"><img class="size-full wp-image-1072 " title="gradientAnimation" src="http://www.useragentman.com/blog/wp-content/uploads/2010/05/gradientAnimation.png" alt="" width="234" height="330" /></a><p class="wp-caption-text">An example of an animation using rgba() gradients (click on the above images to show the examples in action).</p></div></td>
</tr>
</tbody>
</table>
<p>The following code illustrates how to perform an rgba() gradient:</p>
<blockquote class="code">
<pre>/*
 * The following is a horizontal gradient that blends red to blue, with a 50% opacity level
 */

#o2 {
   background-image: -sand-gradient(linear, left top, right top,
      from(rgba(255, 0, 0,  0.5)), to(rgba(0, 0, 255, 0.5)));
}</pre>
</blockquote>
<p>Note that as before, IE only supports two color gradients that are strictly horizontal or vertical.  I hope to support multiple color stops in IE in a future release.  Also note that in IE, the alpha channel is removed from an object if you apply a transform on it. This may be a limitation of <a href="http://msdn.microsoft.com/en-us/library/ms532997%28VS.85%29.aspx">IE&#8217;s  Gradient filter</a>, which cssSandpaper uses to implement CSS3 gradients.</p>
<p>In order to translate <code>rgba()</code> notation to ARGB notation with IE&#8217;s gradient filter understands (e.g. <code>#aarrggbb</code>, where <code>aa</code> are two hex digits representing the amount of opacity), I modified <a href="http://www.phpied.com/">Stoyan Stefanov</a>&#8216;s <a href="http://www.phpied.com/rgb-color-parser-in-javascript/">RGBColor script</a> (which translates from one color notation to another) and added ARGB support.</p>
<p>For information about the rgba color space, read the <a href="http://www.css3.info">CSS3.info&#8217;s</a> <a href="http://www.css3.info/introduction-opacity-rgba/">brief introduction to Opacity and RGBA</a>.</p>
<h2>Future Roadmap</h2>
<p>There is quite a bit more I would like to see cssSandpaper support, including:</p>
<ol>
<li><strong><a href="http://css-tricks.com/rgba-browser-support/">solid rgba() background colors</a>:</strong> this should be quite easy to support, given it is a special case of an rgba() gradient (i.e. a transition from a color to the same color).</li>
<li><strong><a href="http://vision-media.ca/resources/css/css-transformations-animations-and-transitions-examples">CSS3 transitions</a>:</strong> performing animations with only a bit of CSS would be sweet for those who are afraid of <a href="http://en.wikipedia.org/wiki/Recursion">recursive programming</a> with the JavaScript <a href="http://www.w3schools.com/js/js_timing.asp"><code>setTimeout()</code></a> function.</li>
<li><strong><a href="https://developer.mozilla.org/en/CSS/-moz-transform-origin">transform-origin</a>:</strong> modify the origin for transformations of an element (this would allow, for example, developers to produce an animation of planets rotating around the sun, which would be the transform-origin point for all the planets).</li>
<li><strong><a href="http://www.the-art-of-web.com/css/border-radius/">border-radius</a>: </strong> Firefox and Safari have slightly diffferent methods of rounding corners of a block-level element, and it would be useful to simplify this.  It would also be nice to have support for it in any version of IE (there are<a href="http://fetchak.com/ie-css3/"> a few excellent solutions involving VML</a> are out there today, but it would be great if there was one that supported all the features that CSS3 supports, including different radii for each corner, as well as co-existance with the other features of cssSandpaper, which may not be an easy thing to do).</li>
<li><strong>CSS3 gradients with multiple color-stops:</strong> cssSandpaper uses <a href="http://msdn.microsoft.com/en-us/library/ms532997%28VS.85%29.aspx">IE&#8217;s Gradient filter</a>, which only supports two color-stops.  It would be great to do some JavaScript magic to emulate multiple color-stops.</li>
<li><strong>radial gradients in IE: </strong>although IE&#8217;s Gradient filter doesn&#8217;t support it, VML does (I found <a href="http://sample.revulo.com/VML/radial-gradient-clip.html">a really cool example of an VML</a> radial gradient, but it can only be viewed in IE).</li>
<li><strong>better support for other units of measure besides px: </strong>I personally love to use em units in my design work, and want cssSandpaper to support this and other units, like cm, in, and percentages.</li>
</ol>
<p>If <strong>anyone </strong>would like to help me implement these features or any others in cssSandpaper, please contact me either in the discussion below or at the email address at the top of this page (I can <strong>really</strong> use any assistance anyone can give). Even if you don&#8217;t know JavaScript, any comments you have on this library would be most welcome. Let&#8217;s prevent older browsers from keeping us from using CSS3 and doing some really cool design work.</p>
<p><a class="exampleLink" href="http://www.useragentman.com/blog/csssandpaper-a-css3-javascript-library/">Get the latest version of cssSandpaper from the official documentation page</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2010/05/06/csssandpaper-now-supports-transform-translate-and-rgba-gradients/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CSS3 Please &#8211; Another Great Cross Browser CSS3 Solution.</title>
		<link>http://www.useragentman.com/blog/2010/04/06/css3-please-another-great-cross-browser-css3-solution/</link>
		<comments>http://www.useragentman.com/blog/2010/04/06/css3-please-another-great-cross-browser-css3-solution/#comments</comments>
		<pubDate>Tue, 06 Apr 2010 14:47:40 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[gradient]]></category>
		<category><![CDATA[ie filters]]></category>
		<category><![CDATA[rotation]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=1033</guid>
		<description><![CDATA[Although I have been doing a lot of work on cssSandpaper  lately (JavaScript API for cross browser CSS3 animation anyone?), I have also spent a little time on an equally worthwhile project CSS3 Please.  While cssSandpaper tries to give developers an all-in-one interface in which to do transforms, gradients and other nifty effects via simple CSS and JavaScript, CSS3 Please gives developers the opportunity to fill in the blanks of a stylesheet and see how CSS3 properties can be coded without the aid of JavaScript so that they work across the browsers that support it.]]></description>
			<content:encoded><![CDATA[<div id="attachment_1035" class="wp-caption alignleft" style="width: 267px"><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/04/css3please.png"><img class="size-full wp-image-1035" title="css3please" src="http://www.useragentman.com/blog/wp-content/uploads/2010/04/css3please.png" alt="" width="257" height="272" /></a><p class="wp-caption-text">Screenshot of the CSS3 Please editor.</p></div>
<p>Although I have been doing a lot of work on <a href="../csssandpaper-a-css3-javascript-library/">cssSandpaper</a> lately (<a href="../2010/04/05/cross-browser-animated-css-transforms-even-in-ie/">JavaScript  API for cross browser CSS3 animation</a> anyone?), I have also spent a  little time on an equally worthwhile project <a href="http://www.css3please.com/">CSS3  Please</a>. While cssSandpaper tries to give developers an all-in-one interface in which to do transforms, gradients and other nifty effects via simple CSS and JavaScript, CSS3 Please gives developers the opportunity to fill in the blanks of a stylesheet and see how CSS3 properties can be coded without the aid of JavaScript so that they work across the browsers that support it (look at the gradient section to see how different the implementations can be).  It also shows how developers can use Microsoft&#8217;s proprietary filter technology to emulate many of the current CSS3 properties (even if the newer CSS3 properties is folded into IE9 along with HTML5, it may be a bit of time before we see it achieve critical mass).  Take a look at the rotate section (the part I worked on), and you&#8217;ll see how very different the filter syntax is from the standard CSS3 declarations.</p>
<p>What tool you want to use depends on what your needs are.  Choice is good, and I thank <a href="http://paulirish.com/">Paul</a> and <a href="http://twitter.com/jon_neal">Jonathan</a> for letting me be part of it.</p>
<p><a class="exampleLink" href="http://www.css3please.com">Check out the official CSS3 Please website.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2010/04/06/css3-please-another-great-cross-browser-css3-solution/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cross-Browser Animated CSS Transforms &#8212; Even in IE.</title>
		<link>http://www.useragentman.com/blog/2010/04/05/cross-browser-animated-css-transforms-even-in-ie/</link>
		<comments>http://www.useragentman.com/blog/2010/04/05/cross-browser-animated-css-transforms-even-in-ie/#comments</comments>
		<pubDate>Tue, 06 Apr 2010 03:14:09 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[setTimeout]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=923</guid>
		<description><![CDATA[This is a follow-up article to my original CSS3 Transform article where I extend cssSandpaper to support scripting.  Now you can animate Css3 Transforms (as well as gradients, opacities and box-shadows) in all browsers, including IE, without a lot of issues.  Includes lots of neat examples.]]></description>
			<content:encoded><![CDATA[<div id="attachment_996" class="wp-caption alignright" style="width: 267px"><a href="/tests/cssSandpaper/clock.html"><img class="size-full wp-image-996 " title="Clock Example" src="http://www.useragentman.com/blog/wp-content/uploads/2010/04/clock.png" alt="" width="257" height="252" /></a><p class="wp-caption-text">Cross-Browser Animated CSS Clock Example based on an original WebKit example by Toby Pitman. Click image above to view.</p></div>
<p>In <a href="../2010/03/09/cross-browser-css-transforms-even-in-ie/">my  first article about CSS3</a>, I introduced a new script, <a href="http://www.useragentman.com/blog/csssandpaper-a-css3-javascript-library">cssSandpaper</a>, which allows developers to sidestep the myriad of vendor specific properties and just use one property to implement properties like <code>transform </code>for all browsers, including IE.</p>
<p>After posting the article, I saw many examples of CSS3 Transform using animations.  Toby Pitman&#8217;s <a href="http://css-tricks.com/css3-clock/">Old School Clock</a> is an excellent example of how one can use a Webkit&#8217;s <code>-webkit-transform</code> to make a small but excellent demo.  I wanted to prove that it would be easy to take this example and make it work in all modern browsers, so I did.  It took 15 minutes (okay, I had to change cssSandpaper to offer scripting support, but that didn&#8217;t take too long either).  I then coded a few more examples to show that some really neat things can be done using a small bit of JavaScript.   Here are links to these examples:</p>
<ul>
<li><a href="http://www.useragentman.com/tests/cssSandpaper/clock.html">The Cross-Browser CSS Clock</a> based on code by Toby Pitman</li>
<li><a href="http://www.useragentman.com/tests/cssSandpaper/countdown.html">A remixed movie leader countdown</a> (actually, it uses the <a href="http://en.wikipedia.org/wiki/File:RCA_Indian_Head_test_pattern.JPG">RCA Indian Head Test Pattern</a>, but whatever &#8230;)</li>
<li><a href="http://www.useragentman.com/tests/cssSandpaper/gradient.html">A psychedelic animated gradient</a></li>
</ul>
<h2>How To Do CSS3 Animated Effects?</h2>
<p><strong>If this was the perfect world</strong>, all a developer would need to do is use a DOM element&#8217;s <code>style</code> property and manipulate the appropriate camel-case CSS property.  For example, if a developer wanted to script the rotation of a node, he or she would code the following:</p>
<blockquote class="code">
<pre>    node.style.transform = "rotate(25deg)";</pre>
</blockquote>
<p>However, this is not the perfect world — after all, I am not making millions writing this blog and <strong>the current flavours of IE in use today don&#8217;t support many of the CSS3 properties</strong>.  However, using cssSandpaper, one could use the following method to do the same thing:</p>
<blockquote class="code">
<pre>    cssSandpaper.setTransform(node, "rotate(25deg)");</pre>
</blockquote>
<p>Developers can use cssSandpaper to manipulate <code>opacity</code>, <code>box-shadow</code>,  and <code>background</code> gradients, using <code>cssSandpaper.setOpacity()</code>, <code>cssSandpaper.setBoxShadow()</code> and <code>cssSandpaper.setGradient()</code> respectively.  All these functions take two parameters: a DOM node, and the appropriate CSS property values as described in the <a href="http://www.useragentman.com/downloads/cssSandpaper.1.0-beta2.zip">cssSandpaper documentation</a>.  For example:</p>
<blockquote class="code">
<pre>    cssSandpaper.setTransform(node, "rotate(25deg) scale(2, 2) skew(20deg, 20deg)");
    cssSandpaper.setOpacity(node, 0.3);
    cssSandpaper.setBoxShadow(node, "10px 10px 5px #ffcccc");
    cssSandpaper.setGradient(node, "-sand-gradient(linear, center top, center bottom, from(#0000ff), to(#ff0000));")</pre>
</blockquote>
<p>For more information, please read <a href="/blog/csssandpaper-a-css3-javascript-library">the official documentation of cssSandpaper</a>.</p>
<h2>Caveats</h2>
<ul>
<li>When animating using <code>transform</code>&#8216;s <code>scale()</code> function, make sure you avoid scaling objects too much larger than their original size.  This is due to the fact that IE scales objects as if they were images, and scaling-up an object will make the result quite pixelated.</li>
<li>The <code>-sand-gradient()</code> function does not use Firefox&#8217;s native <code>-moz-gradient</code> function to produce CSS3 gradients, but a solution using Canvas which works in all Canvas enabled versions of Firefox.  I will update cssSandpaper to use <code>-moz-gradient</code> in a future release (if anyone wants to help me get this working, please contact me via the email address at the top of this page, or by leaving a comment below).</li>
</ul>
<p><a class="exampleLink" href="http://www.useragentman.com/blog/csssandpaper-a-css3-javascript-library/">Go to the cssSandpaper documentation to download the latest version.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2010/04/05/cross-browser-animated-css-transforms-even-in-ie/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Cross Browser CSS Transforms &#8211; even in IE</title>
		<link>http://www.useragentman.com/blog/2010/03/09/cross-browser-css-transforms-even-in-ie/</link>
		<comments>http://www.useragentman.com/blog/2010/03/09/cross-browser-css-transforms-even-in-ie/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 05:00:05 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[cross-browser]]></category>
		<category><![CDATA[css sandpaper]]></category>
		<category><![CDATA[css transform]]></category>
		<category><![CDATA[css3 transform]]></category>
		<category><![CDATA[cssSandpaper]]></category>
		<category><![CDATA[ie filters]]></category>
		<category><![CDATA[transform]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=896</guid>
		<description><![CDATA[The CSS transform  property allows developers to rotate, scale, and skew blocks of HTML via CSS.  There are variants that work natively on all major browsers ... except for IE.  I created a new library, cssSandpaper, that implements CSS3 transforms (as well as gradients and box-shadows) in IE.  It also allows developers to use one transform declaration, instead of three vendor-specific ones for Opera, Firefox and WebKit browsers.  ]]></description>
			<content:encoded><![CDATA[<div class="importantNotes">
<h3>Update (April 6, 2010):</h3>
<p>Please see the <a href="/blog/2010/04/05/cross-browser-animated-css-transforms-even-in-ie/">follow up article on Cross Browser CSS3 Animation</a> which explores scripting CSS3 properties.</p>
</div>
<div class="mceTemp">
<dl id="attachment_822" class="wp-caption alignright" style="width: 267px;">
<dt class="wp-caption-dt"><a href="http://www.useragentman.com/tests/cssSandpaper/cube3.html"><img class="size-full wp-image-822 " title="CSS3 Cube Layout Example" src="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeExampleScreenshot.png" alt="" width="257" height="208" /></a></dt>
<dd class="wp-caption-dd">
<div>An example of a page using the CSS Transform property and cssSandpaper.  Visible in most major browsers, including Internet Explorer.  Layout based on work done by Paul Hayes in his article <a href="&lt;/dd"></a></div>
</dd>
</dl>
</div>
<p><a href="&lt;/dd">The </a><a href="http://www.w3.org/TR/css3-2d-transforms/">CSS <code>transform</code> property</a> allows developers to rotate, scale, and skew blocks of HTML via CSS.  Although you can do the same thing with images in Photoshop or The GIMP, using CSS transforms allows developers to do the same thing with any HTML markup and allows users to select the text within the transformed object.</p>
<p>When I first saw sites using <code>transform</code>, I looked at the underlying code and tried to produce pages using <code>transform</code> in all browsers.  Although Firefox, Opera and Webkit based browser support it via <a href="http://reference.sitepoint.com/css/vendorspecific">vendor-specific prefixes</a> (using <code>-moz-transform</code>, <code>-o-transform</code> and <code>-webkit-transform</code> respectively) Internet Explorer doesn&#8217;t support it at all.  I didn&#8217;t like that, so I took out my JavaScript whip, beat Explorer into submission and made it do my bidding (but not without getting a few mental bruises of my own).</p>
<p>Before I start talking about the details of my solution, let&#8217;s take a look at a few examples of it in action.  The following code has been tested with Firefox 3.5, Safari 4,  Chrome 4, Internet Explorer 6 and higher.</p>
<ol>
<li><a href="/tests/cssSandpaper/rotateTest.html">Rotations Example</a></li>
<li><a href="/tests/cssSandpaper/skewTest.html">Skew Example</a></li>
<li><a href="/tests/cssSandpaper/cube3.html">Cube Example, using rotates and skews</a></li>
<li><a href="/tests/cssSandpaper/example.html">Another example that looks like a CSS3 version of a Geocities page.</a></li>
</ol>
<p>(The examples  also work on my copy of Opera 10.5, although I have seen it fail on other installations &#8211; I will update this post when I find  out why).</p>
<h2>cssSandpaper to the Rescue</h2>
<p>I saw the design potential of using CSS transforms and was frustrated at Explorer&#8217;s lack of support.  I originally tried a non-JavaScript solution which involved creating CSS rules that combine <code>transform</code> with an IE technology that does something similar: the <a href="http://msdn.microsoft.com/en-us/library/ms533014%28VS.85%29.aspx"><code>DXImageTransform.Microsoft.Matrix</code> CSS <code>filter</code></a>.</p>
<p>I then, to steal a phrase from Russel Peters, started to Hurt Real Bad:</p>
<ul>
<li>the syntax of <code>transform</code> is very obvious:<br />
<blockquote class="code">
<pre>#myObject {
   transform: rotate(40deg) scale(2.0);
}</pre>
</blockquote>
<p>but the IE filter code is quite intimidating:</p>
<blockquote class="code">
<pre>#myObject {
   filter: progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand',
        M11=1.5320888862379554, M12=-1.2855752193730787,
        M21=1.2855752193730796, M22=1.5320888862379558);
}</pre>
</blockquote>
<p>The scary numbers that the <code>DXImageTransform.Microsoft.Matrix</code> filter uses requires knowledge of matrix and vector mathematics.  Even though there is a <a href="http://en.wikipedia.org/wiki/Transformation_matrix">great Wikipedia article on the subject</a>, even the mathematically gifted wouldn&#8217;t want to do the calculations to do a simple rotate in CSS (I would like to note here that even though I have a university degree in Mathematics, I hate doing arithmetic inside my head.  If you don&#8217;t believe me, watch  me figure out a tip at a restaurant sometime.  I&#8217;m not kidding).</li>
<li>although it is possible to have a list of transformations using <code>transform</code>, the <code>DXImageTransform.Microsoft.Matrix</code> filter only allows one transform matrix. In order to implement multiple transforms using one filter,  a designer would have to <a href="http://en.wikipedia.org/wiki/Matrix_multiplication">convert all the transforms into matrices and multiply them together</a>.  Again, as ugly as I am when I first wake up in the morning.</li>
<li>when rotating, skewing, or doing any other transformations on objects using the <code>transform</code> property, the center of the object remains fixed.  However, the <code>Matrix</code> filter doesn&#8217;t keep the centre of the transformed object fixed, as seen by the illustration below:<br />
<table class="screenshots">
<thead>
<tr>
<th>Rotate using CSS transform</th>
<th>Rotate using IE Filter</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/03/rotateFirefox.png"></a><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/03/rotateFirefox.png"><img class="alignnone size-full wp-image-872" title="Screenshot of object rotated using CSS transform property." src="http://www.useragentman.com/blog/wp-content/uploads/2010/03/rotateFirefox.png" alt="" width="241" height="240" /></a></td>
<td><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/03/rotateIE.png"><img class="alignnone size-full wp-image-873" title="example of object rotated with IE filter." src="http://www.useragentman.com/blog/wp-content/uploads/2010/03/rotateIE.png" alt="" width="241" height="240" /></a></td>
</tr>
</tbody>
</table>
</li>
</ul>
<p><a class="exampleLink" href="/tests/cssSandpaper/failedRotateExample.html">See the above example in action (compare IE with the other browsers to see the difference for yourself)</a></p>
<p>I was about to give up on my endeavor until I read Weston Ruter&#8217;s clever <a href="http://weston.ruter.net/projects/css-gradients-via-canvas/">CSS Gradients in Canvas</a> article, which implements gradients in older versions Firefox and Opera.  What I really liked was how he used the CSS from a web page to place the canvas gradients in the page (as opposed to using CSS classes to indicate where the gradients should go).   I then thought it would be a great idea to do the same with CSS transforms &#8211; why not have  JavaScript find out which objects are transformed by reading the style sheets containing the transform rules, and if the browser is Internet Explorer, apply the <code>Matrix</code> filter, while translating the image so that the center is maintained.  How hard could it be &#8230;&#8230;.. right?</p>
<p>After a few obsessive months of coding, coffee drinking and Asprin popping (as well angrily asking myself on several occasions why the &amp;@$! I would wanted to do this in the first place), I created <code>cssSandpaper.js</code>, a library that implements <code>transform</code> (and some other CSS3 properties) as consistently as possible in all browsers.  It uses many ideas from Ruter&#8217;s gradient script, as well as <code>sylvester.js</code>, <a href="www.jcoglan.com/">James Coglan&#8217;s</a> brilliant <a href="http://sylvester.jcoglan.com/">matrix and vector math library</a>.</p>
<p>The code is currently in a beta stage, but I think that it&#8217;s in good enough shape that developers can start to play around with these really cool effects today and have it work in almost any browser.</p>
<h2>Browser Differences</h2>
<p>After I finished cssSandpaper and played around with transforms, I found some slight differences in the way browsers handled them:</p>
<ul>
<li>If you transform an object with scrollbars, it is possible to scroll the object in most browsers in most cases.  However, in the cube page I mocked up, I noticed the following behaviour:
<ul>
<li>the left facing side of the cube isn&#8217;t easily accessible in IE.</li>
<li>the scrollbars don&#8217;t appear at all in Opera.</li>
<li>the scrollbars are not quite clear in Chrome for Windows, although one can still scroll the sides if you can guess where they are.</li>
<li>Firefox 3.5 for Mac puts the scrollbars in strange places (this has been fixed 3.6).</li>
</ul>
</li>
<li>In Internet Explorer, the text is selectable but sometimes it takes a few tries to figure out how to do it (try selecting text with IE in my cube mockup and you&#8217;ll see what I mean).</li>
<li>When selecting text within Firefox, the text tends to jump around ever so slightly for some odd reason (this is quite a subtle effect that it is probably not noticeable in most instances).</li>
<li>It <strong>looks</strong> like Internet Explorer takes the block of HTML, converts it to an image and then does the transform (I&#8217;m not sure .. I&#8217;m guessing).  As a result, the text in certain situations will look a little blurry, especially if scaling is involved.</li>
</ul>
<p>As to be expected, the rendering of the transformed text in the other browsers slightly differs:</p>
<table class="screenshots">
<thead>
<tr>
<th></th>
<th>Explorer 6.x+</th>
<th>Firefox 3.5+</th>
<th>Safari 4.0+</th>
<th>Chrome 3.0+</th>
<th>Opera 10.0+</th>
</tr>
</thead>
<tbody>
<tr>
<th>Windows</th>
<td><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeExplorerWindows.png"><img class="alignnone size-full wp-image-840" title="cubeExplorerWindows" src="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeExplorerWindows.png" alt="" /></a></td>
<td><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeFirefoxWindows.png"><img class="alignnone size-full wp-image-840" src="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeFirefoxWindows.png" alt="" /></a></td>
<td><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeSafariWindows.png"><img class="alignnone size-full wp-image-840" src="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeSafariWindows.png" alt="" /></a></td>
<td><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeChromeWindows.png"><img class="alignnone size-full wp-image-840" title="cubeExplorerWindows" src="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeChromeWindows.png" alt="" /></a></td>
<td><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeOperaWindows.png"><img class="alignnone size-full wp-image-840" src="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeOperaWindows.png" alt="" /></a></td>
</tr>
<tr>
<th>Mac OS X</th>
<td style="text-align: center;">Not Applicable</td>
<td><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeFirefoxMac.png"><img class="alignnone size-full wp-image-840" src="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeFirefoxMac.png" alt="" /></a></td>
<td><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeSafariMac.png"><img class="alignnone size-full wp-image-840" src="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeSafariMac.png" alt="" /></a></td>
<td><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeChromeMac.png"><img class="alignnone size-full wp-image-840" src="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeChromeMac.png" alt="" /></a></td>
<td>Doesn&#8217;t support transforms yet (as of version 10.50)</td>
</tr>
<tr>
<th>Linux</th>
<td style="text-align: center;">Not Applicable</td>
<td><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeFirefoxUbuntu.png"><img class="alignnone size-full wp-image-840" src="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeFirefoxUbuntu.png" alt="" /></a></td>
<td style="text-align: center;">Not Applicable</td>
<td><a href="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeChromeUbuntu.png"><img class="alignnone size-full wp-image-840" src="http://www.useragentman.com/blog/wp-content/uploads/2010/03/cubeChromeUbuntu.png" alt="" /></a></td>
<td>Doesn&#8217;t support transforms yet (as of version 10.50)</td>
</tr>
</tbody>
</table>
<h2>Using cssSandpaper</h2>
<p>After <a href="/downloads/cssSandpaper.1.0-beta1.zip">downloading the archive</a> you must put the following tags into the head of your document <strong>after all of your style sheet declarations</strong> (this is to ensure the JavaScripts will run after the style sheets are loaded):</p>
<blockquote class="code">
<pre>&lt;script type="text/javascript" src="path/to/js/cssQuery-p.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="path/to/js/jcoglan.com/sylvester.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="path/to/js/cssSandpaper.js"&gt;&lt;/script&gt;</pre>
</blockquote>
<p>You can then use the transform property in your web pages.  Note that since the specification for the transform property is finalized by the W3C, I decided to use the  <a href="http://reference.sitepoint.com/css/vendorspecific">vendor-specific prefix</a> <code>-sand-</code> before each CSS3 property it supports.</p>
<p>The following is a description of how to use <code>transform</code>, as well as two other CSS3 properties that cssSandpaper supports, <code>box-shadow</code> and <code>gradient</code>.</p>
<p><a class="exampleLink" href="http://www.useragentman.com/blog/csssandpaper-a-css3-javascript-library/">Go to the cssSandpaper documentation to download the latest version.</a></p>
<h2>-sand-transform</h2>
<p><!-- Begin steps --></p>
<div class="steps">
<h3 class="first">Description</h3>
<p>Transforms allow developers to rotate, scale, and skew blocks of HTML via CSS.</p>
<h3>Syntax</h3>
<blockquote class="code">
<pre>#container {
   -sand-transform:  <em>&lt;function-list&gt;</em>;
}</pre>
</blockquote>
<p>where <em>&lt;function-list&gt;</em> can be a space separated list of the following functions:</p>
<table class="screenshot">
<thead>
<tr>
<th>Function</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>rotate(angle)</code></td>
<td>Rotates HTML elements.  <code>angle</code> can be in degrees (e.g. rotate(30deg)) or radians <code>rotate(1.3rad)</code></td>
</tr>
<tr>
<td><code>scale(sx[, sy])</code></td>
<td>Scales HTML elements.  <code>sx</code> and <code>sy</code> are numbers, where <code>1</code> represents the original size, <code>2</code> represents twice the size, etc.  Note that if <code>sy</code> isn&#8217;t specified, it is assumed to be equal to <code>sx</code>.  Similar functions are <code>scaleX(sx)</code> and <code>scaleY(sy)</code>.</td>
</tr>
<tr>
<td><code>skew(ax[, ay])</code></td>
<td>Skews the object around the x and y axes by the specified angles in degrees or radians.  If <code>ay</code> isn&#8217;t provided, it is assumed to be <code>0deg</code>.</td>
</tr>
<tr>
<td><code>matrix(a, c, b, d, tx, ty)</code></td>
<td>Applies a 2D transformation matrix comprised of the specified six values.  If you aren&#8217;t familiar with linear algebra and matrix arithmetic, this function will be hard to understand.  For further information, you may want to read <a href="http://en.wikipedia.org/wiki/Transformation_matrix">Wikipedia&#8217;s Transformation Matrix</a> article, although if you are mathematically challenged, you may run away from your computer screaming.</p>
<p>If you are familiar with matrix multiplication, note that c and b are reversed.  This follows the way Firefox has implemented this method (i <strong>believe</strong> WebKit based browsers reverse these numbers).</td>
</tr>
</tbody>
</table>
<p><strong>Note:</strong> non-Explorer browsers support the <code>translate</code> function as well.  I have not been able to find a way to make this work IE at this time, due to a technical  issue with the IE&#8217;s <code>Matrix</code> filter property (for those who want details, I use <code>sizingMethod='auto expand'</code> when using the <code>Matrix</code> filter which doesn&#8217;t support translations, and using sizingMethod=&#8217;crop&#8217; is not suitable to emulate the <code>transform</code> property).  For this reason, the <code>tx</code> and <code>ty</code> values of the <code>matrix()</code> function are not supported as well.</p>
<h3>Examples</h3>
<ul>
<li><a href="/tests/cssSandpaper/rotateTest.html">Rotations</a></li>
<li><a href="/tests/cssSandpaper/skewTest.html">Skews</a></li>
</ul>
</div>
<h2>-sand-box-shadow</h2>
<div class="steps">
<h3 class="first">Description</h3>
<p><code>box-shadow</code> allows us to take a block level element and put a shadow underneath.  There can optionally set a blur factor to give a warmer effect to the shadow.</p>
<h3>Syntax</h3>
<blockquote class="code">
<pre>#container {
   -sand-box-shadow: <em>&lt;horizontal-offset&gt;</em> <em>&lt;vertical-offset&gt;</em> <em>&lt;blur-radius&gt;</em> <em>
</em>;
}</pre>
</blockquote>
<p>Note that in IE, the <code>blur-radius</code> is not supported, due to a lack of support in IE&#8217;s <a href="http://msdn.microsoft.com/en-us/library/ms533014%28VS.85%29.aspx"><code>DropShadow</code> filter</a>.</p>
<h3>Examples</h3>
<ul>
<li><a href="/tests/cssSandpaper/boxShadowTest.html">Box-Shadow Example</a></li>
</ul>
</div>
<h2>-sand-gradient</h2>
<div class="steps">
<h3 class="first">Description</h3>
<p>Gradients are gradual blends of color, and can be <code>linear</code> or <code>radial</code>:</p>
<h3>Syntax</h3>
<blockquote class="code">
<pre>#container {
   background-image: -sand-gradient(<em>&lt;type&gt;, &lt;start-point&gt;, &lt;end-point&gt;, &lt;color-stop1&gt;, &lt;color-stop2&gt;, ..., &lt;color-stopN&gt;</em>)
}</pre>
</blockquote>
<p>The type can be <code>linear</code> and <code>gradient</code>, although Internet Explorer doesn&#8217;t support radial gradients at this time, due to limitations in IE&#8217;s <a href="http://msdn.microsoft.com/en-us/library/ms532997%28VS.85%29.aspx"><code>gradient</code> filter</a>.  Internet Explorer also only supports simple linear gradients (i.e. only  horizontal and vertical and only two colours).</p>
<p>A more detailed explanation can be found in the <a href="http://dev.w3.org/csswg/css3-images/#linear-gradients">section regarding gradients</a> of the <a href="http://dev.w3.org/csswg/css3-images/">W3C&#8217;s working draft of CSS Image Values Module Level 3</a></p>
<h3>Examples</h3>
<ul>
<li><a href="/tests/cssSandpaper/gradientTest.html">Gradients Example Page</a></li>
</ul>
</div>
<h2>Other Known Issues</h2>
<ul>
<li>Currently, when a users changes the font-size in IE, the layout gets a little messed up.  This will be fixed in a future release.</li>
<li>Scripting in IE cannot be done via the usual <code>obj.style.transform</code>.  There is, however, an alternative way of scripting the cssSandpaper supported properties which will be outlined in a future blog post (I don&#8217;t mean to keep anyone in suspense &#8230; it&#8217;s just that I feel like I&#8217;ve spent too much time on this post and I want to get at least this part out the door :-) ).</li>
<li>Opera 10.5 sort of works.  It works on my copy, but not on another copy I&#8217;ve seen.  I don&#8217;t know why yet, but I will find out soon and post and update when I do.</li>
<li>Weston Ruter&#8217;s gradient script has more features.  I will incorporate them in a future release.</li>
</ul>
<h2>Future Work</h2>
<p>cssSandpaper will eventually be about more than just transforms &#8211; I would like to be able to support other advanced CSS topics (maybe even animations, if it is possible). It probably has a few bugs in it &#8211; I would really appreciate anyone letting  me know if you find any (my e-mail address is at the top left part of the page).</p>
<p>If anyone would like to get contribute code or do testing, I would love the help too.  :-)</p>
<h2>Acknowledgments</h2>
<p>I would like to thank Weston Ruter for his <a href="http://weston.ruter.net/projects/css-gradients-via-canvas/">CSS Gradients in Canvas</a> script, since I stole many of his ideas with his permission (I will be implementing more of the advanced features of his script in a future release of CSS3Sandbox).  I would also like to thank  <a href="www.jcoglan.com/">James Coglan</a> for building  <a href="http://sylvester.jcoglan.com/">Sylvester</a> so I didn&#8217;t have to.</p>
<h2>Downloads</h2>
<p><a class="exampleLink" href="http://www.useragentman.com/blog/csssandpaper-a-css3-javascript-library/">Go to the cssSandpaper documentation to download the latest version.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2010/03/09/cross-browser-css-transforms-even-in-ie/feed/</wfw:commentRss>
		<slash:comments>71</slash:comments>
		</item>
		<item>
		<title>Cross Browser HTML5 Drag and Drop</title>
		<link>http://www.useragentman.com/blog/2010/01/10/cross-browser-html5-drag-and-drop/</link>
		<comments>http://www.useragentman.com/blog/2010/01/10/cross-browser-html5-drag-and-drop/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 03:52:17 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=734</guid>
		<description><![CDATA[Update (Feb 3, 2009): A bug in Webkit seems to be the culprit in the permissions form example below not working correctly in Safari 4. The code has been updated to work around this bug and the article below has been updated. Thanks to russbuelt for pointing this out. Apparently, an example made by Apple [...]]]></description>
			<content:encoded><![CDATA[<div class="importantNotes">
<h3>Update (Feb 3, 2009):</h3>
<ul>
<li>A <a href="http://code.google.com/p/chromium/issues/detail?id=14654">bug in Webkit</a> seems to be the culprit in the permissions form example below not working correctly in Safari 4.  The code has been updated to work around this bug and the article below has been updated.  Thanks to <code>russbuelt</code> for pointing this out.</li>
<li>Apparently, an example made by Apple which I reported not working in Safari <em>does</em> work in Safari 4.0.4 for Mac OS X.  Thanks for Scott Straker for this information.</li>
</div>
<div id="attachment_538" class="wp-caption alignleft" style="width: 267px"><a href="http://flickr.com/photos/svartling/3822068125/"><img class="size-full wp-image-538   " title="HTML5 Drag and Drop" src="http://www.useragentman.com/blog/wp-content/uploads/2010/12/html5DragAndDrop.png" alt="Remixed version of image by Svartling." width="257" height="174" /></a><p class="wp-caption-text">Image Credit: Flickr user svartling</p></div>
<p><a href="http://dev.w3.org/html5/spec/editing.html#dnd">HTML5 Drag and Drop</a> has been talked about a lot lately, but it&#8217;s hard to find really useful information about implementing it across multiple browsers.   <a href="http://hacks.mozilla.org/2009/07/html5-drag-and-drop/">Mozilla</a>, <a href="http://developer.apple.com/Mac/library/documentation/AppleApplications/Conceptual/SafariJSProgTopics/Tasks/DragAndDrop.html">Apple</a> and <a href="http://msdn.microsoft.com/en-us/library/ms537658%28VS.85%29.aspx">Microsoft</a> all have pages describing how to use it, but their examples seem to work only in their particular browser (<strike><em><a href="http://developer.apple.com/Mac/library/documentation/AppleApplications/Conceptual/SafariJSProgTopics/Tasks/DragAndDrop.html">Apple&#8217;s example</a> doesn&#8217;t even work in their own!</em></strike> <strong>Updated, Jan. 11, 2009:</strong> Although I have not been able to get this example working on Safari 2.0.4 and 3.1.2 for OS X and 4.0.4 for Windows, I have received word that it works on Safari 4.0.4 on OS X).  Remy Sharp&#8217;s great article <a href="http://html5doctor.com/native-drag-and-drop/">Native Drag and Drop</a> was a good place for me to start — however, the examples didn&#8217;t work in Internet Explorer.  I also thoroughly enjoyed JavaScript guru <a href="http://www.quirksmode.org/">Peter-Paul Koch&#8217;s</a> <a href="http://www.quirksmode.org/blog/archives/2009/09/the_html5_drag.html">humorous and lengthy rant about cross-browser drag and drop headaches</a> where he uses creative and colourful language to describe what he thought of the standard, the browser manufacturers, and the WHAT-WG.</p>
<p>When normal people see the author of the <a href="http://www.quirksmode.org/compatibility.html">Compatibility Master Tables</a> respond negatively to a web technology, they would probably assume it would be a good sign to stay away from it.</p>
<p>However, I am not normal.  <strong>With a name like Zoltan, how could I <em>possibly</em> be normal?</strong> (and yes, <a href="http://www.useragentman.com/blog/the-infamous-zoltan-faq/">it <em>is</em> my real name</a>).</p>
<p>So, I decided to find out for myself how bad HTML5 Drag and Drop really is. Almost immediately, I understood Koch&#8217;s reaction &#8211; the browser vendors have not implemented all the same features, and there are even a few quirks in how the features that <em>are </em>implemented work.  However, after doing <em>a lot</em> of research, <strong>I found a common denominator that works well</strong>, with the help of a small bit of JavaScript that smooths out the edges.  Despite the implementation flaws, <strong>Future-proof HTML5 Drag and Drop is not too hard for developers to use in their own applications.</strong> This article will explain how to do this step by step with many examples along the way.  By the time you are done, you will be able to write useful  drag and drop scripts of your own like in this example:</p>
<p><a class="exampleLink" href="/tests/dragAndDrop/permissionForm.html#">See an example of HTML5 Drag and Drop in action.</a></p>
<h2>Advantages Over Existing Drag and Drop Implementations</h2>
<p>Koch mentioned in his blog post that &#8220;Web developers MUST NOT (in the sense of RFC 2119) use HTML 5 drag and drop. They should use <a href="http://www.quirksmode.org/js/dragdrop.html">old-school scripts</a> instead&#8221;.  I would argue that developers <em>should</em> use HTML5 drag and drop for the following reasons:</p>
<ul>
<li><strong>JavaScript Framework Independent: </strong>Most other (but not all) drag and drop implementations are tied into 3rd party frameworks like <a href="http://www.dojotoolkit.org/">Dojo</a>, <a href="http://www.prototypejs.org/">Prototype</a> or <a href="http://jquery.com/">jQuery</a>.</li>
<li><strong>Built-in Browser Support: </strong>HTML5 Drag and Drop is supported in Firefox 3.5+, Chrome 3.0+, Safari 3.0+ and Internet Explorer 5.0 (<strong>Note:</strong> that is not a typo &mdash; HTML5 Drag and Drop is based on work done by Microsoft <strong>in 1999</strong>).  Because it is part of HTML5, I assume Opera support should be inevitable.</li>
<li><strong>Integration With Other Web Applications:</strong> the HTML5 specification will allow developers to <em><strong>produce  drag and drop scripts that work across frames, and across browser windows.</strong></em></li>
<li><strong>Integration With Non-Web Applications:</strong> the HTML5 specification also allows users to <em><strong>drag and drop data to and from non-web applications</strong></em></li>
</ul>
<h2>The Basics of Drag and Drop, Step by Step</h2>
<p>In order to save other developers from the headaches I got deciphering cross browser drag and drop, I present the following guide that shows how to do in five easy steps.   Every step will describe a set of related concepts, and will show examples, most of which are built on code from previous steps.  At the end of each step, I will discuss any issues and interesting bits I came across.</p>
<div class="steps">
<h3>Step 1: Defining a Draggable Object</h3>
<p>First you need to define the HTML nodes that you want to drag.  Firefox requires that these nodes have their <code>draggable</code> attribute set to <code>"true"</code>, Internet Explorer requires that the node must be an <code>&lt;a&gt;</code> tag with (the <code>href</code> attribute set) or an <code>&lt;img&gt;</code> tag.</p>
<blockquote class="code">
<pre>&lt;a href="#" id="toDrag" draggable="true"&gt;This is a draggable item&lt;/a&gt;</pre>
</blockquote>
<p>To show how this works, I have written a very simple page with a the above markup in the <code>&lt;body&gt;</code>:</p>
<blockquote class="code">
<pre>&lt;!DOCTYPE html&gt;

&lt;html lang="en"&gt;
    &lt;head&gt;
        &lt;meta name="generator" content="HTML Tidy, see www.w3.org"&gt;

        &lt;title&gt;Test #1: A Simple Draggable Object&lt;/title&gt;

      &lt;script type="text/javascript" src="../../shared/js/EventHelpers.js"&gt;
      &lt;/script&gt;
      &lt;script type="text/javascript" src="../../shared/js/DragDropHelpers.js"&gt;
      &lt;/script&gt;

        &lt;link rel="stylesheet" type="text/css" media="screen" href=
        "css/test1.css"&gt;
    &lt;/head&gt;

    &lt;body&gt;
        &lt;h1&gt;Test #1: A Simple Draggable Object&lt;/h1&gt;

<span class="hilite">        &lt;a href="#" id="toDrag" draggable="true"&gt;This is a
        draggable item&lt;/a&gt;</span>

        &lt;p&gt;Try to drag the red box around. You will see the
        draggable object cloned in every browser except Explorer
        and Chrome.&lt;/p&gt;

        &lt;a href=
        "http://www.useragentman.com/blog/2010/01/10/cross-browser-html5-drag-and-drop/"&gt;
        Go back to the User Agent Man HTML5 Drag and Drop
        article&lt;/a&gt;
    &lt;/body&gt;
&lt;/html&gt;
</pre>
</blockquote>
<p>Note that this HTML page has two scripts in the <code>&lt;head&gt;</code>:</p>
<ul>
<li><strong><code>EventHelpers.js</code>:</strong> this script implements cross-browser event handling routines without the need for a JavaScript framework.  All the examples in this article use it, but feel free to refactor all the code in this article to use a third party framework like Dojo, jQuery or whatever framework you like.</li>
<li><strong><code>DragDropHelpers.js</code>:</strong> among other things that I will get to later, will activate dragging on <code>draggable="true"</code> objects in Safari and Chrome using a built-in copy of Dean Edwards&#8217; <a href="http://dean.edwards.name/my/cssQuery/">cssQuery</a>.  It does this by inserting the following CSS code into the HTML document:<br />
<blockquote class="code">
<pre>[draggable=true] {
  -khtml-user-drag: element;
  -webkit-user-drag: element;
  -khtml-user-select: none;
  -webkit-user-select: none;
}</pre>
</blockquote>
<p>The first two rules allow the dragging of the <code>draggable="true"</code> nodes, while the last two prevent the user from selecting the text within the node (which can cause some unexpected behavior in Webkit browsers).  The <code>-khtml </code>properties work in older versions of Safari, while <code>-webkit</code> ones work in newer versions.  <strong>Without these CSS properties, these nodes will not be draggable when using the Safari web browser</strong></li>
</ul>
<p><a class="exampleLink" href="/tests/dragAndDrop/01-dragObject.html">See Example  #1: a draggable object</a></p>
<p>A couple of notes:</p>
<ol>
<li> You&#8217;ll notice that when you hover the mouse pointer over the draggable item, it will change to <img class="alignnone size-full wp-image-599" title="The  &quot;Move&quot; cursor" src="http://www.useragentman.com/blog/wp-content/uploads/2010/01/cursor-move.gif" alt="The  &quot;Move&quot; cursor" width="24" height="28" />(i.e. I the &#8220;move&#8221; cursor).  This is not the default behavior of the web browser &#8211; it is something I added in <code>DragDropHelpers</code>, since I believe that it&#8217;s a nice visual cue to show users that an object is draggable (if you don&#8217;t want this behavior, it is possible to turn it off in your own scripts by setting <code>DragDropHelpers.showMouseoverCue</code> to false</li>
<li>How draggable objects look in the various browsers varies.  Here are screenshots of how it looks in Windows web browsers (Note: although all screenshots were taken using Windows XP, similar results occur when viewing under Windows Vista or Windows 7):<br />
<table class="screenshots" border="0">
<thead>
<tr>
<th>Firefox (Windows XP)</th>
<th>Safari (Windows XP)</th>
<th>Explorer &amp; Chrome (Windows XP)</th>
</tr>
</thead>
<tbody>
<tr>
<td><img class="alignnone size-full wp-image-514" title="Dragging of a link element, Firefox Windows" src="http://www.useragentman.com/blog/wp-content/uploads/2010/12/dragLink-firefoxWindows.png" alt="[Dragging of a link element, Firefox Windows]" width="180" height="190" /></td>
<td><img class="alignnone size-full wp-image-514" title="Dragging of a link element, Safari Windows" src="http://www.useragentman.com/blog/wp-content/uploads/2010/12/dragLink-safariWindows.png" alt="[Dragging of a link element, Safari Windows]" width="180" height="190" /></td>
<td><img class="alignnone size-full wp-image-514" title="Dragging of a link element, Explorer Windows" src="http://www.useragentman.com/blog/wp-content/uploads/2010/12/dragLink-explorerWindows.png" alt="[Dragging of a link element, Explorer Windows]" width="180" height="190" /></td>
</tr>
</tbody>
</table>
<p>Note the differences between these three browsers:</p>
<ul>
<li>Firefox for Windows shows a cloned version of the draggable object underneath the mouse pointer when the object is being dragged, while Safari displays a grey box with the text &#8220;This is a draggable item&#8221; written inside.  Explorer and Chrome don&#8217;t show any effect at all (We will address this issue later).</li>
<li>Since we have not established <em>where</em> we are going to drag our object, all Windows browsers will change the mouse pointer cursor to <img class="alignnone size-full wp-image-567" title="&quot;Not-Allowed&quot; cursor." src="http://www.useragentman.com/blog/wp-content/uploads/2010/12/cursor_not-allowed.gif" alt="&quot;Not-Allowed&quot; cursor." width="22" height="22" /> (a.k.a. the &#8220;not-allowed&#8221; mouse pointer).  This is the expected behavior, and you will see later that it will help the user know where to drop the object.</li>
</ul>
<p>On OS X, Firefox and Safari look similar to Firefox for Windows, except that the &#8220;not-allowed&#8221; mouse-pointer doesn&#8217;t show up:</p>
<table class="screenshots" border="0">
<thead>
<tr>
<th>Firefox (OS X)</th>
<th>Safari (OS X)</th>
<th>Chrome (OS X)</th>
</tr>
</thead>
<tbody>
<tr>
<td><img class="alignnone size-full wp-image-513" title="Dragging of a link element, Firefox OS X" src="http://www.useragentman.com/blog/wp-content/uploads/2010/12/dragLink-firefoxMac.png" alt="[Dragging of a link element, Firefox Windows]" width="180" height="190" /></td>
<td><img class="alignnone size-full wp-image-514" title="Dragging of a link element, Safari OS X" src="http://www.useragentman.com/blog/wp-content/uploads/2010/12/dragLink-safariMac.png" alt="[Dragging of a link element, Safari OS X]" width="180" height="190" /></td>
<td><img class="alignnone size-full wp-image-653" title="Chrome for Mac" src="http://www.useragentman.com/blog/wp-content/uploads/2010/01/dragLink-chromeMac.png" alt="Chrome for Mac" width="180" height="190" /></td>
</tr>
</tbody>
</table>
<p>The Linux browsers don&#8217;t have the &#8220;not-allowed&#8221; mouse cursor either.  Also, the cloned version of the draggable object isn&#8217;t transparent using the Linux version of Firefox, and Chrome under Linux behaves  pretty much the  same as on the other platforms (Note: all Linux testing was done using Ubuntu 9.10 using the standard Gnome window manager).</p>
<table class="screenshots" border="0">
<thead>
<tr>
<th>Firefox (Ubuntu)</th>
<th>Chrome (Ubuntu)</th>
</tr>
</thead>
<tbody>
<tr>
<td><img class="size-full wp-image-698 alignnone" title="dragLink-firefoxUbuntu" src="http://www.useragentman.com/blog/wp-content/uploads/2010/01/dragLink-firefoxUbuntu.png" alt="Firefox Linux" width="180" height="190" /></td>
<td><img class="size-full wp-image-697 alignnone" title="dragLink-chromeUbuntu" src="http://www.useragentman.com/blog/wp-content/uploads/2010/01/dragLink-chromeUbuntu.png" alt="Chrome Linux" width="180" height="190" /></td>
</tr>
</tbody>
</table>
<p>The fact that Explorer and Chrome don&#8217;t have any visual dragging cues bugged me, so I put a &#8220;fix&#8221; inside <code>DragDropHelpers.js</code> which can be turned on by setting <code>DragDropHelpers.fixVisualCues</code> to true.  Let&#8217;s look at a slightly refactored version of Example #1 where we insert the following code in the <code>&lt;head&gt;:</code></p>
<blockquote class="code">
<pre>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
   &lt;head&gt;
      &lt;title&gt;Test #1: A Simple Draggable Object (with visual cues added to Explorer and Chrome)&lt;/title&gt;
      &lt;script type="text/javascript" src="../../shared/js/EventHelpers.js"&gt;&lt;/script&gt;
      &lt;script type="text/javascript" src="../../shared/js/DragDropHelpers.js"&gt;&lt;/script&gt;
<span class="hilite">      &lt;script type="text/javascript"&gt;
      &lt;!--
      DragDropHelpers.fixVisualCues=true;
      --&gt;
      &lt;/script&gt;</span>

      &lt;link rel="stylesheet" type="text/css" media="screen" href="css/test1.css" /&gt;

   &lt;/head&gt;
   &lt;body&gt;

      &lt;h1&gt;Test #1: A Simple Draggable Object (with visual cues added to Explorer and Chrome)&lt;/h1&gt;

      &lt;a href="#" id="toDrag" draggable="true"&gt;This is a draggable item&lt;/a&gt;

      &lt;p&gt;Try to drag the red box around.  You will see the draggable object cloned in all browsers.&lt;/p&gt;

      &lt;a href="http://www.useragentman.com/blog/2010/01/10/cross-browser-html5-drag-and-drop/"&gt;Go back to the User Agent Man HTML5 Drag and Drop article&lt;/a&gt;

   &lt;/body&gt;
&lt;/html&gt;
</pre>
</blockquote>
</li>
</ol>
<p><a class="exampleLink" href="/tests/dragAndDrop/01a-dragObject.html">See Example #1a, a draggable object with visual cue fix for Explorer and Chrome</a></p>
<p>Voila!  The visual cue now shows up.  I&#8217;ll explain how this works at the end of the article.</p>
<h3>Step 2: Setting Events on the Draggable Object</h3>
<p>Now that you have defined an object as draggable, you should attach some events to it so the browser knows what to do while it is being dragged.  There are three events that a draggable object can fire:</p>
<table class="dataTable" border="0">
<thead>
<tr>
<th>Event name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>dragstart</code></td>
<td>Fires when the user starts dragging of the object.</td>
</tr>
<tr>
<td><code>drag</code></td>
<td>Fires every time the mouse is moved while the object is being dragged.</td>
</tr>
<tr>
<td><code>dragend</code></td>
<td>Fires when the user releases the mouse button while dragging an object.</td>
</tr>
</tbody>
</table>
<p>A developer would attach these events the way they would any other JavaScript event &#8211; I use <code>EventHelpers.addEvent</code>, but one could use jQuery&#8217;s <code>bind()</code> method, prototype&#8217;s <code>Event.observe()</code> or whatever you favourite framework provides for event handling.  Developers can also use the old school inline events (i.e. <code>&lt;a href="#" id="toDrag" draggable="true" <span class="hilite">ondragstart="somefunction();"</span>&gt;This is a draggable item&lt;/a&gt;</code>), but I try to stay away from using those to seperate document structure from behavior.</p>
<p>Let&#8217;s take the example in step 1 and change it so we can log when these events happen to the <code>toDrag</code> node:</p>
<blockquote class="code">
<pre>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
   &lt;head&gt;
      &lt;title&gt;Example #2: a draggable object with events attached &lt;/title&gt;
<span class="hilite">      &lt;script type="text/javascript" src="../../shared/js/sprintf.js"&gt;&lt;/script&gt;</span>
      &lt;script type="text/javascript" src="../../shared/js/EventHelpers.js"&gt;&lt;/script&gt;
      &lt;script type="text/javascript" src="../../shared/js/DragDropHelpers.js"&gt;&lt;/script&gt;

<span class="hilite">      &lt;script type="text/javascript" src="js/02-dragObjectWithEvent.js"&gt;&lt;/script&gt;</span>

      &lt;link rel="stylesheet" type="text/css" media="screen" href="css/test1.css" /&gt;

   &lt;/head&gt;
   &lt;body&gt;

      &lt;h1&gt;Example #2: a draggable object with events attached&lt;/h1&gt;

      &lt;p&gt;Try to drag the red box around.  This page will tell you if the
      object is currently dragging, and will log all &lt;code&gt;dragstart&lt;/code&gt;
      and &lt;code&gt;dragstop&lt;/code&gt; events&lt;/p&gt;

<span class="hilite">      &lt;p&gt;&lt;strong&gt;Is dragging:&lt;/strong&gt; &lt;span id="dragEventNotice"&gt;no&lt;/span&gt;

      &lt;p id="eventLog"&gt;&lt;strong&gt;Event now firing:&lt;/strong&gt;&lt;br /&gt;&lt;span id="eventNotice"&gt;&lt;/span&gt;</span>

      &lt;a class="goBack" href="http://www.useragentman.com/blog/2010/01/10/cross-browser-html5-drag-and-drop/"&gt;Go back to the User Agent Man HTML5 Drag and Drop article&lt;/a&gt;&lt;/p&gt;

      &lt;a href="#" id="toDrag" draggable="true"&gt;This is a draggable item&lt;/a&gt;

   &lt;/body&gt;
&lt;/html&gt;
</pre>
</blockquote>
<p>In the <code>02-dragObjectWithEvent.js</code> script, the <code>dragEventNotice</code> node will be used to report whether the user is dragging the object around, and the <code>eventNotice</code> will be used to log what events the user has fired:</p>
<blockquote class="code">
<pre>var dragObject = new function () {
   var me = this;

   var dragNode;
   var eventNoticeNode, dragEventNoticeNode;

   /* runs when the page is loaded */
   me.init = function () {

      if (EventHelpers.hasPageLoadHappened(arguments)) {
         return;
      }   

      /* The node being dragged */
      dragNode=document.getElementById('toDrag');

      /* The nodes that report to the user what is happening to that node*/
      eventNoticeNode = document.getElementById('eventNotice');
      dragEventNoticeNode = document.getElementById('dragEventNotice');

      /* The drag event handlers */
<span class="hilite">      EventHelpers.addEvent(dragNode, 'dragstart', dragStartEvent);
      EventHelpers.addEvent(dragNode, 'drag', dragEvent);
      EventHelpers.addEvent(dragNode, 'dragend', dragEndEvent);</span>
   }

   /*
    * The dragstart event handler logs to the user when the event started.
    */
<span class="hilite">   function dragStartEvent(e) {
      eventNoticeNode.innerHTML =
         sprintf("&lt;strong&gt;%s&lt;/strong&gt;: Drag Event started.&lt;br /&gt;%s",
            new Date(),  eventNoticeNode.innerHTML);</span>
   }

   /*
    * The drag event reports to the user that dragging is on.
    */
<span class="hilite">   function dragEvent(e) {
      dragEventNoticeNode.innerHTML = "Currently dragging.";
   }</span>

   /*
    * The dragend event logs to the user when the event had finished *and*
    * also reports that dragging has now stopped.
    */
<span class="hilite">   function dragEndEvent(e) {
      eventNoticeNode.innerHTML =
         sprintf("&lt;strong&gt;%s&lt;/strong&gt;: Drag Event stopped.&lt;br /&gt;%s",
            new Date(), eventNoticeNode.innerHTML);
      dragEventNoticeNode.innerHTML = "Dragging stopped."
   }
}</span>

// fixes visual cues in IE and Chrome.
DragDropHelpers.fixVisualCues=true;

EventHelpers.addPageLoadEvent('dragObject.init');</pre>
</blockquote>
<p>Before we get to the drag events, a word about the coding conventions I use for this and all the other code examples in this article:</p>
<ul>
<li>the <code>var me = this </code>line ensures that the script doesn&#8217;t confuse the <code>this </code>keyword of the object with the <code>this </code>keyword inside an event handler.</li>
<li><code>EventHelpers.addPageLoadEvent()</code> (which is part of <code>EventHelpers.js</code>) will execute <code>dragObject.init</code> when the HTML has loaded.  <code>addPageLoadEvent()</code> is based on code from Dean Edwards&#8217; article <a href="http://dean.edwards.name/weblog/2005/09/busted/">The window.onload Problem &#8211; Solved!</a>.  It is similar to jQuery&#8217;s<code> $(document).ready()</code>method and prototype&#8217;s <code>dom:loaded</code> event.</li>
<li>This code uses a JavaScript version of <code>sprintf()</code> that <a href="/blog/2009/12/22/my-favourite-third-party-javascript-libraries/">I had mentioned in a previous blog post</a>.  I have used it in all the remaining examples because I think it makes the code a lot easier to read (however, it is not necessary in order to make HTML5 drag and drop work).</li>
</ul>
<p>Let&#8217;s get back to the drag events — you&#8217;ll notice that I have set the <code>dragstart</code>, <code>drag</code> and <code>dragend</code> events.  When this page is loaded, it will tell you if the draggable object is currently being dragged, and will log all <code>dragstart</code> and <code>dragstop</code> events on-screen. Click on the example link below and see for yourself:</p>
<p><a class="exampleLink" href="/tests/dragAndDrop/02-dragObjectWithEvents.html">See Example #2, a draggable object with events attached</a></p>
<h3>Step 3: Setting Events on the Target Object</h3>
<p>Step 2 showed us how we can drag an object around the screen and know when each drag starts and ends.  Now we need to drop the object. Let&#8217;s define a <strong>drop target</strong> to be <strong>an object where draggable objects can be dropped</strong>.  A drop target can have the following event handlers attached to it:</p>
<table class="dataTable" border="0">
<thead>
<tr>
<th>Event name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>dragenter</code></td>
<td>Fires when a draggable object is <strong>first dragged inside</strong> an object.</td>
</tr>
<tr>
<td><code>dragover</code></td>
<td>Fires everytime a draggable object is <strong>moved inside</strong> an object.  <strong>Note: if you want to allow the draggable object to be <em>dropped </em>inside this object, <em>you must cancel the default behaviour of this event handler.</em></strong></td>
</tr>
<tr>
<td><code>dragleave</code></td>
<td>Fires when a draggable object is <strong>dragged out</strong> of an object.</td>
</tr>
<tr>
<td><code>drop</code></td>
<td>Fired when a draggable object is <strong>dropped into</strong> an object.</td>
</tr>
</tbody>
</table>
<p><strong>If you want an object to become a drop target, you must attach both the <code>dragover</code> and <code>drop</code> events to it.</strong> You may ask &#8220;I understand why I need to implement <code>drop</code> (after all, it is one half of the term &#8220;drag and drop&#8221;) but why do I need <code>dragover</code>?&#8221;  <strong>As stated in the table above, the <code>drop</code> event will not fire unless you cancel the default behaviour of the event target&#8217;s <code>dragover</code> event</strong>.  This point is really important and <strong>your scripts will not work correctly unless you do this</strong>.</p>
<p>You may ask &#8220;Why is there even a <code>dragover</code> event in the first place?  Isn&#8217;t <code>drag</code> sufficient?&#8221; (In his article, Peter-Paul Koch <a href="http://www.quirksmode.org/blog/archives/2009/09/the_html5_drag.html#link8"> asked this question a bit more emphatically that I did</a>).  The <code>dragover</code> event object does contain some useful information, such as <strong>the coordinates of the  mouse pointer inside the event target</strong>, (When I created <code>DragDropHelpers</code>, this information allowed me to fix Explorer and Chrome&#8217;s visual cue issue that I mentioned in step #1).  These coordinates are stored in the properties <code>offsetX</code> and <code>offsetY</code>, <strong>except in Firefox 3.5</strong> which keeps these values inside of the event properties <code>layerX</code> and <code>layerY</code>.  For convenience, <code>DragDropHelpers</code> includes a method called <code>getEventCoords()</code> that will use the appropriate property to get these values (<strong>Note:</strong> <code>layerX</code> and <code>layerY</code> are only accurate when the drop target&#8217;s CSS <code>position</code> propety is set to <code>relative</code>,<code> absolute</code> or <code>fixed</code>).</p>
<p>To show how to add drop functionality to your code, lets take the code from example #2 and add a drop target:</p>
<blockquote class="code">
<pre>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
   &lt;head&gt;
      &lt;title&gt;Example #3: a dragable object with a drop target&lt;/title&gt;
      &lt;script type="text/javascript" src="../../shared/js/sprintf.js"&gt;&lt;/script&gt;
      &lt;script type="text/javascript" src="../../shared/js/EventHelpers.js"&gt;&lt;/script&gt;
      &lt;script type="text/javascript" src="../../shared/js/DragDropHelpers.js"&gt;&lt;/script&gt;

<span class="hilite">      &lt;script type="text/javascript" src="js/03-dragObjectWithTargetObject.js"&gt;&lt;/script&gt;</span>

      &lt;link rel="stylesheet" type="text/css" media="screen" href="css/test1.css" /&gt;

   &lt;/head&gt;
   &lt;body&gt;

      &lt;h1&gt;Example #3: a dragable object with a drop target&lt;/h1&gt;

      &lt;p&gt;Try to drag the red box around and dropping it in the target object.&lt;/p&gt;

      &lt;p&gt;&lt;strong&gt;Is dragging:&lt;/strong&gt; &lt;span id="dragEventNotice"&gt;no&lt;/span&gt;

      &lt;p id="eventLog"&gt;&lt;strong&gt;Event now firing:&lt;/strong&gt;&lt;br /&gt;&lt;span id="eventNotice"&gt;&lt;/span&gt;
      &lt;a class="goBack" href="http://www.useragentman.com/blog/2010/01/10/cross-browser-html5-drag-and-drop/"&gt;Go back to the User Agent Man HTML5 Drag and Drop article&lt;/a&gt;&lt;/p&gt;

      &lt;a href="#" id="toDrag" draggable="true"&gt;This is a draggable item&lt;/a&gt;
<span class="hilite">      &lt;div id="dropTarget"&gt;This is a "target" object&lt;/div&gt;</span>

   &lt;/body&gt;
&lt;/html&gt;
</pre>
</blockquote>
<p>The drop target will be the <code>&lt;div&gt;</code> with an <code>id</code> of <code>dropTarget</code>.   The <code>03-dragObjectWithTargetObject.js</code> script is the same code in example #2 except we add two event handlers:</p>
<ul>
<li>a <code>dragover</code> event that reports where the mouse is inside <code>dropTarget</code></li>
<li>a <code>drop</code> event that reports when the drop happened.</li>
</ul>
<blockquote class="code">
<pre>var dragObject = new function () {
   var me = this;

   var dragNode, targetNode;
   var eventNoticeNode, dragEventNoticeNode;
   me.init = function () {

   	if (EventHelpers.hasPageLoadHappened(arguments)) {
   		return;
   	}	

   	dragNode=document.getElementById('toDrag');
   	targetNode=document.getElementById('dropTarget');
   	eventNoticeNode = document.getElementById('eventNotice');
   	dragEventNoticeNode = document.getElementById('dragEventNotice');

   	/* These are events for the draggable object */
   	EventHelpers.addEvent(dragNode, 'dragstart', dragStartEvent);
   	EventHelpers.addEvent(dragNode, 'drag', dragEvent);
   	EventHelpers.addEvent(dragNode, 'dragend', dragEndEvent);

   	/* These are events for the object to be dropped */
   	<span class="hilite">EventHelpers.addEvent(targetNode, 'dragover', dragOverEvent);</span>
   	<span class="hilite">EventHelpers.addEvent(targetNode, 'drop', dropEvent);</span>

   }

   function dragStartEvent(e) {
   	showMessage("Drag Event started");
   }

   function dragEvent(e) {
   	dragEventNoticeNode.innerHTML = "Currently dragging.&lt;br /&gt;";
   }

   function dragEndEvent(e) {
   	showMessage("Drag Event stopped");
   	dragEventNoticeNode.innerHTML = "Dragging stopped."
   }

<span class="hilite">   function dragOverEvent(e) {
   	var coords = DragDropHelpers.getEventCoords(e);
   	showMessage(sprintf(
   	   "Drag over event happened on node with id %s at coordinate (%d, %d)",
   	   this.id, coords.x, coords.y));
   	EventHelpers.preventDefault(e);
   }</span>

<span class="hilite">   function dropEvent(e) {
   	showMessage("Drop event happened on node with id " + this.id);
   	EventHelpers.preventDefault(e);
   }</span>

   function showMessage(message) {
   	eventNoticeNode.innerHTML =
   		sprintf("&lt;strong&gt;%s&lt;/strong&gt;: %s&lt;br /&gt;%s",
   			new Date(), message, eventNoticeNode.innerHTML);
   }

}

// fixes visual cues in IE and Chrome.
DragDropHelpers.fixVisualCues=true;

EventHelpers.addPageLoadEvent('dragObject.init');</pre>
</blockquote>
<p>(<strong>Note:</strong> <code>EventHelpers.preventDefault(e)</code> does what you&#8217;d expect: it prevents the default behavior of the event handler, similar to prototype&#8217;s <code>Event.stop()</code> or jQuery&#8217;s <code>event.preventDefault()</code>)</p>
<p><a class="exampleLink" href="/tests/dragAndDrop/03-dragObjectAndTargetObject.html">See Example #3: a dragable object with a drop target</a></p>
<p>Note that in the above example, the time that the draggable object&#8217;s <code>dragend</code> event fires and the time that the drag target&#8217;s <code>drop</code> event fires is not consistant among browsers.  Safari and Chrome fire <code>dragend</code> first, while Firefox and Internet Explorer fire <code>drop</code> first.</p>
<p>The two other drop target events, <code>dragenter</code> and <code>dragleave</code> are not absolutely necessary for every script, but let&#8217;s add these events to example #3 anyway to see how they work:</p>
<blockquote class="code">
<pre>var dragObject = new function () {
   var me = this;

   var dragNode, targetNode;
   var eventNoticeNode, dragEventNoticeNode;
   me.init = function () {

      if (EventHelpers.hasPageLoadHappened(arguments)) {
         return;
      }   

      dragNode=document.getElementById('toDrag');
      targetNode=document.getElementById('dropTarget');
      eventNoticeNode = document.getElementById('eventNotice');
      dragEventNoticeNode = document.getElementById('dragEventNotice');

      /* These are events for the draggable object */
      EventHelpers.addEvent(dragNode, 'dragstart', dragStartEvent);
      EventHelpers.addEvent(dragNode, 'drag', dragEvent);
      EventHelpers.addEvent(dragNode, 'dragend', dragEndEvent);

      /* These are events for the object to be dropped */
      EventHelpers.addEvent(targetNode, 'dragover', dragOverEvent);
      EventHelpers.addEvent(targetNode, 'drop', dropEvent);
<span class="hilite">      EventHelpers.addEvent(targetNode, 'dragenter', dragEnterEvent);
      EventHelpers.addEvent(targetNode, 'dragleave', dragLeaveEvent);</span>
   }

   function dragStartEvent(e) {
      showMessage("Drag Event started");
   }

   function dragEvent(e) {
      dragEventNoticeNode.innerHTML = "Currently dragging.&lt;br /&gt;";
   }

   function dragEndEvent(e) {
      showMessage("Drag Event stopped");
      dragEventNoticeNode.innerHTML = "Dragging stopped.";
   }

   function dragOverEvent(e) {
      var coords = DragDropHelpers.getEventCoords(e);

      showMessage(sprintf(
         "Drag over event happened on node with id %s at coordinate (%d, %d)",
         this.id, coords.x, coords.y));

      EventHelpers.preventDefault(e);
   }

   function dropEvent(e) {
      showMessage("Drop event happened on node with id " + this.id);
      EventHelpers.preventDefault(e);

   }

<span class="hilite">   function dragEnterEvent(e) {
      showMessage("Drag Enter event happened on node with id " + this.id);
   }

   function dragLeaveEvent(e) {
      showMessage("Drag Leave event happened on node with id " + this.id);
   }</span>

   function showMessage(message) {
      eventNoticeNode.innerHTML =
         sprintf("&lt;strong&gt;%s&lt;/strong&gt;: %s&lt;br /&gt;%s",
            new Date(), message, eventNoticeNode.innerHTML);
   }

}

// fixes visual cues in IE and Chrome.
DragDropHelpers.fixVisualCues=true;

EventHelpers.addPageLoadEvent('dragObject.init');</pre>
</blockquote>
<p><a class="exampleLink" href="/tests/dragAndDrop/03a-dragEnterDragLeave.html">See Example #3a: a drop target with dragenter and dragleave event handlers</a></p>
<p>(Note that in Firefox 3.5, a <code>dragleave</code> event will fire just before a <code>drop</code> event, which the other browsers don&#8217;t fire <code>dragleave</code> when dropping).</p>
<h3>Step 4: Passing Data Between the Draggable and Target Objects</h3>
<p>Once a draggable object is dropped into a drop target, the two objects can pass information between them using the drop event&#8217;s <code>dataTransfer</code> property.  This property has two methods, <code>setData()</code> and <code>getData()</code>.  In order to pass data between the two, a developer must use <code>setData()</code> during one of the draggable node&#8217;s drag events (e.g. <code>dragstart</code>).  The drop target can then receive this data during one of it&#8217;s events using the <code>getData()</code> method.</p>
<table class="dataTable" border="0">
<thead>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="methodName"><code>setData(dataType, data)</code></td>
<td>
<p>Sets the data that can be shared between the draggable node and the drag target.</p>
<p><strong>Parameters</strong></p>
<ul>
<li><code>dataType</code> &#8211; The type of data that is to be set.  So far, the only cross-browser dataTypes that can be set are &#8216;Text&#8217; and &#8216;Url&#8217;.</li>
<li><code>data</code> &#8211; The data that is going to be set.</li>
</ul>
</td>
</tr>
<tr>
<td class="methodName"><code>getData(dataType)</code></td>
<td>
<p>Gets the data that was previously set by <code>dataTransfer.setData()</code>.  <strong>It can also get data that was set by a <code>dataTransfer.setData()</code> call from another page, another browser window, and <em>another vendor&#8217;s web browser on the same machine</em>.</strong> It also can get data that was set by a drop event of another desktop application (for example, Windows WordPad).</p>
<p><strong>Parameters</strong></p>
<ul>
<li><code>dataType</code> &#8211; The type of data that is to be set.  So far, the only cross-browser dataTypes that can be set are &#8216;Text&#8217; and &#8216;Url&#8217;.</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p><code>setData()</code> takes one string parameter, which is the data you want to share between the draggable object and a drop target.</p>
<p>Let&#8217;s take the code from step #3 and mix it up a bit: instead of having one draggable object, let&#8217;s make four.  I have taken <a href="http://commons.wikimedia.org/wiki/File:The_Fabs.JPG">four photos of the Beatles from the Wikmedia Commons</a> and made them draggable.</p>
<blockquote class="code">
<pre>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
   &lt;head&gt;
      &lt;title&gt;Test 4: setData() and getData()&lt;/title&gt;
      &lt;script type="text/javascript" src="../../shared/js/sprintf.js"&gt;&lt;/script&gt;
      &lt;script type="text/javascript" src="../../shared/js/helpers.js"&gt;&lt;/script&gt;
      &lt;script type="text/javascript" src="../../shared/js/DragDropHelpers.js"&gt;&lt;/script&gt;

<span class="hilite">      &lt;script type="text/javascript" src="js/04-setDataGetData.js"&gt;&lt;/script&gt;</span>

      &lt;link rel="stylesheet" type="text/css" media="screen" href="css/test1.css" /&gt;

   &lt;/head&gt;
   &lt;body&gt;

      &lt;h1&gt;Test 4: &lt;code&gt;setData()&lt;/code&gt; and &lt;code&gt;getData()&lt;/code&gt;&lt;/h1&gt;

<span class="hilite">      &lt;img draggable="true" src="images/george.png" alt="George Harrison" /&gt;
      &lt;img draggable="true" src="images/john.png" alt="John Lennon" /&gt;
      &lt;img draggable="true" src="images/paul.png" alt="Paul McCartney" /&gt;
      &lt;img draggable="true" src="images/ringo.png" alt="Ringo Starr" /&gt;</span>

      &lt;div id="dropTarget"&gt;&lt;span&gt;Drop an image here to find out more information about it.&lt;/span&gt;&lt;/div&gt;

   &lt;/body&gt;
&lt;/html&gt;</pre>
</blockquote>
<p>The script <code>04-setDataGetData.js</code> uses <code>dataTransfer.setData()</code> and <code>.getData()</code> to copy the <code>&lt;img&gt;</code> of the Beatle being dragged, as well as placing the <code>alt</code> attribute&#8217;s contents underneath the image.</p>
<blockquote class="code">
<pre>var dragObject = new function () {
   var me = this;

   var targetNode;
   var eventNoticeNode, dragEventNoticeNode;

   var dataTransferCommentString;

   me.init = function () {

      if (EventHelpers.hasPageLoadHappened(arguments)) {
         return;
      }   

      targetNode=document.getElementById('dropTarget');
      eventNoticeNode = document.getElementById('eventNotice');
      dragEventNoticeNode = document.getElementById('dragEventNotice');

      /* These are events for the draggable objects */
      var dragNodes = cssQuery('[draggable=true]');
      for (var i = 0; i &lt; dragNodes.length; i++) {
         var  dragNode=dragNodes[i]
         EventHelpers.addEvent(dragNode, 'dragstart', dragStartEvent);
      }

      /* These are events for the object to be dropped */
      EventHelpers.addEvent(targetNode, 'dragover', dragOverEvent);
      EventHelpers.addEvent(targetNode, 'drop', dropEvent);
   }

   function dragStartEvent(e) {
<span class="hilite">      e.dataTransfer.setData('Text',
         sprintf('&lt;img src="%s" alt="%s" /&gt;&lt;br /&gt;&lt;p class="caption"&gt;%s&lt;/p&gt;',
            this.src, this.alt, this.alt
         )
      );</span>
   }

   function dragOverEvent(e) {
      EventHelpers.preventDefault(e);
   }

   function dropEvent(e) {
<span class="hilite">      this.innerHTML = e.dataTransfer.getData('Text');</span>
      EventHelpers.preventDefault(e);
   }

}

// fixes visual cues in IE and Chrome.
DragDropHelpers.fixVisualCues=true;

EventHelpers.addPageLoadEvent('dragObject.init');</pre>
</blockquote>
<p><a class="exampleLink" href="/tests/dragAndDrop/04-setDataGetData.html">See Example #4: using setData() and getData()</a></p>
<p>As previously mentioned the data that is set in setData() can be read in other applications.  If you are in Windows, open up WordPad and drag one of the images into it.  You&#8217;ll see the data that was given to setData() during the dragstart event.</p>
<p>This interoperability with the operating system will allow developers to do some very interesting things which are out of the scope of this article.  I will, however, want to explore this in future postings.</p>
<h3>Step 5: Drag  and  Drop Effects</h3>
<p>In a traditional desktop application, you can use drag and drop to copy objects, move objects, and create links to things.  You can use the HTML5 drag and drop events to do this as well, but it would be nice to give the user visual cues to show what kind of action a draggable object can do, and what kind of action a drop target can accept.  It would also be nice to only allow &#8220;copy objects&#8221; to only drop on drop targets that are programmed to accept them.</p>
<p>These features can be implemented using <code>e.dataTransfer.effectAllowed</code> on the draggable object and <code>e.dataTransfer.dropEffect()</code>on the drop target:</p>
<table class="dataTable" border="0">
<thead>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>e.dataTransfer.effectAllowed</code></td>
<td>Sets the type of effect a draggable object is allowed to make.  Valid values are  <code>copy</code>, <code>move</code>, <code>link</code>, <code>copyMove</code>, <code>copyLink</code>, <code>linkMove</code>, <code>all</code>, and <code>none</code>.</td>
</tr>
<tr>
<td><code>e.dataTransfer.dropEffect</code></td>
<td>Sets the type of effect a drop target is allowed to accept.  Valid effects include <code>copy</code>, <code>move</code>, and <code>link</code>.</td>
</tr>
</tbody>
</table>
<p>When these are set correctly, drag and drop will only work when the draggable object&#8217;s <code>effectAllowed</code> and the drop target&#8217;s <code>dropEffect</code> are compatible.  To illustrate this, let&#8217;s first change the <code>dragstart</code> and <code>dragover</code> events in example #4 to do the <code>copy</code> effect:</p>
<blockquote class="code">
<pre>   function dragStartEvent(e) {
<span class="hilite">      e.dataTransfer.effectAllowed="copy";</span> 

      e.dataTransfer.setData('Text',
         sprintf('&lt;img src="%s" alt="%s" /&gt;&lt;br /&gt;&lt;p class="caption"&gt;%s&lt;/p&gt;',
            this.src, this.alt, this.alt
         )
      );
   }

   function dragOverEvent(e) {
<span class="hilite">      e.dataTransfer.dropEffect = "copy";</span>
      EventHelpers.preventDefault(e);
   }</pre>
</blockquote>
<p><a class="exampleLink" href="/tests/dragAndDrop/05-dataTransfer.html">Example #5: matching drag and drop effects</a></p>
<p>Note that unlike <a href="/tests/dragAndDrop/04-setDataGetData.html">example #4</a>, the mouse pointer has changed from the copy icon (in Windows, <img class="alignnone size-full wp-image-616" title="Windows Copy Icon" src="http://www.useragentman.com/blog/wp-content/uploads/2010/01/copyWindows.gif" alt="[Windows Copy Icon]" width="23" height="32" />) to the move icon (<img class="alignnone size-full wp-image-615" title="Windows Move Icon" src="http://www.useragentman.com/blog/wp-content/uploads/2010/01/moveWindows.gif" alt="[Windows Move Icon]" width="13" height="27" />).</p>
<p>Now let&#8217;s change the code so that the draggable object and the drop target don&#8217;t have matching effects:</p>
<blockquote class="code">
<pre>   function dragStartEvent(e) {
<span class="hilite">      e.dataTransfer.effectAllowed="copy";</span> 

      e.dataTransfer.setData('Text',
         sprintf('&lt;img src="%s" alt="%s" /&gt;&lt;br /&gt;&lt;p class="caption"&gt;%s&lt;/p&gt;',
            this.src, this.alt, this.alt
         )
      );
   }

   function dragOverEvent(e) {
<span class="hilite">      e.dataTransfer.dropEffect = "move";</span>
      EventHelpers.preventDefault(e);
   }</pre>
</blockquote>
<p><a class="exampleLink" href="/tests/dragAndDrop/05a-dataTransferNoMatch.html">See Example #5a: unmatching drag and drop effects</a></p>
<p>You&#8217;ll see that the user is not able to drop the image on the drop target.</p>
<p><strong>Update (Jan 28, 2010):</strong>  There is a documented bug in Safari and Chrome for Windows where <a href="http://code.google.com/p/chromium/issues/detail?id=14654">drag and drop will not occur if <code>effectAllowed</code> and <code>dropEffect</code> are set to <code>move</code></a>.  This bug does not occur in the Mac editions of these browsers.  </p>
</div>
<h2>A More Complex Example</h2>
<p>Let&#8217;s take all the information we have gathered and make a &#8220;real-world&#8221; script. Let&#8217;s say you were asked to create a &#8220;user entitlement&#8221; administration widget for a website.  The widget will have three entitlement catagories: &#8220;Unassigned Users&#8221;, &#8220;Restricted Users&#8221; (e.g. users who have restricted access to the website) and &#8220;Power Users&#8221; (e.g. users who would have administration access to a website):</p>
<div id="attachment_684" class="wp-caption aligncenter" style="width: 403px"><img class="size-full wp-image-684" title="permissionFormScreenshot" src="http://www.useragentman.com/blog/wp-content/uploads/2010/01/permissionFormScreenshot1.png" alt="Screenshot of the user entitlement screen we want to implement" width="393" height="185" /><p class="wp-caption-text">Screenshot of the user entitlement screen we want to implement</p></div>
<p>It should be rather easy for an administrator to drag and drop users back and forth between entitlement &#8220;buckets&#8221; in order to elevate or lower a users credentials.</p>
<p>Let&#8217;s go through the steps we established above to implement this script.</p>
<div class="steps">
<h3>Step 1: Defining a Draggable Objects</h3>
<p>First let&#8217;s take a look at the table in the HTML:</p>
<blockquote class="code">
<pre>&lt;table&gt;
    &lt;thead&gt;
        &lt;tr&gt;
            &lt;th&gt;Unassigned Users&lt;/th&gt;
            &lt;th&gt;Restricted Users&lt;/th&gt;
            &lt;th&gt;Power Users&lt;/th&gt;
        &lt;/tr&gt;
    &lt;/thead&gt;

    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td id="unassignedUsers"&gt;
            	&lt;a href="#" draggable="true"&gt;Moe Howard&lt;/a&gt;
		&lt;a href="#" draggable="true"&gt;Curly Howard&lt;/a&gt;
		&lt;a href="#" draggable="true"&gt;Shemp Howard&lt;/a&gt;
            	&lt;a href="#" draggable="true"&gt;Larry Fine&lt;/a&gt;
	    &lt;/td&gt;

            &lt;td id="restrictedUsers"&gt;
            &lt;/td&gt;

            &lt;td id="powerUsers"&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
    &lt;tfoot&gt;
	&lt;td id="unassignedUsersHelp"&gt;
	  Drag a user from this list to another list to change the
	  user's permissions.
	&lt;/td&gt;
	&lt;td id="restrictedUsersHelp"&gt;
	  Dragging user here will give this user restricted
	  permissions.
	&lt;/td&gt;
	&lt;td id="powerUsersHelp" &gt;
	  Dragging a user here will give this user power user access.
	&lt;/td&gt;
    &lt;/tfoot&gt;
&lt;/table&gt;</pre>
</blockquote>
<p>(Note that the contents in the <code>tfoot</code> node are hidden by CSS).</p>
<h3>Step 2: Setting Events on the Draggable Objects</h3>
<p>The &#8220;users&#8221; are draggable objects.  In the script, we find all these nodes using Dean Edwards&#8217; <a href="http://dean.edwards.name/my/cssQuery/">cssQuery</a> and  set <code>dragstart</code> and <code>dragend</code> event handlers on each of them (Note: cssQuery allows us to select nodes by CSS selector, similar to the built-in functionality inside jQuery).</p>
<blockquote class="code">
<pre>userNodes = cssQuery('[draggable=true]');
for (var i=0; i&lt;userNodes.length; i++) {
   EventHelpers.addEvent(userNodes[i], 'dragstart', userDragStartEvent);
   EventHelpers.addEvent(userNodes[i], 'dragend', userDragEndEvent);
}</pre>
</blockquote>
<p>It then keeps track of the current node being dragged in the object variable <code>currentlyDraggedNode</code> and makes that node transparent by making it a member of the <code>draggedUser</code> class, which the page&#8217;s stylesheet defines as transparent.</p>
<blockquote class="code">
<pre>function userDragStartEvent(e) {
   currentlyDraggedNode = this;
   currentlyDraggedNode.className = 'draggedUser';
}</pre>
</blockquote>
<p>The <code>dragend</code> event removes the transparency of the <code>currentlyDraggedNode</code>:</p>
<blockquote class="code">
<pre>function userDragEndEvent(e) {
   currentlyDraggedNode.className = '';
}</pre>
</blockquote>
<h3>Step 3: Setting Events on the Target Objects</h3>
<p>All the table cells in the <code>&lt;tbody&gt;</code> are drop targets, so we use cssQuery again to grab all those nodes and set the appropriate events.</p>
<blockquote class="code">
<pre>userListNodes = cssQuery('.userList');

for (var i=0; i&lt;userListNodes.length; i++) {
   var userListNode = userListNodes[i];
   EventHelpers.addEvent(userListNode, 'dragover', cancel);
   EventHelpers.addEvent(userListNode, 'dragleave', userDragLeaveListEvent);
   EventHelpers.addEvent(userListNode, 'drop', userDropListEvent);
   EventHelpers.addEvent(userListNode, 'dragenter', userDragOverListEvent);
}</pre>
</blockquote>
<p>The most important event is the <code>drop</code> event handler.  This event handler takes the <code>currentlyDraggedNode</code>, removes it from its current table cell (using <code>removeChild()</code>) and  drops it into the drop target (using <code>appendChild()</code>).</p>
<blockquote class="code">
<pre>function setHelpVisibility(node, isVisible) {
   var helpNodeId = node.id + "Help";
   var helpNode = document.getElementById(helpNodeId);

   if (isVisible) {
      helpNode.className =  'showHelp';
   } else {
      helpNode.className =  '';
   }
}

function userDropListEvent(e) {
   currentlyDraggedNode.parentNode.removeChild(currentlyDraggedNode);
   this.appendChild(currentlyDraggedNode);
   setHelpVisibility(this, false);
   userDragEndEvent(e);
}</pre>
</blockquote>
<p>They show the contents of the table cell below it by making it a member of the class <code>showHelp</code>.  They also</p>
<p>prevent the <code>dragover</code> default behaviour so that <code>drop</code> events will fire in the drop target.</p>
<blockquote class="code">
<pre>function userDragOverListEvent(e) {
   setHelpVisibility(this, true);
   EventHelpers.preventDefault(e);
}</pre>
</blockquote>
<p>The <code>dragleave</code> re-hides the contents of the table cell below it.</p>
<blockquote class="code">
<pre>function userDragLeaveListEvent(e) {
  setHelpVisibility(this, false);
}</pre>
</blockquote>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 4921px; width: 1px; height: 1px;">
<pre>function userDragEndEvent(e) {
   currentlyDraggedNode.className = '';
}</pre>
</div>
<h3>Steps 4 and 5</h3>
<p>We do not actually pass any data between the draggable object and the drag target — when the <code>drop</code> event occurs, the draggable object is moved from one column to another without the need of any <code>dataTransfer</code> data.  The drag and drop effects were already handled in step 3, so we are all done.</p>
<p><a class="exampleLink" href="/tests/dragAndDrop/permissionForm.html">See the above example in action</a></p>
</div>
<h2>Drag and Drop Between Frames</h2>
<p>Using the above information, it is also possible to drag and drop objects between frames (this is something that I don&#8217;t think any old school drag and drop script can do).  I made an example below, and I leave it as an exercise to the reader to go through the code and figure out how it works.</p>
<p><a class="exampleLink" href="/tests/dragAndDrop/05a-crossFrameSetData/">See the inter-frame drag and drop example in action</a></p>
<h2>Cross-Browser Issues I Have Seen</h2>
<p>These are the cross-browser issues I know of so far.  I will update this list with others I find in the future.</p>
<ul>
<li>in Firefox 3.5, a <code>dragleave</code> event will fire just before a <code>drop</code> event, which the other browsers don’t fire <code>dragleave</code> when dropping.</li>
<li>the time that the draggable object’s <code>dragend</code> event fires and the time that the drag target’s <code>drop</code> event fires is not consistant among browsers. Safari and Chrome fire <code>dragend</code> first, while Firefox and Internet Explorer fire <code>drop</code> first.</li>
<li>According to <a href="http://www.alertdebugging.com/drag-and-drop-bugs/">Francisco Tolmasky</a>, <a href="http://www.alertdebugging.com/drag-and-drop-bugs/"><code>setData()</code> cannot be called during drag events in Firefox</a>.  Hopefully this will be fixed in a future release of the browser.</li>
<li><code>DragDropHelpers</code> implements a workaround for Explorer so it can drag <em>any</em> object around. However, I did not use this functionality in any of the examples because it exposes a problem with <a href="http://lists.apple.com/archives/web-dev/2009/Jul/msg00042.html">Safari not being able to drag an object correctly when the user initiates the drag on the text inside it</a>.  This problem doesn&#8217;t happen with text inside of links, but with text inside other nodes (like a <code>&lt;div&gt;</code> tag).  I understand this problem has been fixed in the Safari nightly builds, so I left the functionality in the DragDropHelpers library for future use.</li>
<li>DragDropHelpers.js &#8220;fixes&#8221; the dragging visual cues in Explorer and Chrome by:
<ul>
<li>making a transparent and absolutely positioned clone of a draggable object when it&#8217;s <code>dragstart</code> event is fired</li>
<li>moving the cloned object near the mouse when the <code>&lt;body&gt;</code>&#8216;s <code>drag</code> event is fired.</li>
<li>destroying the clone when draggable object&#8217;s <code>dragend</code> event is fired.</li>
</ul>
<p>I didn&#8217;t turn it on by default because I am not sure when (or if) this problem will be fixed in Internet Explorer or Chrome.  I also doesn&#8217;t work well when dragging objects from one window or frame to another, since the cloned visual cue can&#8217;t jump from page to page.  Feel free to use it (or not) as you see fit.</li>
<li>As mentioned previously, because of a <a href="http://code.google.com/p/chromium/issues/detail?id=14654">bug in Webkit</a>, drag and drop will not occur if <code>effectAllowed</code> and <code>dropEffect</code>  are set to <code>move</code> in Safari 4.0.4.  Hopefully this will be fixed in a future version of Webkit.</li>
</ul>
<h2>Conclusion</h2>
<p>HTML5 drag and drop will be an important part of our front-end toolkit.  Even though the flavors that browser-vendors offer today are incomplete, it is possible to smooth out these flaws to produce useful web applications.  What I have covered here only scratches the surface &#8211; there are more properties and methods that some of browsers offer that can be used to further enhance the drag and drop experience.   But I have been working on this blog entry way to long, and my wife is giving me that &#8220;what the hell are you doing up at this hour&#8221; look, so I think I&#8217;ll stop here for now.</p>
<h2>Download</h2>
<p><code>DragDropHelpers</code>, and all code used in this article can be downloaded below.</p>
<p><a class="exampleLink" href="/downloads/DragDropHelpers-1.0a.zip">DragDropHelpers.js v.1.0a and sample code.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2010/01/10/cross-browser-html5-drag-and-drop/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>My Favourite Third Party JavaScript Libraries</title>
		<link>http://www.useragentman.com/blog/2009/12/22/my-favourite-third-party-javascript-libraries/</link>
		<comments>http://www.useragentman.com/blog/2009/12/22/my-favourite-third-party-javascript-libraries/#comments</comments>
		<pubDate>Tue, 22 Dec 2009 22:15:23 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=433</guid>
		<description><![CDATA[Blogging has been a powerful tool for me to publicize code that I have written.  Not only can I announce code that I want to release, I am always complimented by the fact that others like to share what they read here as well. Over the years, however, I have found bits of code others [...]]]></description>
			<content:encoded><![CDATA[<div>
<div id="attachment_453" class="wp-caption alignleft" style="width: 260px"><img class="size-full wp-image-453" title="JavaScript" src="http://www.useragentman.com/blog/wp-content/uploads/2009/12/JavaScript.png" alt="&lt;span&gt;Source: remix of images created by &lt;a href=" width="250" height="188" /><p class="wp-caption-text">Source: remix of images created by Everaldo Coelho and Wikimedia Commons user S.Möller.</p></div>
<p>Blogging has been a powerful tool for me to publicize code that I have written.  Not only can I announce code that I want to release, I am always complimented by the fact that <strong>others like to share what they read here as well. </strong>Over the years, however, I have found bits of code others have written that have found irreplaceable in my web developer toolkit.  Some of them are popular, but others are either obscure or not talked about at all.  In order to give back to those who have unknowingly helped me do my job in the last decade, I am publishing the first in what hope is a series of articles about 3rd party JavaScript libraries.  If anyone else would like to add to this list, please feel free to do so in the comment area below &#8211; I&#8217;d love to hear what others find as useful as what I have listed here.</p>
<h2>Object Oriented Timeouts</h2>
<p>I start off with a script that has been around for a while but to my knowledge is hardly ever talked about.   It concerns <a title="&quot;Tutorial: JavaScript Timers with setTimeout and setInterval&quot; from elated.com" href="http://www.elated.com/articles/javascript-timers-with-settimeout-and-setinterval/">Timeouts</a> &#8211; which are quite important in this             day-and-age of the  			&#8220;nifty-Web-2.0-animated-fade-in-and-out-effect&#8221;. When I             starting coding JavaScript back in the mid-1990&#8242;s, <code>setTimeout()</code> and             <code>setInterval()</code> did what I needed them to do &#8211; pause the application logic for a specified amount of time. However, when I starting to use the object-oriented features of JavaScript,  			I found a few problems:</p>
<ul>
<li><code>setTimeout()</code>and <code>setInterval()</code> both lose track of scope                 when calling a method of an object</li>
<li><code>setTimeout()</code>and <code>setInterval()</code> can only pass strings                 and numbers to methods, <strong>not</strong> an                 arbitrary object.</li>
<li>the function call passed to <code>setTimeout()</code>and <code>setInterval()</code>is passed as a string.   Parameters of the function call must be inserted by using ugly string concatenation:</li>
</ul>
<blockquote class="code">
<pre>setTimeout('fadeInLayer(' + (n+50).toString() +')');</pre>
</blockquote>
<p>However, <strong>back in 2003</strong>, a user named             “algorithm” on <a href="http://www.codingforums.com/">Coding Forums</a> came up             with a great solution for <a href="http://www.codingforums.com/archive/index.php/t-10531.html"> Object Oriented Timeouts</a>. Timeouts can now be done             with objects and with a more elegant syntax:</p>
<blockquote class="code">
<pre>function AjaxDialogue() {
   var me = this;

   // declaration of Timer object.
   me.timer = new Timer(me);

   // a timeout function using the Timer object:
   me.fadeInLayer = function (n, layerOpened, onFadeInEvent){

      ....

      /*
       * This call will set the opacity level of the node layeredOpened to n
       * percent
       */
      CSSHelpers.setOpacity(layerOpened, n);

      if (n &lt; 100) {

         /*
          * setting a timeout of 10 milliseconds on the *public* method fadeInLayer() with the
          * parameters n+50, layerOpened, and onFadeInEvent.  Note only the first parameter
          * is not an object.
          */
         me.timer.setTimeout('fadeInLayer', 10, n+50, layerOpened, onFadeInEvent);

      }
   }
}</pre>
</blockquote>
<p>The question is: <strong>who <em>is</em> this &#8220;algorithm&#8221; person?</strong> This is brilliant code and should be credited             correctly.  It should also have a better home than just a forum  			posting.</p>
<h2>Calendar Widget</h2>
<p><a href="http://en.wikipedia.org/wiki/HTML5">HTML5</a> will have date input tags (i.e. <code>&lt;input type="date"             /&gt;</code>), complete will pop-up calendars, but until it is implemented by all browser vendors,             what is a developer to do when they want users to input             dates in a user friendly way? The best calendar widget I have found is <a href="http://www.dynarch.com/projects/calendar/old/">dynarch.com&#8217;s             Ex-“Coolest” DHTML Calendar</a>. Although             they have a <a href="http://localhost/bin/myTemplate.cgi/%3Cbr%20/%3E%20http://www.dynarch.com/projects/calendar/"> cooler version</a>, I like the former one more because             it was released under the <a href="http://www.gnu.org/licenses/lgpl.html">GNU Lesser             Public License</a>, so it is free as in beer as well as             in freedom.</p>
<h2>Querystring Parsing and Ajax Form Data             Submission</h2>
<p>I always found it odd that there is no built-in method in             JavaScriptto <strong>grab </strong> <strong>form data from the query string from a web page&#8217;s URL.</strong> <a href="http://adamv.com/dev/javascript/querystring">Adam             Vandenberg&#8217;s Querystring Object</a> filled in this gap with a simple 			script that gets this job done.  Suppose your web page had the following 			URL:</p>
<blockquote class="shell">
<pre>http://me.com/mypage.html?page=3&amp;itemsPerPage=10&amp;query=Biker+Babes</pre>
</blockquote>
<p>To tell JavaScript to retrieve the value inside the CGI variable 			<code>query</code>, use the following code:</p>
<blockquote class="code">
<pre>var qs = new Querystring();
var message = qs.get('query');</pre>
</blockquote>
<p>But how about if you have <strong>data in a  			form and you want to  			submit it using Ajax</strong> instead of the traditional  			post-to-the-server-and-retrieve-from-the-server way?  Matthew Eernisse&#8217;s             <a href="http://localhost/bin/myTemplate.cgi/thirdParty.html?templateRoot=useragentman">formData2QueryString()</a> will construct a query string 			from a form so you can use with the XMLHttpRequest Object.</p>
<blockquote class="code">
<pre>var queryString = formData2QueryString(form);

req=new new XMLHttpRequest();

req.onreadystatechange(myFunc);

req.open("GET", "/path/to/ajaxCall?" + queryString, true);</pre>
</blockquote>
<h2>Logging</h2>
<p>In any language, logging and debugging are necessary when it comes to  			discovering what is wrong with your code.  While debuggers like  			<a href="http://localhost/bin/myTemplate.cgi/thirdParty.html?templateRoot=useragentman#">Firebug</a> are great for stepping into code line by 			line and understanding why an algorithm isn&#8217;t working right, it is  			sometimes more desirable to dump variables into a log, especially when trying to debug <a href="http://www.the-art-of-web.com/javascript/ajax-race-condition/">race conditions</a>.  Logging is also useful when you are too lazy to open a debugger but you don&#8217;t want your code bogged down by <code>window.alert()</code>&#8216;s</p>
<p>My favourite 			JavaScript logger is <a href="http://earthcode.com/blog/2005/12/jslog.html">Andre             Lewis&#8217; JSLog</a> . It doesn&#8217;t rely on a specific             JavaScript framework, and it also stays out of the way until I need it  			— it starts off as a             small yellow box in the top left corner of the             application&#8217;s page, and only shows up when I click on it.</p>
<h2>Ajax History and Bookmarking</h2>
<p>After Google Maps came on the scene, a few usability experts pointed out the drawbacks of a lot of &#8220;Ajax&#8221; Applications:</p>
<ul>
<li><strong>Ajax breaks bookmarking: </strong>when users click on a link that results in an Ajax call that changes the content on the screen, users may wish to bookmark the results, and will be disappointed to realize that they didn&#8217;t really bookmark the result of the Ajax call.</li>
<li><strong>Ajax breaks browser history: </strong>when users click on a link that results in an Ajax call that changes the content on the screen, they may intuitively click the back button in order return to the page&#8217;s state, ande will be frustrated when this doesn&#8217;t happen.</li>
</ul>
<p><a href="http://code.google.com/p/reallysimplehistory/">Really             Simple History (RSH): Ajax history and bookmarking             library</a>, developed by <a href="http://codinginparadise.org/">Brad Neuberg</a> and <a href="http://www.briandillard.com/">Brian             Dillard</a>, fixes these issues by storing data inside an JavaScript &#8220;cache&#8221; so that application state can be bookmarked and so that the back button can be used to return your application to an earlier state.  I have used this library on a number of Ajax heavy applications and it works extremely well.</p>
<h2>Fixing IE</h2>
<p>Although <a href="http://dean.edwards.name/IE7/">Dean             Edwards&#8217; /ie7/</a> is not perfect, it does fix a lot of CSS issues with elderly versions of IE.  I use it as one of many utilities in my toolbox when working with Internet Explorer.  It is an awesome piece of work and since Edwards is well known in the JavaScript community, the only thing I can really add that hasn&#8217;t been said before is &#8220;<a href="http://vids.myspace.com/index.cfm?fuseaction=vids.individual&amp;videoid=1276185">Rispek</a>&#8220;.</p>
<h2>sprintf()</h2>
<p>I started off as a C programmer, and when I first started coding in JavaScript, I was happy with it&#8217;s &#8220;C-like&#8221; syntax.  The thing I missed most from the C-world was (and is) JavaScript&#8217;s lack of a <a href="http://en.wikipedia.org/wiki/Printf"><code>sprintf()</code> function</a>, which makes the task of formatting strings quite easy.  <code>sprintf()</code> is more powerful and             produces more human-legable code than using the <code>+</code> JavaScript&#8217;s operator.</p>
<p><a href="http://www.klproductions.com/">K&amp;L             Productions</a> has produced a very good version <a href="http://omino.com/sw/ominoAdobeScriptsSuite/shared/sprintf.jsx"> JavaScript implementation of sprintf</a> that I use             regularly. There are others, but this one is the most complete version 			I have found and works well enough that I haven&#8217;t found a reason to  			change it. Perhaps it would be worthy  			of a future blog post to compare implementations to see which             performs the best.</div>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2009/12/22/my-favourite-third-party-javascript-libraries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
