<?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>Lea Verou &#187; Original</title>
	<atom:link href="http://lea.verou.me/category/original/feed/" rel="self" type="application/rss+xml" />
	<link>http://lea.verou.me</link>
	<description>Life at the bleeding edge (of web standards)</description>
	<lastBuildDate>Thu, 02 Feb 2012 14:08:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Exactly how much CSS3 does your browser support?</title>
		<link>http://lea.verou.me/2012/02/exactly-how-much-css3-does-your-browser-support/</link>
		<comments>http://lea.verou.me/2012/02/exactly-how-much-css3-does-your-browser-support/#comments</comments>
		<pubDate>Thu, 02 Feb 2012 13:18:56 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Apps & scripts]]></category>
		<category><![CDATA[Original]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[standards]]></category>

		<guid isPermaLink="false">http://lea.verou.me/?p=1562</guid>
		<description><![CDATA[This project started as an attempt to improve dabblet and to generate data for the book chapter I&#8217;m writing for Smashing Book #3. I wanted to create a very simple/basic testsuite for CSS3 stuff so that you could hover on a e.g. CSS3 property and you got a nice browser support popup. While I didn&#8217;t achieve [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2012%252F02%252Fexactly-how-much-css3-does-your-browser-support%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FygJdaT%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Exactly%20how%20much%20CSS3%20does%20your%20browser%20support%3F%22%20%7D);"></div>
<p><a href="http://lea.verou.me/wp-content/uploads/2012/02/Screen-shot-2012-02-02-at-14.20.15-.png"><img class="alignleft size-medium wp-image-1563" title="Screen shot 2012-02-02 at 14.20.15" src="http://lea.verou.me/wp-content/uploads/2012/02/Screen-shot-2012-02-02-at-14.20.15--300x187.png" alt="" width="300" height="187" /></a>This project started as an attempt to improve <a href="http://dabblet.com" target="_blank">dabblet</a> and to generate data for the book chapter I&#8217;m writing for Smashing Book #3. I wanted to create a very simple/basic testsuite for CSS3 stuff so that you could hover on a e.g. CSS3 property and you got a nice browser support popup. While I didn&#8217;t achieve that (turns out BrowserScope doesn&#8217;t do that kind of thing), I still think it&#8217;s interesting as a spin-off project, especially since the results will probably surprise you.</p>
<h3>How it works</h3>
<p>css3test (very superficially) tests pretty much everything in the specs mentioned on the sidebar (not just the popular widely implemented stuff). You can click on every feature to expand it and see the exact the testcases run and whether they passed. <strong>It only checks what syntax the browser recognizes, which doesn&#8217;t necessarily mean it will work correctly when used.</strong> WebKit is especially notorious for cheating in tests like this, recognizing stuff it doesn&#8217;t understand, like the values &#8220;round&#8221; and &#8220;space&#8221; for background-repeat, but the cheating isn&#8217;t big enough to seriously compromise the test.</p>
<p><strong>Whether a feature is supported with a prefix or not doesn&#8217;t matter for the result.</strong> If it&#8217;s supported without a prefix, it will test that one. If it&#8217;s supported only with a prefix, it will test the prefixed one. For properties especially, if an unprefixed one is supported, it will be used in all the tests.</p>
<p><strong>Only stuff that&#8217;s in a W3C specification is tested.</strong> So, please don&#8217;t ask or send pull requests for proprietary things like -webkit-gradient() or -webkit-background-clip: text; or -webkit-box-reflect and so on.</p>
<p><strong>Every feature contributes the same to the end score</strong>, as well as to the score of the individual spec, regardless of the number of tests it has.</p>
<h3>Crazy shit</h3>
<p>Chrome may display slightly different scores (1% difference) across pageloads. It seems that for some reason, it fails the tests for border-image completely on some pageloads, which doesn&#8217;t make any sense. Whoever wants to investigate, I&#8217;d be grateful.</p>
<h3>Browserscope</h3>
<p>This is the first project of mine in which I&#8217;ve used <a href="http://www.browserscope.org/user/settings" target="_blank">browserscope</a>. This means that your results will be sent over to its servers and aggreggated. When I have enough data, I&#8217;m gonna built a nice table for everyone to see <img src='http://lea.verou.me/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  In the meantime, check the <a href="http://www.browserscope.org/browse?category=usertest_agt1YS1wcm9maWxlcnINCxIEVGVzdBidzawNDA" target="_blank">results</a> page.</p>
<h3>It doesn&#8217;t work on my browser, U SUCK!</h3>
<p>The test won&#8217;t work on dinosaur browsers like IE8, but who cares measuring their CSS3 support anyway? &#8220;For a laugh&#8221; isn&#8217;t a good enough answer to warrant the time needed.</p>
<p>If you find a bug, please remember you didn&#8217;t pay a dime for this before nagging. Politely report it on Github, or even better, fix it and send a pull request.</p>
<h3>Why did you build it?</h3>
<p>To motivate browsers to support the less hyped stuff, because I&#8217;m tired of seeing the same things being evangelized over and over. There&#8217;s much more to CSS3.</p>
<h3>Current results</h3>
<p>At the time of this writing, these are the results for the major modern browsers:</p>
<ul>
<li>Chrome Canary, WebKit nightlies, Firefox Nightly:<strong> 64%</strong></li>
<li>Chrome, IE10PP4: <strong>63%</strong></li>
<li>Firefox 10: <strong>61%</strong></li>
<li>Safari 5.1, iOS5 Safari: <strong>60%</strong></li>
<li>Opera 11.60: <strong>56%</strong></li>
<li>Firefox 9: <strong>58%</strong></li>
<li>Firefox 6-8: <strong>57%</strong></li>
<li>Firefox 5, Opera 11.1 &#8211; 11.5: <strong>55%</strong></li>
<li>Safari 5.0: <strong>54%</strong></li>
<li>Firefox 4: <strong>49%</strong></li>
<li>Safari 4:<strong> 47%</strong></li>
<li>Opera 10:<strong> 45%</strong></li>
<li>Firefox 3.6: <strong>44%</strong></li>
<li>IE9: <strong>39%</strong></li>
</ul>
<p>Enjoy! <a class="view-demo" href="http://css3test.com" target="_blank">css3test.com</a> <a class="view-demo" href="https://github.com/LeaVerou/css3test" target="_blank">Fork css3test on Github</a> <a class="view-demo" href="http://www.browserscope.org/browse?category=usertest_agt1YS1wcm9maWxlcnINCxIEVGVzdBidzawNDA" target="_blank">Browserscope results</a></p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2012/02/exactly-how-much-css3-does-your-browser-support/feed/</wfw:commentRss>
		<slash:comments>34</slash:comments>
		</item>
		<item>
		<title>Introducing dabblet: An interactive CSS playground</title>
		<link>http://lea.verou.me/2011/12/introducing-dabblet-an-interactive-css-playground/</link>
		<comments>http://lea.verou.me/2011/12/introducing-dabblet-an-interactive-css-playground/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 23:58:29 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Apps & scripts]]></category>
		<category><![CDATA[Original]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[dabblet]]></category>

		<guid isPermaLink="false">http://lea.verou.me/?p=1471</guid>
		<description><![CDATA[I loved JSFiddle ever since I first used it. Being able to test something almost instantly and without littering my hard drive opened new possibilities for me. I use it daily for experiments, browser bug testcases, code snippet storage, code sharing and many other things. However, there were always a few things that bugged me: [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F12%252Fintroducing-dabblet-an-interactive-css-playground%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FsEGEmN%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Introducing%20dabblet%3A%20An%20interactive%20CSS%20playground%22%20%7D);"></div>
<p><a href="http://lea.verou.me/wp-content/uploads/2011/12/Screen-shot-2011-12-14-at-23.32.02-.png"><img src="http://lea.verou.me/wp-content/uploads/2011/12/Screen-shot-2011-12-14-at-23.32.02--300x183.png" alt="" title="Dabblet screenshot" width="300" height="183" class="alignleft size-medium wp-image-1503" /></a>I loved <a href="http://jsfiddle.net" target="_blank">JSFiddle</a> ever since I first used it. Being able to test something almost instantly and without littering my hard drive opened new possibilities for me. I use it daily for experiments, browser bug testcases, code snippet storage, code sharing and many other things. However, there were always a few things that bugged me:</p>
<ul>
<li>JSFiddle is very JS oriented, as you can tell even from the name itself</li>
<li>JSFiddle is heavily server-side so there&#8217;s always at least the lag of an HTTP request every time you make an action. It makes sense not to run JS on every keystroke (JSBin does it and it&#8217;s super annoying, even caused me to fall in an infinite loop once) but CSS and HTML could be updated without any such problems.</li>
<li>I&#8217;m a huge tabs fan, I hate spaces for indenting with a passion.</li>
<li>Every time I want to test a considerable amount of CSS3, I need to include <a href="http://leaverou.github.com/prefixfree/" target="_blank">-prefix-free </a>as a resource and I can&#8217;t save that preference or any other (like &#8220;No library&#8221;).</li>
</ul>
<div>Don&#8217;t get me wrong, I LOVE JSFiddle. It was a pioneer and it paved the way for all similar apps. It&#8217;s great for JavaScript experiments. But for pure CSS/HTML experiments, we can do better.</div>
<div>The thought of making some interactive playground for CSS experiments was lingering in my mind for quite a while, but never attempted to start it as I knew it would be a lot of fascinating work and I wouldn&#8217;t be able to focus on anything else throughout. While I was writing <a href="http://24ways.org/2011/css3-patterns-explained">my 24ways article</a>, I wanted to include lots of CSS demos and I wanted the code to be editable and in some cases on top of the result to save space. JSFiddle&#8217;s embedding didn&#8217;t do that, so I decided to make something simple, just for that article. It quickly evolved to something much bigger, and yes I was right, it was lots of fascinating work and I wasn&#8217;t able to focus on anything else throughout. I even delayed my 24ways article for the whole time I was developing it, and I&#8217;m grateful that Drew was so patient. After 3 weeks of working on it, I present <a href="http://dabblet.com">dabblet</a>.</div>
<p><span id="more-1471"></span></p>
<h3>Features</h3>
<p>So what does dabblet have that similar apps don&#8217;t? Here&#8217;s a list:</p>
<ul>
<li>Realtime updates, no need to press a button or anything</li>
<li>Saves everything to <a href="https://gist.github.com/" target="_blank">Github gists</a>, so even if dabblet goes away (not that I plan to!) you won&#8217;t lose your data</li>
<li>No page reloads even on saving, everything is XHR-ed</li>
<li>Many familiar keyboard shortcuts</li>
<li>Small inline previewers for many kinds of CSS values, in particular for: <a href="http://dribbble.com/shots/338667-Mystery-upcoming-project-UI-detail-CSS-color-preview" target="_blank">colors</a>, <a href="http://dribbble.com/shots/339917-Mystery-upcoming-project-UI-detail-Length-preview" target="_blank">absolute lengths</a>, durations, <a href="http://dribbble.com/shots/346253-Mystery-upcoming-project-UI-detail-Angle-preview" target="_blank">angles</a>, <a href="http://dribbble.com/shots/349045-Mystery-upcoming-project-UI-detail-Easing-previewer" target="_blank">easing functions</a> and <a href="http://dribbble.com/shots/346247-Mystery-upcoming-project-UI-detail-CSS-gradient-preview" target="_blank">gradients</a>. Check them all in <a href="http://dabblet.com/gist/1441328" target="_blank">this dabblet</a>.</li>
<li>Automatically adds prefixes with <a href="http://leaverou.github.com/prefixfree/" target="_blank">-prefix-free</a>, to speed up testing</li>
<li>Use the Alt key and the up/down arrows to increment/decrement &lt;length&gt;, &lt;time&gt; and &lt;angle&gt; values.</li>
<li>Dabblet is <a href="https://github.com/LeaVerou/dabblet" target="_blank">open source</a> under a NPOSL 3.0 license</li>
<li>You can save anonymously even when you are logged in</li>
<li>Multiple view modes: Result behind code, Split views (horizontal or vertical), separate tabs. View modes can be saved as a personal preference or in the gists (as different demos may look better with different view modes)</li>
<li>Editable even from an embedded iframe (to embed just use the same dabblet URL, it will be automatically adjusted through media queries)</li>
</ul>
<div>Here&#8217;s a rough screencast that I made in 10 minutes to showcase some of dabblet&#8217;s features. There&#8217;s no sound and is super sloppy but I figured even this lame excuse of a screencast is better than none.</div>
<p><iframe width="600" height="500" src="http://www.youtube.com/embed/ztMJQJgTMSE" frameborder="0" allowfullscreen></iframe></p>
<div>I&#8217;m hoping to make a proper screencast in the next few days.</div>
<div>However, dabblet is still very new. I wouldn&#8217;t even call it a beta yet, more like an Alpha. I&#8217;ve tried to iron out every bug I could find, but I&#8217;m sure there are many more lingering around. Also, it has some limitations, but it&#8217;s my top priority to fix them:</div>
<div>
<ul>
<li>It&#8217;s currently not possible to see or link to older versions of a dabblet. You can of course use Github to view them.</li>
<li>It currently only works in modern, CORS-enabled browsers. Essentially Chrome, Safari and Firefox. I intend to support Opera too, once Opera 12 comes out. As for IE, I&#8217;ll bother with it when a significant percentage of web developers start using it as their main browser. Currently, I don&#8217;t know anyone that does.</li>
<li>It doesn&#8217;t yet work very well on mobile but I&#8217;m working on it and it&#8217;s a top priority</li>
<li>You can&#8217;t yet add other scripts like LESS or remove -prefix-free.</li>
<li>Hasn&#8217;t been tested in Windows very much, so not sure what issues it might have there.</li>
</ul>
<div>I hope you enjoy using it as much as I enjoyed making it. Please report any bugs and suggest new features in <a href="https://github.com/LeaVerou/dabblet/issues" target="_blank">its bug tracker</a>.</div>
</div>
<h2>Examples</h2>
<p>Here are some dabblets that should get you started:</p>
<ul>
<li><a href="http://dabblet.com/gist/1441328" target="_blank">http://dabblet.com/gist/1441328</a></li>
<li><a href="http://dabblet.com/gist/1454230" target="_blank">http://dabblet.com/gist/1454230</a></li>
<li><a href="http://dabblet.com/gist/1454409" target="_blank">http://dabblet.com/gist/1454409</a></li>
<li><a href="http://dabblet.com/gist/1457668" target="_blank">http://dabblet.com/gist/1457668</a></li>
<li><a href="http://dabblet.com/gist/1457677" target="_blank">http://dabblet.com/gist/1457677</a></li>
<li><a href="http://dabblet.com/gist/1421054" target="_blank">http://dabblet.com/gist/1421054</a></li>
<li><a href="http://dabblet.com/gist/1454889" target="_blank">http://dabblet.com/gist/1454889</a></li>
</ul>
<h2>Credits</h2>
<p><a href="http://kizu.ru/en/">Roman Komarov</a> helped tremendously by doing QA work on dabblet. Without his efforts, it would have been super buggy and much less polished.</p>
<p>I&#8217;d also like to thank <a href="http://twitter.com/dstorey" target="_blank">David Storey</a> for coming up with the name &#8220;dabblet&#8221; and for his support throughout these 3 weeks.</p>
<p>Last but not least, I&#8217;d also like to thank <a href="http://oli.jp/" target="_blank">Oli Studholme</a> and <a href="http://richclarkdesign.com/" target="_blank">Rich Clark</a> for promoting dabblet in their .net magazine articles even before its release.</p>
<p><strong>Update:</strong> Dabblet has its own twitter account now: Follow <a href="http://twitter.com/dabblet" target="_blank">@dabblet</a></p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/12/introducing-dabblet-an-interactive-css-playground/feed/</wfw:commentRss>
		<slash:comments>85</slash:comments>
		</item>
		<item>
		<title>Animatable: A CSS transitions gallery</title>
		<link>http://lea.verou.me/2011/10/animatable-a-css-transitions-gallery/</link>
		<comments>http://lea.verou.me/2011/10/animatable-a-css-transitions-gallery/#comments</comments>
		<pubDate>Sun, 30 Oct 2011 07:18:32 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Apps & scripts]]></category>
		<category><![CDATA[Original]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[CSS3 animations]]></category>
		<category><![CDATA[CSS3 transitions]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=1420</guid>
		<description><![CDATA[What kind of transitions can you create with only one property? This is what my new experiment, animatable aims to explore. It&#8217;s essentially a gallery of basic transitions. It aims to show how different animatable properties look when they transition and to broaden our horizons about which properties can be animated. Hover over the demos [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F10%252Fanimatable-a-css-transitions-gallery%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FtgIxqV%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Animatable%3A%20A%20CSS%20transitions%20gallery%22%20%7D);"></div>
<p><a href="http://lea.verou.me/wp-content/uploads/2011/10/Screen-shot-2011-10-30-at-08.54.38-.png"><img class="alignleft size-medium wp-image-1421" title="Screen shot 2011-10-30 at 08.54.38" src="http://lea.verou.me/wp-content/uploads/2011/10/Screen-shot-2011-10-30-at-08.54.38--300x187.png" alt="" width="300" height="187" /></a>What kind of transitions can you create with only one property? This is what my new experiment, <a href="http://leaverou.github.com/animatable/" target="_blank">animatable</a> aims to explore.</p>
<p>It&#8217;s essentially a gallery of basic transitions. It aims to show how different animatable properties look when they transition and to broaden our horizons about which properties can be animated. Hover over the demos to see the animation in action, or click &#8220;Animate All&#8221; to see all of them (warning: might induce nausea, headache and seizures <img src='http://lea.verou.me/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  ). You can also click on it to see more details and get a <a href="http://leaverou.github.com/animatable/#background-size" target="_blank">permalink</a>. Instead of clicking, you can also navigate with the arrow keys and press Esc to return to the main listing.</p>
<p><a href="https://github.com/LeaVerou/animatable" target="_blank">Fork it on Github</a> and add your own ideas. Be sure to add your twitter username to them as a <code>data-author</code> attribute!</p>
<p>I&#8217;ve only tested in Firefox and Chrome for OSX so far. Not sure which other browsers are supported. However, since it uses CSS animations, we know for sure that it won&#8217;t work in browsers that don&#8217;t support CSS animations.</p>
<p>Hope you enjoy it <img src='http://lea.verou.me/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/10/animatable-a-css-transitions-gallery/feed/</wfw:commentRss>
		<slash:comments>53</slash:comments>
		</item>
		<item>
		<title>PrefixFree: Break free from CSS prefix hell!</title>
		<link>http://lea.verou.me/2011/10/prefixfree-break-free-from-css-prefix-hell/</link>
		<comments>http://lea.verou.me/2011/10/prefixfree-break-free-from-css-prefix-hell/#comments</comments>
		<pubDate>Wed, 12 Oct 2011 13:28:41 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Apps & scripts]]></category>
		<category><![CDATA[Original]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[Vendor prefixes]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=1365</guid>
		<description><![CDATA[I wrote this script while at the airport travelling to Oslo and during the Frontend 2011 conference. I think it&#8217;s amazing, and it makes authoring CSS3 a pleasure. Read my announcement about it on Smashing Magazine. Hope you like it!]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F10%252Fprefixfree-break-free-from-css-prefix-hell%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FshtOlG%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22PrefixFree%3A%20Break%20free%20from%20CSS%20prefix%20hell%21%22%20%7D);"></div>
<p><a href="http://lea.verou.me/wp-content/uploads/2011/10/Screen-shot-2011-11-15-at-14.33.38-.png"><img src="http://lea.verou.me/wp-content/uploads/2011/10/Screen-shot-2011-11-15-at-14.33.38--300x187.png" alt="" title="-prefix-free project page screenshot" width="300" height="187" class="alignleft size-medium wp-image-1440" /></a>I wrote this script while at the airport travelling to Oslo and during the <a href="http://www.frontend2011.com/" target="_blank">Frontend 2011 conference</a>. I think it&#8217;s amazing, and it makes authoring CSS3 a pleasure.</p>
<p><a href="http://coding.smashingmagazine.com/2011/10/12/prefixfree-break-free-from-css-prefix-hell/" target="_blank">Read my announcement about it on Smashing Magazine.</a></p>
<p>Hope you like it!</p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/10/prefixfree-break-free-from-css-prefix-hell/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Major update to Chainvas: modularity, a client side build script &amp; more</title>
		<link>http://lea.verou.me/2011/09/major-update-to-chainvas-modularity-a-client-side-build-script-more/</link>
		<comments>http://lea.verou.me/2011/09/major-update-to-chainvas-modularity-a-client-side-build-script-more/#comments</comments>
		<pubDate>Sun, 18 Sep 2011 08:34:12 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Apps & scripts]]></category>
		<category><![CDATA[Original]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=1306</guid>
		<description><![CDATA[A week ago, I released Chainvas. It was a spin-off script I wrote while developing my cubic-bezier tool, to make using the Canvas API a bit less painful. However, unlike similar attempts to make the Canvas API chainable, most of my code was written in a very generic manner, and was actually able to make [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F09%252Fmajor-update-to-chainvas-modularity-a-client-side-build-script-more%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FrDlHmt%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Major%20update%20to%20Chainvas%3A%20modularity%2C%20a%20client%20side%20build%20script%20%26%20more%22%20%7D);"></div>
<p><a href="http://lea.verou.me/wp-content/uploads/2011/09/Screen-shot-2011-11-15-at-14.57.17-.png"><img src="http://lea.verou.me/wp-content/uploads/2011/09/Screen-shot-2011-11-15-at-14.57.17--300x187.png" alt="" title="Chainvas project page screenshot" width="300" height="187" class="alignleft size-medium wp-image-1442" /></a>A week ago, <a href="http://lea.verou.me/2011/09/chainvas-make-apis-chainable-enhance-the-canvas-api/" target="_blank">I released Chainvas</a>. It was a spin-off script I wrote while developing <a href="http://lea.verou.me/2011/09/a-better-tool-for-cubic-bezier-easing/" target="_blank">my cubic-bezier tool</a>, to make using the Canvas API a bit less painful. However, unlike similar attempts to make the Canvas API chainable, most of my code was written in a very generic manner, and was actually able to make every API chainable. However, when I released it, even though I mentioned that it can be used for other APIs and provided some examples, practically everyone that shared the link on twitter or other means (thank you .net magazine for the newsletter mention btw!) focused on what Chainvas did for Canvas.</p>
<p><img src="http://lea.verou.me/chainvas/img/madewith.png" class="alignright size-medium" />Actually, while using Chainvas myself, I found it immensely more useful for chaining DOM methods and setting multiple element properties at once. Chainvas had a lot of potential, that most people were missing. And then it dawned on me: I should modularize the library! A generic chaining library at its core and additional modules for making the different APIs chainable. And I did it.</p>
<p>On the way to that, I added IE8 compatibility, and tested in many other browsers, thanks to <a href="http://www.browserstack.com/" target="_blank">Browserstack</a>. I actually found that Chainvas&#8217; core even works in IE6! I also wrote <a href="http://lea.verou.me/chainvas/unit-tests.html" target="_blank">unit tests</a>, a much more extensive <a href="http://lea.verou.me/chainvas/#documentation" target="_blank">documentation</a>, added a script generated table of contents and designed <a href="http://lea.verou.me/chainvas/img/logo.svg" target="_blank">a logo</a> and a <a href="http://lea.verou.me/chainvas/img/madewith.svg" target="_blank">Chainvas pride banner</a>.</p>
<p>Also, since it was now modular, it needed a build script. I badly wanted to make this client side, so I followed this architecture:</p>
<ul>
<li>Every module is included in chainvas.js and chainvas.min.js, along with a header comment that follows <a href="http://lea.verou.me/chainvas/#making-your-own-modules" target="_blank">a specific syntax</a>.</li>
<li>The user selects a compression level and then, the relevant script is downloaded through XHR and split into parts according to the module headers. Then a module list is generated with checkboxes for the user to select the ones they want to include.</li>
<li>When the user checks and unchecks those checkboxes, the URL of the download link changes to a data URI that contains the script.</li>
</ul>
<div>This approach has the disadvantage that there is no default filename, and the &#8220;Save page as&#8230;&#8221; link is deactivated in Chrome (why Chrome??). However, I like the idea so much, I don&#8217;t mind these shortcomings.</div>
<div>That&#8217;s about it. <a href="http://lea.verou.me/chainvas/#documentation" target="_blank">Enjoy</a> and let me know about any bugs.</div>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/09/major-update-to-chainvas-modularity-a-client-side-build-script-more/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>A better tool for cubic-bezier() easing</title>
		<link>http://lea.verou.me/2011/09/a-better-tool-for-cubic-bezier-easing/</link>
		<comments>http://lea.verou.me/2011/09/a-better-tool-for-cubic-bezier-easing/#comments</comments>
		<pubDate>Wed, 14 Sep 2011 19:23:05 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Apps & scripts]]></category>
		<category><![CDATA[Original]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[CSS3 transitions]]></category>
		<category><![CDATA[cubic-bezier]]></category>
		<category><![CDATA[easing]]></category>
		<category><![CDATA[HTML5]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=1293</guid>
		<description><![CDATA[A few days ago, I had a talk at a conference in Zurich (I&#8217;m going to write more about it in another post). The talk was about &#8220;10 things you might not know about CSS3&#8243;. The first of those things was how you can do bouncing transitions with cubic-bezier() instead of an easing keyword. As usual, my [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F09%252Fa-better-tool-for-cubic-bezier-easing%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2Fpgcxul%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22A%20better%20tool%20for%20cubic-bezier%28%29%20easing%22%20%7D);"></div>
<p><a href="http://lea.verou.me/wp-content/uploads/2011/09/Screen-shot-2011-09-14-at-10.33.11-.png"><img class="alignleft size-medium wp-image-1299" style="border:10px solid #ddd" title="Screenshot of cubic-bezier.com" src="http://lea.verou.me/wp-content/uploads/2011/09/Screen-shot-2011-09-14-at-10.33.11--300x204.png" alt="" width="300" height="204" /></a>A few days ago, I had a talk at <a href="http://frontendconf.ch/" target="_blank">a conference in Zurich</a> (I&#8217;m going to write more about it in another post). The talk was about &#8220;10 things you might not know about CSS3&#8243;. The first of those things was how you can do bouncing transitions with cubic-bezier() instead of an easing keyword. As usual, my slides included a few live demos of the functionality, in which I edited the cubic-bezier() parameters and the audience could see the transition produced.</p>
<p>However, in the case of cubic-bezier() that&#8217;s not enough. No matter how much you see someone changing the parameters, if you don&#8217;t picture it in a 2D plane, it&#8217;s very hard to understand how it works. So, the night before, I searched for a tool I could use to show them how bezier curves are formed. I found plenty, but all of them restricted the the coordinates to the 0-1 range. I&#8217;m not sure if the cause is ignorance about the spec changes or that Webkit hasn&#8217;t caught up with those changes yet (<a href="https://bugs.webkit.org/show_bug.cgi?id=45761" target="_blank">but it will, soon</a>). The only one that supported values out of range was <a href="http://scope.bitbucket.org/ui-elements/bezier-control/index.xml" target="_blank">this one</a> from the Opera Dragonfly developers, but I found it kinda impossible to adapt.</p>
<p>For my talk, I tried to adapt one of them but it was late so I gave up after a while and ended up just showing them a screenshot. And the day after the talk, I started adapting <a href="http://www.roblaplaca.com/examples/bezierBuilder/" target="_blank">this</a> to my needs (ever tried coding at a conference? It&#8217;s awesome, you get to ask questions from very knowledgeable people and ger replies straight away). And then I started cleaning up the code, changing how it worked, adding features. At this point, I think the only thing that&#8217;s left from that tool is &#8230;the HTML5 doctype. After 3-4 days, I finished it, and got it its own domain, <a href="http://cubic-bezier.com/" target="_blank">cubic-bezier.com</a> (I was surprised it was still free).</p>
<h2>So, in a nutshell, what makes this better?</h2>
<p>Lots of things:</p>
<ul>
<li>It supports y values out of range, as per <a href="http://dev.w3.org/csswg/css3-transitions/#transition-timing-function" target="_blank">the latest version of the spec</a> (and shows a warning for Webkit)</li>
<li>It&#8217;s fully accessible from the keyboard</li>
<li>You can move the handles not only by dragging but also by clicking on the plane or using the keyboard arrow keys</li>
<li>You can mouse over the plane and see the progression and time percentages that correspond to every point</li>
<li>You can save curves you like in your &#8220;Library&#8221; (uses localStorage to persist them)</li>
<li>You can import and export curves to/from your library to share them with others</li>
<li>You can share a permalink to every curve. For example, <a href="http://cubic-bezier.com/#.64,.57,.67,1.53" target="_blank">here&#8217;s a bouncing transition</a> (FF &amp; Opera only)</li>
<li>You can compare the current curve with any in your library, setting the duration yourself</li>
<li>Custom favicon that reflects the current curve</li>
</ul>
<h2>Cool stuff used</h2>
<p>Given that this tool is not only for developers, but for badass developers that care about stuff like cubic-bezier(), I think I can safely assume they&#8217;re using a top notch browser. So, I went crazy with using cool modern stuff:</p>
<ul>
<li>HTML5: Canvas, localStorage, History API, range inputs, oninput event, output, classList, data- attributes</li>
<li>ES5: Accessors, Array#map, Array#forEach</li>
<li>Selectors API</li>
<li>JSON</li>
<li>CSS3: Transitions, gradients, media queries, border-radius, shadows, :in-range pseudoclass, box-sizing, transforms, text-overflow</li>
</ul>
<div>I also used my tiny chaining framework, <a href="http://lea.verou.me/chainvas" target="_blank">Chainvas</a> throughout this project.</div>
<h2>Browser support</h2>
<p>So far, I&#8217;ve tested it in modern versions of Chrome, Firefox, Opera and Safari and it seems to work. I haven&#8217;t tested it in IE10 (too lazy to open vm), although I want it to work there too, so if it doesn&#8217;t let me know. <img src='http://lea.verou.me/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Enjoy! <a class="view-demo" href="http://cubic-bezier.com" target="_blank">cubic-bezier.com</a></p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/09/a-better-tool-for-cubic-bezier-easing/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Chainvas: Make APIs chainable, enhance the canvas API</title>
		<link>http://lea.verou.me/2011/09/chainvas-make-apis-chainable-enhance-the-canvas-api/</link>
		<comments>http://lea.verou.me/2011/09/chainvas-make-apis-chainable-enhance-the-canvas-api/#comments</comments>
		<pubDate>Sun, 11 Sep 2011 04:17:32 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Original]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[HTML5]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=1288</guid>
		<description><![CDATA[It&#8217;s definitely not the first time someone writes a script to make the canvas API chainable, as a quick Google search will confirm. However, I think my attempt has merit, because it&#8217;s not really focused in chaining canvas methods, but just about every API you use it on and because it&#8217;s super small, only 1KB! [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F09%252Fchainvas-make-apis-chainable-enhance-the-canvas-api%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FqMb8gt%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Chainvas%3A%20Make%20APIs%20chainable%2C%20enhance%20the%20canvas%20API%22%20%7D);"></div>
<p><a href="http://lea.verou.me/wp-content/uploads/2011/09/chainvas.png"><img class="alignleft size-medium wp-image-1289" title="chainvas page screenshot" src="http://lea.verou.me/wp-content/uploads/2011/09/chainvas-300x228.png" alt="" width="300" height="228" /></a>It&#8217;s definitely not the first time someone writes a script to make the canvas API chainable, as <a href="http://www.google.com/search?sourceid=chrome&amp;ie=UTF-8&amp;q=chainable+canvas" target="_blank">a quick Google search</a> will confirm.</p>
<p>However, I think my attempt has merit, because it&#8217;s not really focused in chaining canvas methods, but just about every API you use it on and because it&#8217;s super small, only 1KB!</p>
<div>You can find it here: <a href="http://lea.verou.me/chainvas/" target="_blank" class="view-demo">chainvas</a></div>
<div>Enjoy!</div>
<div></div>
<div></div>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/09/chainvas-make-apis-chainable-enhance-the-canvas-api/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Pure CSS3 typing animation with steps()</title>
		<link>http://lea.verou.me/2011/09/pure-css3-typing-animation-with-steps/</link>
		<comments>http://lea.verou.me/2011/09/pure-css3-typing-animation-with-steps/#comments</comments>
		<pubDate>Mon, 05 Sep 2011 18:19:13 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Original]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[CSS3 animations]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=1269</guid>
		<description><![CDATA[steps() is a relatively new addition to the CSS3 animations module. Instead of interpolating the values smoothly, it allows us to define the number of &#8220;frames&#8221; precisely. So I used it to create headers that have the well-known animated &#8220;typing effect&#8221;: As you can see, the number of characters is hardcoded in the steps() function, [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F09%252Fpure-css3-typing-animation-with-steps%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FnNBowW%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Pure%20CSS3%20typing%20animation%20with%20steps%28%29%22%20%7D);"></div>
<p><a href="http://dev.w3.org/csswg/css3-animations/#animation-timing-function" target="_blank">steps()</a> is a relatively new addition to the CSS3 animations module. Instead of interpolating the values smoothly, it allows us to define the number of &#8220;frames&#8221; precisely. So I used it to create headers that have the well-known animated &#8220;typing effect&#8221;:</p>
<p><iframe style="width: 100%; height: 160px" src="http://jsfiddle.net/leaverou/7rnQP/embedded/result%2Ccss%2Chtml"></iframe></p>
<p>As you can see, the number of characters is hardcoded in the steps() function, but that&#8217;s the only place. Everything else is totally flexible. Apart from the font: It has to be monospace, so that every character has the same width.</p>
<p>Also, this particular way requires a solid background and an extra &lt;span&gt;. You can avoid these limitations by directly animating the width of the heading itself, but this requires a fixed target width hardcoded in the animation, so 2 things that need to be changed for every heading:</p>
<p><iframe style="width: 100%; height: 160px" src="http://jsfiddle.net/leaverou/y8kNx/embedded/result%2Ccss%2Chtml"></iframe></p>
<p>If you&#8217;re having trouble understanding how it works, take a look at <a href="http://jsfiddle.net/leaverou/vrEnp/" target="_blank">this simpler example</a>, with just the cursor.</p>
<p>Gecko (Firefox) and Webkit only at the moment, since other engines haven&#8217;t implemented CSS animations yet. However, both examples degrade very gracefully in other browsers (IMO at least).</p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/09/pure-css3-typing-animation-with-steps/feed/</wfw:commentRss>
		<slash:comments>38</slash:comments>
		</item>
		<item>
		<title>CSS.coloratum: Convert and share CSS colors</title>
		<link>http://lea.verou.me/2011/09/css-coloratum-convert-and-share-css-colors/</link>
		<comments>http://lea.verou.me/2011/09/css-coloratum-convert-and-share-css-colors/#comments</comments>
		<pubDate>Fri, 02 Sep 2011 10:22:22 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Apps & scripts]]></category>
		<category><![CDATA[Original]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[css3 colors]]></category>
		<category><![CDATA[HTML5]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=1257</guid>
		<description><![CDATA[Whenever I wanted to convert a CSS named color to RGB, I used to open the CSS3 colors spec in a new tab, search in the page and copied the values. Every time it felt even more tedious. I didn&#8217;t want to search in long tables, I wanted to type the color somewhere and get [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F09%252Fcss-coloratum-convert-and-share-css-colors%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FrfzCD3%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22CSS.coloratum%3A%20Convert%20and%20share%20CSS%20colors%22%20%7D);"></div>
<p><img src="http://lea.verou.me/wp-content/uploads/2011/09/shot1-300x200.png" alt="" title="screenshot" width="300" height="200" class="alignleft size-medium wp-image-1263" />Whenever I wanted to convert a CSS named color to RGB, I used to open <a href="http://www.w3.org/TR/css3-color/" target="_blank">the CSS3 colors spec</a> in a new tab, search in the page and copied the values. Every time it felt even more tedious. I didn&#8217;t want to search in long tables, I wanted to type the color somewhere and get the values back, in an easy to copy format. So, after yet another color lookup earlier today, I decided to scratch my own itch and do it myself.</p>
<p>Of course, I didn&#8217;t plan to include a whole database of CSS colors in the website. My idea was much simpler: Use the named color to draw a rectangle in a &lt;canvas&gt; and then read the R,G,B values through ctx.getImageData().</p>
<p>I got the core functionality done in under 10 minutes, so I started adding stuff. I added a hex and HSL representation, I used canvas.toDataURL() to get a data URI of the rectangle and use it as a dynamic favicon*, I made the colors sharable and bookmarkable by using an old-fashioned hash. Also, I realized it actually supports any CSS supported color represenation by design, not just named colors.</p>
<p>Regarding the color conversions themselves, I took extra care to avoid redundancy. So values &lt; 1 don&#8217;t have leading zeroes (.5 instead of 0.5) and when the hex color is in the format #xxyyzz it gets converted to #xyz. When it&#8217;s an RGBA color, it still converts it to hex, since those values will be supported in CSS4.</p>
<p>Since it&#8217;s for developers, I didn&#8217;t bother at all with fallbacks.</p>
<p>Cool stuff used:</p>
<ul>
<li>HTML5: canvas, autofocus, output, oninput event, hashchange event</li>
<li>CSS3: gradients, media queries, box-sizing, background-clip, border-radius, shadows, RGBA</li>
<li>ES5: Array#map()</li>
<li>Selectors API</li>
</ul>
<p>The reason the input&#8217;s border appears weird on Webkit is <a href="https://bugs.webkit.org/show_bug.cgi?id=63952" target="_blank">this long standing Webkit bug</a>. Also, for some reason my nice dynamic favicons don&#8217;t display on Firefox, although they display fine in Webkit and Opera.</p>
<div>Enjoy: <a href="http://css.coloratum.com" target="_blank" class="view-demo">CSS.coloratum</a></div>
<div>Happy color sharing! Let me know of any problems or suggestions you may have.</div>
<div>PS: In case you&#8217;re wondering about the domain, I&#8217;ve had it for ages for another project and I thought it was quite fitting.</div>
<p>*Thanks to <a href="http://twitter.com/milo" target="_blank">@milo</a> for giving me the idea of using a dynamic favicon</p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/09/css-coloratum-convert-and-share-css-colors/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Accessible star rating widget with pure CSS</title>
		<link>http://lea.verou.me/2011/08/accessible-star-rating-widget-with-pure-css/</link>
		<comments>http://lea.verou.me/2011/08/accessible-star-rating-widget-with-pure-css/#comments</comments>
		<pubDate>Thu, 18 Aug 2011 16:07:38 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Original]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[CSS3 selectors]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=1233</guid>
		<description><![CDATA[For ages, we couldn’t utilize the sibling combinators (~ and +) to ease the pain of creating star rating widgets, because of this stupid Webkit bug. Nowadays, not only it’s fixed, but the fix has already propagated to Chrome and Safari 5.1. So, we can at least use the sibling combinator to make coloring the [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F08%252Faccessible-star-rating-widget-with-pure-css%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FnsoxJj%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Accessible%20star%20rating%20widget%20with%20pure%20CSS%22%20%7D);"></div>
<p>For ages, we couldn’t utilize the sibling combinators (<code>~</code> and <code>+</code>) to ease the pain of creating star rating widgets, because of <a href="http://css-tricks.com/8439-webkit-sibling-bug/" target="_blank">this stupid Webkit bug</a>. Nowadays, not only it’s fixed, but the fix has already propagated to Chrome and Safari 5.1. So, we can at least use the sibling combinator to make coloring the stars easier.</p>
<p>But can we use <strong>no JavaScript</strong> for a rating widget and make it just with CSS?</p>
<p>Actually, we can. By adapting <a href="http://www.thecssninja.com/css/custom-inputs-using-css" target="_blank">Ryan Seddon&#8217;s technique for custom radio buttons with CSS</a>, we can turn a series of radio buttons into stars that change colors (for the purposes of this demo they&#8217;re just unicode characters that change colors, but in your case they may as well be images) and use the sibling combinator to color the previous stars. <a href="http://twitter.com/#!/stephband/status/104159169657053184" target="_blank">A</a> <a href="http://twitter.com/#!/scottjehl/status/104194465480183808" target="_blank">series</a> <a href="http://twitter.com/#!/anselmhannemann/status/104176613159206912" target="_blank">of</a> <a href="http://twitter.com/#!/hlb/status/104176520939044865" target="_blank">radio</a> <a href="http://twitter.com/#!/tomfullerton/status/104165058191433728" target="_blank">buttons</a> <a href="http://twitter.com/#!/leads/status/104161288279695360" target="_blank">is</a> <a href="http://twitter.com/#!/jamygolden/status/104158932267827201" target="_blank">what</a> <a href="http://twitter.com/#!/thijs/status/104158812684038144" target="_blank">many</a> <a href="http://twitter.com/#!/rossbruniges/status/104157949064249344" target="_blank">people</a> <a href="http://twitter.com/#!/maskingtape/status/104157878230843392" target="_blank">use</a> <a href="http://twitter.com/#!/edge0703/status/104157335756341249" target="_blank">as</a> <a href="http://twitter.com/#!/rasmusfl0e/status/104157216029949955" target="_blank">a</a> <a href="http://twitter.com/#!/stephenhay/status/104157128704540672" target="_blank">star</a> <a href="http://twitter.com/#!/derSchepp/status/104157124787060737" target="_blank">rating</a> <a href="http://twitter.com/#!/hzr/status/104160608848584704" target="_blank">widget</a> <a href="http://twitter.com/#!/iPaintCode/status/104161792925765633" target="_blank">fallback</a> anyway, so the markup required is not necessarily more than usual. The only thing that needs to be done differently is their reverse ordering: The highest ratings need to go first, due to the way CSS3 selectors work (this limitation might be removed in CSS4, but that&#8217;s a long way ahead).</p>
<p>Of course, you&#8217;d still need JS to attach an event handler if you want the votes to be registered through AJAX, but that&#8217;s not part of the rating widget per se (it could still work as part of a regular form).</p>
<p>What&#8217;s best is that it&#8217;s fully keyboard accessible (focus and then use keyboard arrows) and screen reader accessible (although VoiceOver will also pronounce the generated stars, but that won’t happen if you use images instead of unicode stars). I&#8217;m guessing it could become even more accessible with proper ARIA, but I’ll leave that as an exercise to the commenter <img src='http://lea.verou.me/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>In browsers that don&#8217;t support <code>:checked</code> (essentially only IE &lt; 9), it degrades to a series of radio buttons (haven’t verified that it does, but it should do).</p>
<p>So, here it is:</p>
<p><iframe style="width: 100%; height: 180px;" src="http://jsfiddle.net/leaverou/CGP87/embedded/result%2Ccss%2Chtml/" width="320" height="240"></iframe></p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/08/accessible-star-rating-widget-with-pure-css/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>twee+: Longer tweets, no strings attached</title>
		<link>http://lea.verou.me/2011/08/tweeplus-longer-tweets-no-strings-attached/</link>
		<comments>http://lea.verou.me/2011/08/tweeplus-longer-tweets-no-strings-attached/#comments</comments>
		<pubDate>Sun, 14 Aug 2011 05:27:39 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Apps & scripts]]></category>
		<category><![CDATA[Original]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=1197</guid>
		<description><![CDATA[As some people that have been following me for a while know, the 140 character limit on twitter bugs me a lot sometimes, and I&#8217;ve tried to find a way to overcome it previously as well. The most common ways these days seems to be either cutting down the long tweet into multiple pieces (yuck) [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F08%252Ftweeplus-longer-tweets-no-strings-attached%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FnJq3Xc%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22twee%2B%3A%20Longer%20tweets%2C%20no%20strings%20attached%22%20%7D);"></div>
<p><img class="alignleft size-medium wp-image-1207" title="tweeplus screenshot" src="http://lea.verou.me/wp-content/uploads/2011/08/tweeplus-300x200.png" alt="" width="300" height="200" />As some people that have been following me for a while know, the 140 character limit on twitter bugs me a lot sometimes, and I&#8217;ve tried to find <a href="http://lea.verou.me/2009/11/exploring-browser-supported-unicode-characters-and-a-tweet-shortening-experiment/" target="_blank">a way to overcome it</a> previously as well. The most common ways these days seems to be either cutting down the long tweet into multiple pieces (yuck) or using a service to host the longer tweet and post a summary with a link to it.</p>
<p>The latter isn&#8217;t an entirely horrible option. However, I see 3 big downsides:</p>
<ol>
<li>I&#8217;m not very comfortable with the idea of some external service hosting my content which could close down any time due to failure to monetize their website. In that case, I&#8217;d be left with some dead links that are of no value and my content would be lost forever. Yes, they usually warn you in advance in such cases, but such news could be missed for a number of reasons.</li>
<li>People (including yours truly) don&#8217;t plan those things in advance. They just seek services like that at the exact moment when they want to post a long tweet. Being greeted with a prompt to use Twitter Connect is NOT nice. For starters, it slows me down. Also, I don&#8217;t want to give permission to every website on the effing interwebs to post on my twitter timeline. I owe it to my followers to be responsible and not risk filling their timelines with crap.</li>
<li>Most of these websites look like someone puked and what came out happened to be HTML and CSS. The only exception I&#8217;ve found is <a href="http://twtmore.com/" target="_blank">twtmore</a>, but it still suffers from #1 and #2.</li>
</ol>
<div>So, like every developer with a healthy amount of NIH syndrome, I decided to write my own <img src='http://lea.verou.me/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </div>
<div>My goals were:</div>
<div>
<ol>
<li>It had to be entirely client-side (except initially getting downloaded from the server of course). This way, whoever is concerned can download the full website and decode their tweets with it if it ever goes down. Also, being entirely client side allows it to scale very easily, as serving files is not a very resource intensive job (compared to databases and the like).</li>
<li>No Twitter Connect, the tweets would get posted through <a href="https://dev.twitter.com/docs/intents" target="_blank">Twitter Web Intents</a>.</li>
<li>It had to look good. I&#8217;m not primarily a designer, so I can&#8217;t make something that looks jaw-droppingly amazing, but I can at least make it look very decent.</li>
<li>If I was gonna go through all the hassle of making this, I may as well try to keep it under 10K, so that I could take part in the <a href="http://10k.aneventapart.com/" target="_blank">10K apart contest</a>. (I haven&#8217;t submitted it yet, I&#8217;ll submit a few days before the deadline, as it seems you can&#8217;t make changes to your submission and I want to polish the code a bit, especially the JS — I&#8217;m not too proud about it)</li>
</ol>
<div>I managed to succeed in all my goals and I really liked the result. I ended up using it for stuff I never imagined, like checking if a twitter username corresponds to the account I think (as it shows the avatars). So I went ahead and came up with a name, bought a domain for it, and <a href="http://tweeplus.com" target="_blank">tweeplus.com</a> was born <img src='http://lea.verou.me/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </div>
</div>
<h2>twee+? Seriously?</h2>
<p>Yes, I like it. The plus means &#8220;more&#8221;, which is fitting and + kinda looks like a t, so it could be read as &#8220;tweet&#8221; as well. Yes, I know that the word &#8220;twee&#8221; has some negative connotations, but oh well, I still like the name. Whoever doesn&#8217;t can just not use it, I won&#8217;t get depressed, I promise. <img src='http://lea.verou.me/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<h2>Geeky stuff</h2>
<h3>How it works</h3>
<ul>
<li>A relatively new feature, Twitter automatically wraps URLs in <a href="http://t.co" target="_blank">t.co</a> links, making them only 20 characters long.</li>
<li>All the text of the tweet is stored in the URL hash (query string will also work, although the output uses a hash). Some research revealed that actually <a href="http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url" target="_blank">browsers can handle surprisingly long URLs</a>. Essentially, the only limit (2083 characters) is enforced by Internet Explorer. I decided to limit tweets to 2000 characters (encoded length), not only because of the IE limit, but also because I wouldn&#8217;t like people to post whole books in t.co links. We don&#8217;t want Twitter to start taking measures against this, do we? <img src='http://lea.verou.me/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li>A hard part was deciding which encoding to use (twitter is quite limited in the characters it parses as part of a URL).
<ul>
<li>My first thought was base64, but I quickly realized this was not a very good idea:
<ul>
<li>The encoding &amp; decoding functions (<code>btoa()</code> and <code>atob()</code> respectively) are relatively new and therefore not supported by older browsers. I&#8217;m fine with the app hardly working in old browsers, but existing links must as a minimum be readable.</li>
<li>It uses approximately 1.34 characters per ASCII character. Unicode characters need to be URL-encoded first, otherwise an Exception is thrown. URL-encoding them uses 6 characters, which would result in 8 characters when they&#8217;re base64 encoded.</li>
</ul>
</li>
<li>Then I thought of using URL-encoding for the whole thing. The good thing with it is that for latin alphanumeric characters (which are the most) it doesn&#8217;t increase the string length at all. For non-alphanumeric characters it takes up 3 characters and 6 characters for Unicode ones. Also, it&#8217;s much more readable.</li>
<li>Still, implementing it was tricky. It doesn&#8217;t encode some characters (like the dot), even though twitter doesn&#8217;t accept them as part of a URL. Also, escape() and encodeURI() behave differently and <a href="http://twitter.com/#!/LeaVerou/status/101348203756130304" target="_blank">the Unicode encoding returned by the former isn&#8217;t accepted by Twitter</a>. So I had to combine the two and do some substitutions manually.</li>
</ul>
</li>
<li>When the textarea changes, the hash does too. The whole thing is a form with action=&#8221;http://twitter.com/intent/tweet&#8221;, so submitting it does the right thing naturally. I keep a hidden input with the tweet and the textarea has no name, so it doesn&#8217;t get submitted.</li>
<li>Usernames, hashtags and URLs get extracted and linkified. Usernames also get an avatar (it&#8217;s dead easy: Just use twitter.com/api/users/profile_image?screen_name={username} where {username} is the user&#8217;s username)</li>
<li>Internal &#8220;pages&#8221; (like &#8220;About&#8221; or &#8220;Browser support&#8221;) are essentially long &#8220;tweets&#8221; too.</li>
<li>A little easter egg is that if the browser supports radial gradients, the gradient follows the mouse, creating a spotlight effect. This looks nice on Chrome and Firefox, and really shitty on IE10, probably due to bugs in the gradient implementation (which I have to reduce &amp; report sometime).</li>
</ul>
<h3>Buzzword compliance</h3>
<p>This little app demonstrates quite a lot new open web technologies (HTML5, CSS3 etc), such as:</p>
<ul>
<li>textarea maxlength</li>
<li>placeholder</li>
<li>autofocus (edit: I had to remove it cause it triggered a Webkit bug in Safari)</li>
<li>required inputs</li>
<li>New input types (url)</li>
<li>History API</li>
<li>oninput event (with <a href="http://mathiasbynens.be/notes/oninput" target="_blank">keyup fallback</a>)</li>
<li>hashchange event</li>
<li>SVG</li>
<li>Common CSS3 (border-radius, shadows, transitions, rgba, media queries)</li>
<li>CSS3 gradients</li>
<li>CSS3 animations</li>
<li>CSS3 resize</li>
<li>:empty</li>
</ul>
<div>Let me know if I forgot something.</div>
<div>Oh yeah, I did forget something. There it is: <a class="view-demo" href="http://tweeplus.com/">twee+</a></div>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/08/tweeplus-longer-tweets-no-strings-attached/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>Detecting CSS selectors support + my JSConf EU talk</title>
		<link>http://lea.verou.me/2011/07/detecting-css-selectors-support-my-jsconf-eu-talk/</link>
		<comments>http://lea.verou.me/2011/07/detecting-css-selectors-support-my-jsconf-eu-talk/#comments</comments>
		<pubDate>Thu, 21 Jul 2011 02:30:26 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Original]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[feature detection. CSS selectors]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=1153</guid>
		<description><![CDATA[I&#8217;ll start with a little backstory, if you want to jump straight to the meat, skip the next 4 paragraphs. In the past few months, my CSS research has been getting some attention and I&#8217;ve been starting to become somewhat well-known in the CSS industry. A little known fact about me is that JavaScript has [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F07%252Fdetecting-css-selectors-support-my-jsconf-eu-talk%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2Fog7bKy%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Detecting%20CSS%20selectors%20support%20%2B%20my%20JSConf%20EU%20talk%22%20%7D);"></div>
<p>I&#8217;ll start with a little backstory, if you want to jump straight to the meat, skip the next 4 paragraphs.</p>
<p>In the past few months, my CSS research has been getting some attention and I&#8217;ve been starting to become somewhat well-known in the CSS industry. A little known fact about me is that JavaScript has always been one of my loves, almost as much as CSS (even more than it in the past). Ironically, <a href="http://front-trends.com/" target="_blank">the first time I was asked to speak in a big conference</a>, it was about JavaScript, even though I ended up choosing to speak about CSS3 instead.</p>
<p>Lately, I&#8217;ve started wanting to get more into the JavaScript industry as well. I&#8217;m quite reluctant to submit speaking proposals myself (every conference or meetup I&#8217;ve given a talk so far has asked me to speak, not the other way around) and most JavaScript conferences expect you to submit a proposal yourself. I also couldn&#8217;t think of a good topic, something I was passionate about and hasn&#8217;t already been extensively covered.</p>
<p>This changed a few weeks ago. While I was writing <a href="http://lea.verou.me/2011/07/a-polyfill-for-html5-progress-element-the-obsessive-perfectionist-way/" target="_blank">my &lt;progress&gt; polyfill</a>, it dawned on me: Polyfills is something that&#8217;s JS-related and I&#8217;m passionate about! I love studying them, writing them, talking about them. I quickly searched if there were any talks about polyfill writing already and I couldn&#8217;t find any. So, I decided to submit a proposal to <a href="http://jsconf.eu" target="_blank">JSConf EU</a>, even though the call for speakers had passed 10 days ago. When I read <a href="http://twitter.com/#!/cramforce/status/90737580466896896" target="_blank">@cramforce&#8217;s tweet</a> that they had decided on most of the speakers, I spent a few days stressed as hell, checking my inbox every few minutes and hoping that my gut feeling that I would get accepted was right.</p>
<p>And it was! 3 days ago I received an email from JSConf EU that my proposal was accepted!! I can&#8217;t even begin to describe how happy and excited I am about it. And nervous too: What if they know everything I&#8217;m going to say? What if they hate my talk? What if the JavaScript industry is really as sexist as some people claim and they dismiss me because of my gender? I decided to put my fears aside and start working on my slides, as I couldn&#8217;t wait until later (even though I have multiple deadlines creeping up on me right now&#8230;).</p>
<p>A big part of writing polyfills is feature detection. Before trying to implement a feature with JavaScript, you first have to check if it&#8217;s already supported. So, a substantial portion of my talk will be about that. How to detect if APIs, HTML elements, CSS properties/values/selectors etc are supported. There are already established solutions and techniques about most of these, except CSS selectors. <a href="http://www.modernizr.com/" target="_blank">Modernizr</a> doesn&#8217;t detect any, and judging from <a href="http://www.google.com/webhp?sourceid=chrome-instant&amp;ie=UTF-8&amp;ion=1&amp;nord=1#sclient=psy&amp;hl=en&amp;safe=off&amp;nord=1&amp;site=webhp&amp;source=hp&amp;q=detect%20css%20selector%20support&amp;pbx=1&amp;oq=&amp;aq=&amp;aqi=&amp;aql=&amp;gs_sm=&amp;gs_upl=&amp;fp=39b0a615b729321b&amp;ion=1&amp;ion=1&amp;bav=on.2,or.r_gc.r_pw.&amp;fp=39b0a615b729321b&amp;biw=1280&amp;bih=679&amp;ion=1" target="_blank">my Google search</a> nobody has written about any techniques for doing so in a generic fashion.</p>
<p>A really simple way to detect CSS selectors support is using <code>document.querySelector()</code> in a <code>try...catch</code> statement. If the selector is not supported, an error will be thrown. However, that&#8217;s not really reliable, as the Selectors API is not supported in IE &lt; 8. So, I thought of another idea: What if I turn the hassle of reading out a stylesheet via the DOM methods (browsers drop stuff they don&#8217;t understand) into a feature detection method?</p>
<p>The basic idea is creating a new <code>&lt;style&gt;</code> element with an empty rule and the selector we want to test support for, and then read out the stylesheet through the DOM methods to see if a rule actually exists. I&#8217;ve so far tested it in Firefox, Opera and Chrome and it seems to work. I haven&#8217;t tested it in IE yet, as I currently have too many apps running to turn on the vm, so it might need a few fixes to work there (or I might be unlucky and the idea might not work at all).</p>
<p>You can test it out yourself in this <a href="http://jsfiddle.net/leaverou/Pmn8m/" target="_blank">fiddle</a>, just check the console: <a href="http://fiddle.jshell.net/leaverou/Pmn8m/show/light/">http://fiddle.jshell.net/leaverou/Pmn8m/show/light/</a></p>
<p>Apologies if this has already been documented elsewhere, I really couldn&#8217;t find anything.</p>
<p><strong>Edit:</strong> <a href="http://jsfiddle.net/Skateside/5dKc7/5/">James Long worked on fixing my example&#8217;s issues with IE</a></p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/07/detecting-css-selectors-support-my-jsconf-eu-talk/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>A polyfill for HTML5 progress element, the obsessive perfectionist way</title>
		<link>http://lea.verou.me/2011/07/a-polyfill-for-html5-progress-element-the-obsessive-perfectionist-way/</link>
		<comments>http://lea.verou.me/2011/07/a-polyfill-for-html5-progress-element-the-obsessive-perfectionist-way/#comments</comments>
		<pubDate>Sat, 02 Jul 2011 06:16:19 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Apps & scripts]]></category>
		<category><![CDATA[Original]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[shims and polyfills]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=1143</guid>
		<description><![CDATA[Yesterday, for some reason I don&#8217;t remember, I was looking once more at Paul Irish&#8217;s excellent list of polyfills on Github. I was really surprised to see that there are none for the &#60;progress&#62; element. It seemed really simple: Easy to fake with CSS and only 4 IDL attributes (value, max, position and labels). &#8220;Hey, [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F07%252Fa-polyfill-for-html5-progress-element-the-obsessive-perfectionist-way%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FrDkalP%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22A%20polyfill%20for%20HTML5%20progress%20element%2C%20the%20obsessive%20perfectionist%20way%22%20%7D);"></div>
<p><a href="http://lea.verou.me/wp-content/uploads/2011/07/Screen-shot-2011-11-15-at-15.02.37-.png"><img src="http://lea.verou.me/wp-content/uploads/2011/07/Screen-shot-2011-11-15-at-15.02.37--300x219.png" alt="" title="Progress polyfill, project page screenshot" width="300" height="219" class="alignleft size-medium wp-image-1444" /></a>Yesterday, for some reason I don&#8217;t remember, I was looking once more at <a href="https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills" target="_blank">Paul Irish&#8217;s excellent list of polyfills on Github</a>. I was really surprised to see that there are none for <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#the-progress-element" target="_blank">the &lt;progress&gt; element</a>. It seemed really simple: Easy to fake with CSS and only 4 IDL attributes (value, max, position and labels). &#8220;Hey, it sounds fun and easy, I&#8217;ll do it!&#8221;, I thought. I have no idea how in only 1 day this turned into &#8220;OMG, my brain is going to explode&#8221;. I&#8217;ve documented below all the pitfalls I faced. And don&#8217;t worry, it has a happy ending: I did finish it. And <a href="https://github.com/LeaVerou/HTML5-Progress-polyfill" target="_blank">published it</a>. So, if you&#8217;re not interested in long geeky stories, just jump straight to <a href="http://lea.verou.me/polyfills/progress/" target="_blank">its page</a>.<span id="more-1143"></span></p>
<h2>First things first: Controlling the width of the value bar</h2>
<p>Most progress bars out there use 2 elements: One for the container and one for the value bar. I was pretty stubborn about not using an extra element. I wanted to use pseudo-elements instead and keep the DOM tree as clean as I found it. And there it was, the first problem: How to set the width?</p>
<p>CSS3 attr() and calc() are hardly supported and <a href="http://lea.verou.me/2010/09/on-attr-and-calc/" target="_blank">attr() is not even allowed in calc()</a>, so I quickly realized that a pure CSS solution was out of the question. However, if I used JavaScript, how would I set a different width for every progress::before? You can&#8217;t set that in an inline style, and assigning every &lt;progress&gt; element an ID and adding separate rules seems a bit too intrusive to me. Think about it for a second, what would you do?</p>
<p>I realized I had to control the width of the pseudo-element through CSS properties of the parent container somehow. And then it dawned on me: If the pseudoelement has <code>display:block</code>, it will automatically get the parent width, minus the padding and borders. There it was, this was my solution. I just had to set <code>padding-right</code> accordingly, so that the value bar gets the width it needs to be! And I had already given it <code>box-sizing: border-box</code>, as it was in Webkit&#8217;s UA stylesheet, so I didn&#8217;t have to worry about padding changing the width of the element. The first problem was solved.</p>
<h2>Becoming dynamic</h2>
<p>The static part was quite easy indeed. Selecting all &lt;progress&gt; elements and using their attributes to set an appropriate padding-right was pretty much run of the mill. But that wasn&#8217;t enough. What happens if you set the properties through script? What happens if you set the attributes? The progress bar should update accordingly, it had to be dynamic. A static progress bar is not much of a fallback. It might be acceptable for &lt;meter&gt;, since in most interfaces it&#8217;s used in a static way. But a progress bar needs to change in order to show um, <em>progress</em>.</p>
<p>First step was adding the properties that are in its DOM Interface. &#8220;Easy, I&#8217;ll add them to the prototype&#8221; thought my naïve self. So, I needed to find which prototype, I didn&#8217;t want to add them in every HTML element of course. So I eagerly typed <code>Object.prototype.toString.call(document.createElement('progress'))</code> in Firebug&#8217;s console and it slapped me in the face with an <code>'[object HTMLUnknownElement]'</code>. D&#8217;oh! I had forgotten that unknown elements share a common prototype named like that. So, I had to add them to each one individually. I hated that, but since it was the only way, I did it and moved on.</p>
<p>Of course, I didn&#8217;t just assign a static value to them, otherwise they wouldn&#8217;t solve much: The progress bar would still be static. I assigned getters and setters that used the <code>value</code> and <code>max</code> attributes to return what they should. Assigning getters and setters to a property is a whole new problem by itself, as some browsers use <code>__defineGetter__</code>/<code>__defineSetter__ </code>and some others the ES5 standard <code>Object.defineProperty</code>. But <a href="http://lea.verou.me/2011/05/strongly-typed-javascript/" target="_blank">I had solved that one before</a>, so it didn&#8217;t slow me down.</p>
<p>The getters and setters solved the issue one-way only: If you set the properties, the progress bar and its attributes would be updated. That would be enough for most authors using the polyfill, but no, I wanted it to be <em>perfect</em>. &#8220;If you change the attributes, the progress bar and its properties should too!&#8221; my annoyingly pedantic inner self insisted. &#8220;And what if you dynamically add more &lt;progress&gt; elements?&#8221;. </p>
<p>There are two ways to do stuff when attributes change and elements get added: Polling and <a href="http://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-eventgroupings-mutationevents" target="_blank">mutation events</a>. The advantage of polling is its perfect browser support, which comes at a big cost: It&#8217;s horrible performance-wise. Also, polling introduces a delay that could be unacceptable in some cases, especially considering how short the duration of some progress bar use cases is. So, I went with mutation events, even though they are deprecated (seriously W3C? deprecating something, without providing a solid alternative??) and don&#8217;t have perfect browser support. After all, it was the only way (I don&#8217;t consider polling a real option in this case).</p>
<h2>Styling</h2>
<p>After messing around a little, it seemed to work great in Opera 10.63 and Firefox 5, which I had open for my tests. It was time to write some unit tests and check it out in more browsers. Instead, I opted to style it, as a desperate attempt to delay my confrontation with IE8 a bit longer (and for good reason, as it turned out later). Given that CSS is kinda my specialization, I expected styling to be a piece of cake and even relaxing. Instead, it came with it&#8217;s fair share of trouble and hard dilemmas.</p>
<p>If you notice the native progress bars in OSX, you will see that they use gradients. I mocked up something similar with CSS gradients, which wasn&#8217;t easy, as I wanted to keep the hue/saturation information in the background-color only, for easy modifications and Webkit uses a regular gradient with color stops that have different hues and saturations. And then I realised that this was not going to show up at all in IE8-IE9, which were 2 major browsers that my polyfill would target. No gradient may be acceptable in determinate progress bars, but it&#8217;s not an option in indeterminate ones: Scrolling diagonal stripes is the convention and there&#8217;s no other way to communicate this status to the average user.</p>
<p>So I decided to go with the old way of using raster images for gradients (through a data URI). Another painful slap in the face was when I realized that those moving stripes need to be semi-transparent. To do that, my options were:</p>
<ul>
<li>CSS3 animations &#8211; no good in my case, as it&#8217;s crucial to show up and their browser support isn&#8217;t that good</li>
<li>SVG with SMIL &#8211; Much better browser support than CSS3 animations, but still no go in IE</li>
<li>APNG &#8211; Only supported by Firefox and Opera, even after all these years</li>
</ul>
<p>I happened to be chatting with <a href="http://xanthir.com/blog" target="_blank">Tab Atkins</a> at the moment, and he suggested I go with plain ol&#8217; GIFs. I was originally negative, but after thinking about it I realized that antialiasing is not that crucial in 45deg stripes, especially when they&#8217;re moving. I tried it, I liked the result, so I kept it. Phew, that one was easy.</p>
<h2>The IE8 nightmare</h2>
<p>After spending a few hours tweaking the gradients and the CSS (yes, hours. I said I&#8217;m an obsessive perfectionist, didn&#8217;t I?) I finally wrote some unit tests and fired up Virtualbox to test with IE8. I prepared myself for the worst, and secretly hoped I&#8217;d be pleasantly surprised. Instead, I faced a developer&#8217;s worst nightmare. Two words: Stack overflow.</p>
<p>The culprit was a classic IE bug with DOM properties and HTML attrtibutes that I had blissfully forgotten: IE thinks they&#8217;re the same. I had added getters and setters (or etters, as I like to call both) to the max and value <em>properties</em> which used the max and value <em>attributes</em>, resulting in infinite recursion in IE8.</p>
<p>This was the hardest of all problems, and I never completely solved it: A few unit tests still fail in IE8 because of it, although there&#8217;s no infinite recursion any more. Luckily, this bug was fixed in IE9, so the polyfill works flawlessly there.</p>
<p>My first idea was the obvious one: to duplicate the values somewhere. In a lookup table, in another property, somewhere. I didn&#8217;t quite like the idea, so I kept brainstorming. And then it dawned on me. They&#8217;re already duplicated somewhere, and not only it&#8217;s not redundant, but actually encouraged: in the WAI-ARIA attributes!</p>
<p>To clarify, when progress elements are natively supported, they already have built-in ARIA roles and attributes. However, when they&#8217;re not, you should add them yourself, if you want the control to be accessible. From my research, there was a <code>progressbar</code> role, and it required the attributes <code>aria-valuemin</code>, <code>aria-valuemax</code>,<code> aria-valuenow</code> and <code>aria-labelledby</code>. I implemented all but the latter, as it proved too much of a hassle for very few edge cases (how many people put IDs in their <em>labels</em> without using aria-labelledby themselves?). So, <code>aria-valuemax</code> was already duplicating <code>max</code> and <code>aria-valuenow</code> was duplicating <code>value</code>. I changed everything to use those instead.</p>
<p>After lots of head-scratching, IE-cursing and feeling that my brain was going to explode all over my laptop, I managed to kinda have it working. I knew in advance that some unit tests would fail, as it doesn&#8217;t support mutation events. I eventually gave up when I realized that the last unit test in the &#8220;static&#8221; category failed because <code>getAttribute('max')</code> returned <code>null</code>, since IE had completely removed the attribute from the DOM tree. It was the last straw and made me say &#8220;That&#8217;s it, I&#8217;m done with this piece of shit&#8221;.</p>
<h2>Safari 5 craziness</h2>
<p>After IE, it was Safari&#8217;s turn. I knew that I could only target Safari 5, as Safari 4 doesn&#8217;t support etters on DOM elements and Safari 5.1 will probably support progress elements natively, since they&#8217;ve been in Webkit for ages. I launched Safari without fear. &#8220;How can it possibly not work in Safari? It will probably be fine, maybe just need a one or two little tweaks in the worst case&#8221;, I reassured myself thinking.</p>
<p>The progress bars were not even showing. At all. My first guess was that it was a one time rendering error. When it persisted after a few reloads, I opened the dev tools to see what the hell happened. I saw a series of errors like this:</p>
<pre>&lt;progress&gt; is not allowed inside &lt;label&gt;. Content ignored.
Unmatched &lt;/progress&gt; encountered.  Ignoring tag.</pre>
<p>At first, I thought the problem was the label. So I made all labels external. And then still got the same errors for the &lt;li&gt;s. And every other element I tried. Even when I put them directly into the &lt;body&gt;, Safari complained that they are not allowed to be inside it! It turned out that this was a bug in a build of Webkit, and coincidentally, this build was the one Safari 5 uses.</p>
<p>There wasn&#8217;t much to think about in this one: They&#8217;re not in the DOM, so I can&#8217;t do anything about them. It&#8217;s mission impossible.</p>
<h2>Happy(?) end</h2>
<p>After IE8&#8242;s and Safari5&#8242;s cruel rejection, I was quite dispirited. IE8 had already caused me to make my code uglier and more verbose, and now Safari 5 flat out refuses to accept any treatment. It worked flawlessly in Firefox 3.5, but that didn&#8217;t cheer me up much. I decided that this has already taken up too much of my time. It&#8217;s now the community&#8217;s turn. Have any ideas about how further improvement? Maybe some more unit tests? I’ll be waiting for your pull requests! <img src='http://lea.verou.me/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
<a href="https://github.com/LeaVerou/HTML5-Progress-polyfill">Github repo</a></p>
<h2>Appendix: Why do some unit tests fail in browsers that natively support &lt;progress&gt;?</h2>
<p>While developing this, I discovered 2 browser bugs: One in Webkit&#8217;s implementation and in for Opera&#8217;s. I plan to report these soon.</p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/07/a-polyfill-for-html5-progress-element-the-obsessive-perfectionist-way/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>CSS reflections for Firefox, with -moz-element() and SVG masks</title>
		<link>http://lea.verou.me/2011/06/css-reflections-for-firefox-with-moz-element-and-svg-masks/</link>
		<comments>http://lea.verou.me/2011/06/css-reflections-for-firefox-with-moz-element-and-svg-masks/#comments</comments>
		<pubDate>Wed, 29 Jun 2011 20:31:46 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Original]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[CSS3 image values]]></category>
		<category><![CDATA[SVG]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=1132</guid>
		<description><![CDATA[We all know about the proprietary (and imho, horrible) -webkit-box-reflect. However, you can create just as flexible reflections in Firefox as well, by utilizing -moz-element(), some CSS3 and Firefox&#8217;s capability to apply SVG effects to HTML elements. And all these are actually standards, so eventually, this will work in all browsers, unlike -webkit-box-reflect, which was [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F06%252Fcss-reflections-for-firefox-with-moz-element-and-svg-masks%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FkDZ9rk%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22CSS%20reflections%20for%20Firefox%2C%20with%20-moz-element%28%29%20and%20SVG%20masks%22%20%7D);"></div>
<p>We all know about the proprietary (and imho, horrible) <code>-webkit-box-reflect.</code> However, you can create just as flexible reflections in Firefox as well, by utilizing <a href="https://developer.mozilla.org/en/CSS/-moz-element" target="_blank">-moz-element()</a>, some CSS3 and Firefox&#8217;s capability to apply <a href="https://developer.mozilla.org/En/Applying_SVG_effects_to_HTML_content" target="_blank">SVG effects to HTML elements</a>. And all these are actually standards, so eventually, this will work in all browsers, unlike <code>-webkit-box-reflect</code>, which was never accepted by the CSS WG.</p>
<p>First and foremost, have a look at the <a href="http://lea.verou.me/demos/reflection/">demo</a>:<br />
<iframe src="http://lea.verou.me/demos/reflection/" width="100%" height="500px"></iframe></p>
<h2>How it works</h2>
<ul>
<li>For every element, we generate an <code>::after</code> pseudoelement with the same dimensions and a position of being right below our original element.</li>
<li>Then, we make it appear the same as our element, by giving it a background of <code>&#8209;moz-element(#element-id)</code> and no content.</li>
<li>Reflections are flipped, so we flip it vertically, by applying <code>transform: scaleY(&#8209;1);</code></li>
<li>If we want the reflection to have a little distance from the element (for example 10px like the demo), we also apply a transform of <code>translateY(10px)</code></li>
<li>We want the reflection to not be as opaque as the real element, so we give it an <code>opacity</code> of around 0.3-0.4</li>
<li>At this point, <strong>we already have a decent reflection</strong>, and we didn&#8217;t even need SVG masks yet. It&#8217;s essentially the same result -webkit-box-reflect gives if you don&#8217;t specify a mask image. However, to really make it look like a reflection, we apply a mask through an SVG and the <code>mask</code> CSS property. In this demo, the SVG is external, but it could be a data URI, or even embedded in the HTML.</li>
</ul>
<h2>Caveats</h2>
<ul>
<li>Won&#8217;t work with replaced elements (form controls, images etc).</li>
<li>If you have borders, it gets a bit more complicated to size it properly</li>
<li>Doesn&#8217;t degrade gracefully, you still get the pseudoelement in other browsers, so you need to filter it out yourself</li>
<li>Bad browser support (currently only Firefox 4+)</li>
<li>You need to set the reflection&#8217;s background for every element and every element needs an id to use it (but this could be done automatically via script)</li>
</ul>
<h2>Further reading</h2>
<ul>
<li><a href="http://www.w3.org/TR/css3-images/#element-reference">element() function</a></li>
<li><a href="http://people.mozilla.com/~roc/SVG-CSS-Effects-Draft.html">SVG effects for CSS</a></li>
<li><strong>Edit:</strong> <a href="https://hacks.mozilla.org/2010/08/mozelement/">Turns out Paul Rouget did something similar before me, back in August 2010</a>. The pros of this approach is that it works with replaced elements as well, the cons is that it requires extra markup and JavaScript.</li>
</ul>
<p>Credits: Thanks to <a href="http://wait-till-i.com/">Christian Heilmann</a> for helping me debug why SVG masks for HTML elements weren&#8217;t originally working for me.</p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/06/css-reflections-for-firefox-with-moz-element-and-svg-masks/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Pure CSS Tic Tac Toe</title>
		<link>http://lea.verou.me/2011/06/pure-css-tic-tac-toe/</link>
		<comments>http://lea.verou.me/2011/06/pure-css-tic-tac-toe/#comments</comments>
		<pubDate>Fri, 17 Jun 2011 22:53:35 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Original]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[CSS3 selectors]]></category>
		<category><![CDATA[indeterminate]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=1103</guid>
		<description><![CDATA[It&#8217;s supposed to be used by 2 people taking turns (click twice for the other sign). Basic idea: It uses hidden checkboxes for the states (indeterminate means empty, checked means X, not checked means O) and labels for the visible part When it starts, a little script (the only js in the demo) sets the [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F06%252Fpure-css-tic-tac-toe%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FkEXjk2%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Pure%20CSS%20Tic%20Tac%20Toe%22%20%7D);"></div>
<p>It&#8217;s supposed to be used by 2 people taking turns (click twice for the other sign).</p>
<p>Basic idea:</p>
<ul>
<li>It uses hidden checkboxes for the states (indeterminate means empty, checked means X, not checked means O) and labels for the visible part</li>
<li>When it starts, a little script (the only js in the demo) sets the states of all checkboxes to indeterminate.</li>
<li>It uses the <code>:checked</code> and <code>:indeterminate</code> pseudo-classes and sibling combinators to change the states and show who won.</li>
<li>Once somebody clicks on a checkbox (or in this case, its label) they change it&#8217;s state from indeterminate to either checked or not checked, depending on how many times they click on it.</li>
</ul>
<p><span id="more-1103"></span><br />
<strong>As a bonus, it&#8217;s perfectly accessible through the keyboard</strong> (although I assume it&#8217;s not screen reader accessible).</p>
<p>A &lt;table&gt; would be much more appropriate for the markup, but I decided to sacrifice semantics in this case to make the demo simpler.</p>
<p>All modern browsers support the indeterminate state in checkboxes (for Opera you will need the latest Opera.Next), however <strong>this demo doesn&#8217;t work on old Webkit (Chrome and Safari) because of an old bug</strong> that made the sibling combinators (+ and ~) static in some cases which has been fixed in the nightlies. <strong>It should work in Firefox, Opera.next, Webkit nightlies and IE9, although I haven&#8217;t tested in Opera.next and IE9 to verify.</strong></p>
<p>Enjoy:<br />
<iframe style="width: 100%; height: 350px" src="http://jsfiddle.net/leaverou/5X5Tq/embedded/result,css,html,js"></iframe></p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/06/pure-css-tic-tac-toe/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Change URL hash without page jump</title>
		<link>http://lea.verou.me/2011/05/change-url-hash-without-page-jump/</link>
		<comments>http://lea.verou.me/2011/05/change-url-hash-without-page-jump/#comments</comments>
		<pubDate>Fri, 13 May 2011 21:40:05 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Original]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[History API]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=1053</guid>
		<description><![CDATA[In modern complex layouts, sometimes the point where a hash will transport you to will be entirely different than the one you actually wanted. If you prevent the default event, you will save yourself from the page jump, but the hash won&#8217;t change either. You can accept the regular behavior and change scrollTop after the [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F05%252Fchange-url-hash-without-page-jump%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FiRDLcc%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Change%20URL%20hash%20without%20page%20jump%22%20%7D);"></div>
<p>In modern complex layouts, sometimes the point where a hash will transport you to will be entirely different than the one you actually wanted. If you prevent the default event, you will save yourself from the page jump, but the hash won&#8217;t change either. You can accept the regular behavior and change scrollTop after the jump, but the user will still see a distracting flicker.<br />
<a href="http://css-tricks.com/" target="_blank">Chris Coyier</a> found <a href="http://css-tricks.com/hash-tag-links-padding/" target="_blank">a great workaround</a> last year but it&#8217;s not meant for every case.</p>
<h2>A different solution</h2>
<p>Turns out we can take advantage of the <a href="http://www.w3.org/TR/html5/history.html#the-history-interface" target="_blank">History API</a> to do that quite easily. It&#8217;s just one line of code:</p>
<pre>history.pushState(null, null, '#myhash');</pre>
<p>and we can combine it with the old method of setting location.hash to cater for older browsers as well:</p>
<pre>if(history.pushState) {
    history.pushState(null, null, '#myhash');
}
else {
    location.hash = '#myhash';
}
</pre>
<h2>Browser support?</h2>
<p>The History API is supported by:</p>
<ul>
<li>Firefox 4+</li>
<li>Safari 5+</li>
<li>Chrome 8+</li>
<li>Coming soon in Opera</li>
</ul>
<p>Enjoy <img src='http://lea.verou.me/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/05/change-url-hash-without-page-jump/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>StronglyTyped: A library for strongly typed properties &amp; constants in JavaScript</title>
		<link>http://lea.verou.me/2011/05/strongly-typed-javascript/</link>
		<comments>http://lea.verou.me/2011/05/strongly-typed-javascript/#comments</comments>
		<pubDate>Thu, 05 May 2011 23:11:30 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Apps & scripts]]></category>
		<category><![CDATA[Original]]></category>
		<category><![CDATA[ES5]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=983</guid>
		<description><![CDATA[I&#8217;ll start by saying I love the loosely typed nature of JavaScript. When I had to work with strongly typed languages like Java, it always seemed like an unnecessary hassle. On the contrary, my boyfriend even though very proficient with HTML, CSS and SVG, comes from a strong Java background and hates loosely typed scripting [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F05%252Fstrongly-typed-javascript%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2Fj7Sc7x%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22StronglyTyped%3A%20A%20library%20for%20strongly%20typed%20properties%20%26%20constants%20in%20JavaScript%22%20%7D);"></div>
<p><a href="http://www.flickr.com/photos/leaverou/5691500699/in/photostream"><img class="alignleft size-medium wp-image-987" title="StronglyTyped logo" src="http://lea.verou.me/wp-content/uploads/2011/05/strongly-typed-300x210.png" alt="StronglyTyped" width="300" height="210" /></a>I&#8217;ll start by saying I <strong>love</strong> the loosely typed nature of JavaScript. When I had to work with strongly typed languages like Java, it always seemed like an unnecessary hassle. On the contrary, my boyfriend even though very proficient with HTML, CSS and SVG, comes from a strong Java background and hates loosely typed scripting languages. So, to tempt him into JS and keep him away from heavy abstractions like Objective-J, I wrote a little library that allows you to specify strongly typed properties (and since global variables are also properties of the window object, those as well) of various types (real JS types like <code>Boolean</code>, <code>Number</code>, <code>String</code> etc or even made up ones like <code>Integer</code>) and constants (final properties in Java). It uses ES5 getters and setters to do that and falls back to regular, loosely typed properties in non-supporting browsers.<br />
<span id="more-983"></span></p>
<p>Also, as a bonus, you get cross-browser <code>Function.prototype.bind</code> and <code>Array.prototype.forEach</code> and a robust type checking function: <code>StronglyTyped.is(type, value)</code>.</p>
<h2>Example: Strongly typed properties</h2>
<p>You define strongly typed properties by using the corresponding methods of the <code>StronglyTyped</code> object. For example, the following snippet defines a boolean property called &#8220;foo&#8221; on an object literal:</p>
<pre>var o = {};

StronglyTyped.boolean(o, 'foo', true);

console.log(o.foo); // prints true

o.foo = false;
console.log(o.foo); // prints false

o.foo = 'bar'; // <strong style="color: red;">TypeError: foo must be of type Boolean. bar is not.</strong></pre>
<h2>Example: Constants</h2>
<p>You define constants by using the <code>constant</code> method of the <code>StronglyTyped</code> object. For example, the following snippet defines a global MAGIC_NUMBER constant:</p>
<pre>var o = {};

StronglyTyped.constant(window, 'MAGIC_NUMBER', 3.1415926535);

console.log(MAGIC_NUMBER); // prints 3.1415926535

MAGIC_NUMBER = 4;
console.log(MAGIC_NUMBER); // prints 3.1415926535
</pre>
<p>Please note that constants only become read-only after they first get a non-undefined value. For example:</p>
<pre>StronglyTyped.constant(window, 'MAGIC_NUMBER');

console.log(MAGIC_NUMBER); // prints undefined

MAGIC_NUMBER = undefined;

console.log(MAGIC_NUMBER); // prints undefined

MAGIC_NUMBER = 3.1415926535;
console.log(MAGIC_NUMBER); // prints 3.1415926535

MAGIC_NUMBER = 4;
console.log(MAGIC_NUMBER); // prints 3.1415926535</pre>
<h2>Supported types</h2>
<p>The property types currently supported by StronglyTyped are:</p>
<ul>
<li>Array</li>
<li>Boolean</li>
<li>Date</li>
<li>Function</li>
<li>Integer</li>
<li>Number</li>
<li>RegExp</li>
<li>String</li>
</ul>
<p><code>null</code> and <code>undefined</code> are valid in every type. <code>NaN</code> and <code>Infinity</code> values are accepted in both the Number and the Integer types.</p>
<p>If you want to use a type that&#8217;s not among the above but either is native to the browser (for example <code>Element</code>) or a global object, you can use the generic method <code>StronglyTyped.property(type, object, property [, initialValue])</code>:</p>
<pre>var o = {};

StronglyTyped.property('Element', o, 'foo', document.body);

console.log(o.foo); // prints a representation of the &lt;body&gt; element

o.foo = document.head;
console.log(o.foo); // prints a representation of the &lt;head&gt; element

o.foo = 5; // <strong style="color: red;">TypeError: foo must be of type Element. 5 is not.</strong></pre>
<h2>Browser support</h2>
<p>It should work on every browser that supports <code>Object.defineProperty</code> or <code>__defineGetter__</code> and <code>__defineSetter__</code>. As you can see from kangax&#8217;s awesome compatibility tables for <a href="http://kangax.github.com/es5-compat-table/">Object.defineProperty</a> and <a href="http://kangax.github.com/es5-compat-table/non-standard/">__define(G|S)etter__</a>, those are:</p>
<ul>
<li>Firefox 3.5+</li>
<li>IE8 (only on DOM elements)</li>
<li>IE9+</li>
<li>Opera 10.5+</li>
<li>Chrome 5+</li>
<li>Safari 4+</li>
<li>Konqueror 4.4+</li>
</ul>
<p>However, it&#8217;s only verified to work in:</p>
<ul>
<li>Firefox 4 (Win and OSX)</li>
<li>IE9+</li>
<li>Opera 11.10 for OSX, Opera 11 for Windows</li>
<li>Chrome (Win and OSX)</li>
<li>Safari 5 (Win and OSX)</li>
</ul>
<p><strong>This doesn&#8217;t mean it won&#8217;t work in the rest</strong>, just that it hasn&#8217;t been tested there (yet). You can load <a href="http://leaverou.github.com/StronglyTyped/">the unit tests (sort of&#8230;)</a> in a browser you want to test and let me know about the results. <img src='http://lea.verou.me/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Naice! Can I haz?</h2>
<p>As usual, you can get it from Github: <a href="https://github.com/LeaVerou/StronglyTyped" class="view-demo">Github repo</a></p>
<h2>Credits</h2>
<p>Thanks a lot to Max (<a href="http://twitter.com/suprMax">@suprMax</a>) for Windows testing!</p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/05/strongly-typed-javascript/feed/</wfw:commentRss>
		<slash:comments>50</slash:comments>
		</item>
		<item>
		<title>CSS3 patterns gallery and a new pattern</title>
		<link>http://lea.verou.me/2011/04/css3-patterns-gallery-and-a-new-pattern/</link>
		<comments>http://lea.verou.me/2011/04/css3-patterns-gallery-and-a-new-pattern/#comments</comments>
		<pubDate>Fri, 15 Apr 2011 15:32:20 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Apps & scripts]]></category>
		<category><![CDATA[Original]]></category>
		<category><![CDATA[css3 gradients]]></category>
		<category><![CDATA[patterns]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=932</guid>
		<description><![CDATA[I finally got around to doing what I wanted to do for quite a few months: Create a gallery with all the basic patterns I was able to create with CSS3 gradients. Here it is:  CSS3 Pattern Gallery Also, it includes a brand new pattern, which is the hardest one I have ever made so [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F04%252Fcss3-patterns-gallery-and-a-new-pattern%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FdKWRfr%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22CSS3%20patterns%20gallery%20and%20a%20new%20pattern%22%20%7D);"></div>
<p><a href="http://lea.verou.me/wp-content/uploads/2011/04/csspatterns.png"><img src="http://lea.verou.me/wp-content/uploads/2011/04/csspatterns-300x177.png" alt="" title="Screenshot from the gallery" width="300" height="177" class="alignleft size-medium wp-image-1356" /></a>I finally got around to doing what I wanted to do for quite a few months: Create a gallery with all the basic patterns I was able to create with CSS3 gradients. Here it is: <br />
<a href="http://lea.verou.me/css3patterns/" class="view-demo">CSS3 Pattern Gallery</a></p>
<p>Also, it includes a brand new pattern, which is the hardest one I have ever made so far: Japanese cubes. Thanks to <a href="http://twitter.com/dstorey" target="_blank">David Storey</a> for challenging me about it.</p>
<p>Supported browsers:</p>
<ul>
<li>Firefox 4 (the patterns themselves work on 3.6 too but the gallery doesn&#8217;t due to a JS limitation)</li>
<li>Opera 11.10</li>
<li>IE10</li>
<li>Google Chrome</li>
<li>Webkit nightlies</li>
</ul>
<p>However bear in mind that every implementation has its limitations so a few of them won&#8217;t work in all the aforementioned browsers (for example Opera doesn&#8217;t support radial gradients and Firefox doesn&#8217;t support explicitly sized ones).</p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/04/css3-patterns-gallery-and-a-new-pattern/feed/</wfw:commentRss>
		<slash:comments>33</slash:comments>
		</item>
		<item>
		<title>Invert a whole webpage with CSS only</title>
		<link>http://lea.verou.me/2011/04/invert-a-whole-webpage-with-css-only/</link>
		<comments>http://lea.verou.me/2011/04/invert-a-whole-webpage-with-css-only/#comments</comments>
		<pubDate>Thu, 14 Apr 2011 20:28:51 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Original]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[CSS]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=920</guid>
		<description><![CDATA[I recently saw Paul Irish&#8217;s jQuery invert page plugin. It inverts every color on a webpage including images or CSS. This reminded me of the invert color keyword that&#8217;s allowed on outlines (and sadly only supported by Opera and IE9+). So I wondered how it could be exploited to achieve the same effect through CSS [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F04%252Finvert-a-whole-webpage-with-css-only%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2Fh9xH7V%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Invert%20a%20whole%20webpage%20with%20CSS%20only%22%20%7D);"></div>
<p><a href="http://lea.verou.me/wp-content/uploads/2011/04/Screen-shot-2011-04-14-at-22.24.18-.png"><img class="alignleft size-medium wp-image-922" title="Screenshot from the effect applied on my blog" src="http://lea.verou.me/wp-content/uploads/2011/04/Screen-shot-2011-04-14-at-22.24.18--300x199.png" alt="" width="300" height="199" /></a>I recently saw <a href="https://gist.github.com/373253" target="_blank">Paul Irish&#8217;s jQuery invert page plugin</a>. It inverts every color on a webpage including images or CSS. This reminded me of the invert color keyword that&#8217;s allowed on outlines (and sadly only supported by Opera and IE9+). So I wondered how it could be exploited to achieve the same effect through CSS alone. Turned out to be quite simple actually:</p>
<pre>body:before {
	content:"";
	position:fixed;
	top:50%; left: 50%;
	z-index:9999;
	width:1px; height: 1px;
	outline:2999px solid invert;
}</pre>
<p>Not even <code>pointer-events:none;</code> is needed, since outlines don&#8217;t receive pointer events anyway, and there&#8217;s no issue with scrollbars since they don&#8217;t contribute to scrolling. So this is not even CSS3, it&#8217;s just plain ol&#8217; CSS 2.1.</p>
<p>And here&#8217;s a bookmarklet to inject it into any given page: <a href="javascript:(function(){var%20style=document.createElement('style');style.innerHTML='body:before%20{%20content:%22%22;%20position:fixed;%20top:50%25;%20left:50%25;%20z-index:9999;%20width:1px;%20height:%201px;%20outline:2999px%20solid%20invert;%20}';document.body.appendChild(style)})();" class="view-demo">Invert page</a></p>
<p><strong>Note:</strong>This will only work on Opera and IE9+ since they&#8217;re currently the only ones supporting the color keyword &#8216;invert&#8217; on outlines. However, it&#8217;s probably possible to add Firefox support too with SVG filters, since they support them on HTML elements as well.</p>
<p>As for why would someone want to invert a page&#8230; I guess it could be useful for people that can read white text on dark backgrounds more easily, April fools jokes, konami code fun and stuff like that.</p>
<p><strong>Update:</strong> Mozilla is planning to <strong>never</strong> support <code>invert</code> because there&#8217;s a <a href="http://www.w3.org/TR/CSS21/ui.html#propdef-outline-color">loophole in the CSS 2.1 spec</a> that allows them to do that. However, you can push them to support it by <a href="https://bugzilla.mozilla.org/votes.cgi?action=show_user&#038;bug_id=359497#vote_359497">voting</a> on the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=359497">relevant issue</a>.</p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/04/invert-a-whole-webpage-with-css-only/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Create complex RegExps more easily</title>
		<link>http://lea.verou.me/2011/03/create-complex-regexps-more-easily/</link>
		<comments>http://lea.verou.me/2011/03/create-complex-regexps-more-easily/#comments</comments>
		<pubDate>Mon, 28 Mar 2011 16:05:45 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Original]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[RegExp]]></category>
		<category><![CDATA[regular expressions]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=916</guid>
		<description><![CDATA[When I was writing my linear-gradient() to -webkit-gradient() converter, I knew in advance that I would have to use a quite large regular expression to validate and parse the input. Such a regex would be incredibly hard to read and fix potential issues, so I tried to find a way to cut the process down [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F03%252Fcreate-complex-regexps-more-easily%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FfEXA40%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Create%20complex%20RegExps%20more%20easily%22%20%7D);"></div>
<p>When I was writing <a href="http://lea.verou.me/2011/03/convert-standard-gradient-syntax-to-webkit-gradient-and-others/">my linear-gradient() to -webkit-gradient() converter</a>, I knew in advance that I would have to use a quite large regular expression to validate and parse the input. Such a regex would be incredibly hard to read and fix potential issues, so I tried to find a way to cut the process down in reusable parts.</p>
<p>Turns out JavaScript regular expression objects have a .source property that can be used in the RegExp constructor to create a new RegExp out of another one. So I wrote a new function that takes a string with identifiers for regexp replacements in {{ and }} and replaces them with the corresponding sub-regexps, taken from an object literal as a second argument:</p>
<pre>/**
 * Create complex regexps in an easy to read way
 * @param str {String} Final regex with {{id}} for replacements
 * @param replacements {Object} Object with the replacements
 * @param flags {String} Just like the flags argument in the RegExp constructor
 */
RegExp.create = function(str, replacements, flags) {
	for(var id in replacements) {
		var replacement = replacements[id],
			idRegExp = RegExp('{{' + id + '}}', 'gi');

		if(replacement.source) {
			replacement = replacement.source.replace(/^\^|\$$/g, '');
		}

		// Don't add extra parentheses if they already exist
		str = str.replace(RegExp('\\(' + idRegExp.source + '\\)', 'gi'), '(' + replacement + ')');

		str = str.replace(idRegExp, '(?:' + replacement + ')');
	}

	return RegExp(str, flags);
};</pre>
<p>If you don&#8217;t like adding a function to the RegExp object, you can name it however you want. Here&#8217;s how I used it for my linear-gradient() parser:</p>
<pre>self.regex = {};

self.regex.number = /^-?[0-9]*\.?[0-9]+$/;
self.regex.keyword = /^(?:top\s+|bottom\s+)?(?:right|left)|(?:right\s+|left\s+)?(?:top|bottom)$/;

self.regex.direction = RegExp.create('^(?:{{keyword}}|{{number}}deg|0)$', {
	keyword: self.regex.keyword,
	number: self.regex.number
});

self.regex.color = RegExp.create('(?:{{keyword}}|{{func}}|{{hex}})', {
	keyword: /^(?:red|tan|grey|gray|lime|navy|blue|teal|aqua|cyan|gold|peru|pink|plum|snow|[a-z]{5,20})$/,
	func: RegExp.create('^(?:rgb|hsl)a?\\((?:\\s*{{number}}%?\\s*,?\\s*){3,4}\\)$', {
		number: self.regex.number
	}),
	hex: /^#(?:[0-9a-f]{1,2}){3}$/
});

self.regex.percentage = RegExp.create('^(?:{{number}}%|0)$', {
	number: self.regex.number
});

self.regex.length = RegExp.create('{{number}}{{unit}}|0', {
	number: self.regex.number,
	unit: /%|px|mm|cm|in|em|rem|en|ex|ch|vm|vw|vh/
});

self.regex.colorStop = RegExp.create('{{color}}\\s*{{length}}?', {
	color: self.regex.color,
	length: self.regex.length
}, 'g');

self.regex.linearGradient = RegExp.create('^linear-gradient\\(\\s*(?:({{direction}})\\s*,)?\\s*({{colorstop}}\\s*(?:,\\s*{{colorstop}}\\s*)+)\\)$', {
	direction: self.regex.direction,
	colorStop: self.regex.colorStop
}, 'i');</pre>
<p>(self in this case was a local variable, not the window object)</p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/03/create-complex-regexps-more-easily/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Convert standard gradient syntax to -webkit-gradient and others</title>
		<link>http://lea.verou.me/2011/03/convert-standard-gradient-syntax-to-webkit-gradient-and-others/</link>
		<comments>http://lea.verou.me/2011/03/convert-standard-gradient-syntax-to-webkit-gradient-and-others/#comments</comments>
		<pubDate>Sat, 26 Mar 2011 03:51:32 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Original]]></category>
		<category><![CDATA[CSS gradients]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=907</guid>
		<description><![CDATA[I hate -webkit-gradient() with a passion. Its syntax is cumbersome and it&#8217;s really limited: No angle support, no &#60;length&#62;s in color stop positions, no implied color stop positions, no elliptical gradients&#8230; So, I was really happy, when Webkit implemented the standard syntax this January. However, we&#8217;re still stuck with the horrid -webkit-gradient() for quite a [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F03%252Fconvert-standard-gradient-syntax-to-webkit-gradient-and-others%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FffjvKb%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Convert%20standard%20gradient%20syntax%20to%20-webkit-gradient%20and%20others%22%20%7D);"></div>
<p><img src="http://lea.verou.me/wp-content/uploads/2011/03/cssgradientsplease-screenshot-300x148.png" alt="Screenshot of the demo" title="cssgradientsplease - screenshot" width="300" height="148" class="alignleft size-medium wp-image-909" />I hate <code>-webkit-gradient()</code> with a passion. Its syntax is cumbersome and it&#8217;s really limited: No angle support, no &lt;length&gt;s in color stop positions, no implied color stop positions, no elliptical gradients&#8230; So, I was really happy, when Webkit implemented the standard syntax this January. However, we&#8217;re still stuck with the horrid <code>-webkit-gradient()</code> for quite a while, since older Webkit browsers that don&#8217;t support it are widely used at this time.</p>
<p>Today, I decided to finally spare myself the hassle of converting my standard gradient syntax to -webkit-gradient() by hand. Tasks like that shouldn&#8217;t be handled by a human. So, I coded a little script to do the chore. Hope it helps you too:<br />
<a class="view-demo" href="http://lea.verou.me/demos/cssgradientsplease/">View demo</a></p>
<p>It currently only supports linear gradients, but I plan to add radial ones in the future. Also, when I get around to cleaning up the code a bit, I&#8217;ll add it on Github.</p>
<p>(Hope I didn&#8217;t leave in any very stupid bug, it&#8217;s really late here and I&#8217;m half asleep.)</p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/03/convert-standard-gradient-syntax-to-webkit-gradient-and-others/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Beveled corners &amp; negative border-radius with CSS3 gradients</title>
		<link>http://lea.verou.me/2011/03/beveled-corners-negative-border-radius-with-css3-gradients/</link>
		<comments>http://lea.verou.me/2011/03/beveled-corners-negative-border-radius-with-css3-gradients/#comments</comments>
		<pubDate>Mon, 14 Mar 2011 15:53:56 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Original]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[css3 gradients]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=892</guid>
		<description><![CDATA[Just found out how to do beveled corners and simulate negative border radius without images, by utilizing CSS3 gradients once again. It&#8217;s amazing how many CSS problems can be solved with gradients alone. Read the text in the fiddle to find out how (or just check the code): It also falls back to a solid [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F03%252Fbeveled-corners-negative-border-radius-with-css3-gradients%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FhYU0F8%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Beveled%20corners%20%26%20negative%20border-radius%20with%20CSS3%20gradients%22%20%7D);"></div>
<p>Just found out how to do beveled corners and simulate negative border radius without images, by utilizing CSS3 gradients once again. It&#8217;s amazing how many CSS problems can be solved with gradients alone. Read the text in the fiddle to find out how (or just check the code):</p>
<p><iframe style="width: 100%; height: 525px" src="http://jsfiddle.net/leaverou/EjE7c/embedded/result,css,html"></iframe></p>
<p>It also falls back to a solid color background if CSS gradients are not supported. It will work on Firefox 3.6, latest Webkit and —hopefully— Opera 11.10 (they <a href="http://www.opera.com/press/releases/2011/03/11/" target="_blank">announced that gradients support is coming</a>). You could add a <code>-webkit-gradient()</code> background too, to make it work in practically all versions of Webkit currently in use, but I warn you: It&#8217;s not going to be easy and I personally refuse to spend more than 5 minutes of my time messing with that non-standard sh*t.</p>
<p>PS: For my twitter friends, I had already written this when the robbers came and I was about to post it. I might have been really calm, but not as much as making CSS experiments the same day I was robbed and threatened by a gun <img src='http://lea.verou.me/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/03/beveled-corners-negative-border-radius-with-css3-gradients/feed/</wfw:commentRss>
		<slash:comments>34</slash:comments>
		</item>
		<item>
		<title>Custom &lt;select&gt; drop downs with CSS3</title>
		<link>http://lea.verou.me/2011/03/custom-select-drop-downs-with-css3/</link>
		<comments>http://lea.verou.me/2011/03/custom-select-drop-downs-with-css3/#comments</comments>
		<pubDate>Fri, 04 Mar 2011 19:26:20 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Original]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[CSS3 properties]]></category>
		<category><![CDATA[Opera bugs]]></category>
		<category><![CDATA[pointer-events]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=856</guid>
		<description><![CDATA[The CSS3 Basic UI module defines pointer-events as: The pointer-events property allows authors to control whether or when an element may be the target of user pointing device (pointer, e.g. mouse) events. This property is used to specify under which circumstance (if any) a pointer event should go &#8220;through&#8221; an element and target whatever is [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F03%252Fcustom-select-drop-downs-with-css3%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FhbYWRJ%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Custom%20%26lt%3Bselect%26gt%3B%20drop%20downs%20with%20CSS3%22%20%7D);"></div>
<p>The CSS3 Basic UI module defines <a href="http://dev.w3.org/csswg/css3-ui/#pointer-events"><code>pointer-events</code></a> as:</p>
<blockquote><p>The <code>pointer-events</code> property allows authors to control whether or when an element may be the target of user pointing device (pointer, e.g. mouse) events. This property is used to specify under which circumstance (if any) a pointer event should go &#8220;through&#8221; an element and target whatever is &#8220;underneath&#8221; that element instead. This also applies to other &#8220;hit testing&#8221; behaviors such as dynamic pseudo-classes (:hover, :active, :focus), hyperlinks, and Document.elementFromPoint().</p></blockquote>
<p>The property was originally SVG-only, but eventually browsers and the W3C adopted a more limited version for HTML elements too.</p>
<p>It can be used in many use cases that weren&#8217;t possible before (or the solution was overly complicated), one of them being to create custom-looking &lt;select&gt; drop downs, by overlaying an element over the native drop down arrow (to create the custom one) and disallowing pointer events on it. Here&#8217;s a quick example:</p>
<p><iframe style="width: 100%; height: 200px" src="http://jsfiddle.net/leaverou/XxkSC/embedded/result,css"></iframe></p>
<p><code>-webkit-appearance: none</code> was needed in Webkit to turn off the native OSX appearance (in OSX and maybe Safari on Windows, I didn&#8217;t test that). However, since that also removes the native drop down arrow, our custom arrow now obscures part of the text, so we had to add a 30px padding-right to the select element, only in Webkit.<br />
<span id="more-856"></span><br />
You can easily detect if <code>pointer-events</code> is supported via JS and only apply this it if it is (eg by adding or removing a class from the body element):</p>
<pre>if(!('pointerEvents' in document.body.style)) {
    ...
}</pre>
<p>However, there is one caveat in this: Opera does include pointerEvents in HTML elements as well, but it does not actually support the property on HTML. There&#8217;s a more elaborate feature detection script <a href="https://github.com/ausi/Feature-detection-technique-for-pointer-events/blob/master/modernizr-pointerevents.js">here</a> as a Modernizr plugin (but the code is quite short, so you can adapt it to your needs).</p>
<p>Also, don&#8217;t try to replicate the behavior in JavaScript for browsers that don&#8217;t support this: it&#8217;s impossible to open a &lt;select&gt; drop down with JavaScript. Or, to put it differently, if you manage to do it, you&#8217;ll probably be the first to. Everything I could think of failed and I spent hours yesterday searching for a way, but no avail.</p>
<h3>References</h3>
<ul>
<li><a href="http://dev.w3.org/csswg/css3-ui/#pointer-events">W3C specification</a></li>
<li><a href="https://developer.mozilla.org/en/CSS/pointer-events">MDN article</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/03/custom-select-drop-downs-with-css3/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
		<item>
		<title>Checkerboard pattern with CSS3</title>
		<link>http://lea.verou.me/2011/02/checkerboard-pattern-with-css3/</link>
		<comments>http://lea.verou.me/2011/02/checkerboard-pattern-with-css3/#comments</comments>
		<pubDate>Wed, 16 Feb 2011 17:19:12 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Original]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[css3 gradients]]></category>
		<category><![CDATA[CSS3 values]]></category>
		<category><![CDATA[multiple backgrounds]]></category>
		<category><![CDATA[patterns]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=850</guid>
		<description><![CDATA[A while ago, I wrote a post on creating simple patterns with CSS3 gradients. A common pattern I was unable to create was that of a regular, non-rotated checkerboard. However, I noticed today that by giving a different background-position to every triangle in the pattern tile, a checkerboard can be easily created: View in Gecko [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F02%252Fcheckerboard-pattern-with-css3%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FgaHHGq%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Checkerboard%20pattern%20with%20CSS3%22%20%7D);"></div>
<p>A while ago, I wrote a post on <a href="http://lea.verou.me/2010/12/checkered-stripes-other-background-patterns-with-css3-gradients/">creating simple patterns with CSS3 gradients</a>. A common pattern I was unable to create was that of a regular, non-rotated checkerboard. However, I noticed today that by giving a different background-position to every triangle in the pattern tile, a checkerboard can be easily created:</p>
<p><iframe style="width: 100%; height: 300px" src="http://jsfiddle.net/leaverou/SUgfD/embedded/result,css"></iframe></p>
<p>View in Gecko or Webkit.<br />
Webkit seems to have an odd rendering bug, so it needed a background-size override and it still doesn&#8217;t look perfect. Oh well, <a href="https://bugs.webkit.org/show_bug.cgi?id=54805">reported the bug</a> and moved on.</p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/02/checkerboard-pattern-with-css3/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Incrementable length values in text fields</title>
		<link>http://lea.verou.me/2011/02/incrementable-length-values-in-text-fields/</link>
		<comments>http://lea.verou.me/2011/02/incrementable-length-values-in-text-fields/#comments</comments>
		<pubDate>Mon, 14 Feb 2011 16:58:48 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Apps & scripts]]></category>
		<category><![CDATA[Original]]></category>
		<category><![CDATA[Incrementable]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=839</guid>
		<description><![CDATA[I always loved that Firebug and Dragonfly feature that allows you to increment or decrement a &#60;length&#62; value by pressing the up and down keyboard arrows when the caret is over it. I wished my Front Trends slides supported it in the editable examples, it would make presenting so much easier. So, I decided to [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F02%252Fincrementable-length-values-in-text-fields%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FhQkwUS%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Incrementable%20length%20values%20in%20text%20fields%22%20%7D);"></div>
<p><a href="http://lea.verou.me/wp-content/uploads/2011/02/incrementable-demo.png"><img src="http://lea.verou.me/wp-content/uploads/2011/02/incrementable-demo-300x202.png" alt="" title="incrementable-demo" width="300" height="202" class="alignleft size-medium wp-image-846" /></a>I always loved that Firebug and Dragonfly feature that allows you to increment or decrement a &lt;length&gt; value by pressing the up and down keyboard arrows when the caret is over it. I wished my <a href="http://lea.verou.me/2010/10/my-ft2010-slides-and-csss-my-presentation-framework/">Front Trends slides</a> supported it in the editable examples, it would make presenting so much easier. So, I decided to implement the functionality, to use it in my next talk.</p>
<p>If you still have no idea what I&#8217;m talking about, you can see a demo here:<br />
<a class="view-demo" href="http://lea.verou.me/demos/incrementable/">View demo</a></p>
<p>You may configure it so that it only does that when modifiers (alt, ctrl and/or shift) are used by providing a second argument to the constructor and/or change the units supported by filling in the third argument. However, bear in mind that holding down the Shift key will make it increment by ±10 instead of ±1 and that&#8217;s not configurable (it would add too much unneeded complexity, I&#8217;m not even sure whether it&#8217;s a good idea to make the other thing configurable either).</p>
<p>You may download it or fork it from it&#8217;s <a href="https://github.com/LeaVerou/Incrementable/">Github repo</a>.</p>
<p><del datetime="2011-02-14T23:15:49+00:00">And if you feel creative, you may improve it by fixing an Opera bug I gave up on: When the down arrow is pressed, the caret moves to the end of the string, despite the code telling it not to.</del></p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/02/incrementable-length-values-in-text-fields/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Convert PHP serialized data to Unicode</title>
		<link>http://lea.verou.me/2011/02/convert-php-serialized-data-to-unicode/</link>
		<comments>http://lea.verou.me/2011/02/convert-php-serialized-data-to-unicode/#comments</comments>
		<pubDate>Sun, 13 Feb 2011 23:29:15 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Original]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[latin1]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[serialized]]></category>
		<category><![CDATA[Unicode]]></category>
		<category><![CDATA[utf8]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=835</guid>
		<description><![CDATA[I recently had to convert a database of a large greek website from single-byte greek to Unicode (UTF-8). One of the problems I faced was the stored PHP serialized data: As PHP stores the length of the data (in bytes) inside the serialized string, the stored serialized strings could not be unserialized after the conversion. [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2011%252F02%252Fconvert-php-serialized-data-to-unicode%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FdTf69m%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Convert%20PHP%20serialized%20data%20to%20Unicode%22%20%7D);"></div>
<p>I recently had to convert a database of a large greek website from single-byte greek to Unicode (UTF-8). One of the problems I faced was the stored PHP serialized data: As PHP stores the length of the data (in bytes) inside the serialized string, the stored serialized strings could not be unserialized after the conversion.</p>
<p>I didn&#8217;t want anyone to go through the frustration I went through while searching for a solution, so here is a little function I wrote to recount the string lengths, since I couldn&#8217;t find anything on this:</p>
<pre>function recount_serialized_bytes($text) {
	mb_internal_encoding("UTF-8");
	mb_regex_encoding("UTF-8");

	mb_ereg_search_init($text, 's:[0-9]+:"');

	$offset = 0;

	while(preg_match('/s:([0-9]+):"/u', $text, $matches, PREG_OFFSET_CAPTURE, $offset) ||
		  preg_match('/s:([0-9]+):"/u', $text, $matches, PREG_OFFSET_CAPTURE, ++$offset)) {
		$number = $matches[1][0];
		$pos = $matches[1][1];

		$digits = strlen("$number");
		$pos_chars = mb_strlen(substr($text, 0, $pos)) + 2 + $digits;

		$str = mb_substr($text, $pos_chars, $number);

		$new_number = strlen($str);
		$new_digits = strlen($new_number);

		if($number != $new_number) {
			// Change stored number
			$text = substr_replace($text, $new_number, $pos, $digits);
			$pos += $new_digits - $digits;
		}

		$offset = $pos + 2 + $new_number;
	}

	return $text;
}</pre>
<p>My initial approach was to do it with regular expressions, but the PHP serialized data format is not a regular language and cannot be properly parsed with regular expressions. All approaches fail on edge cases, and I had lots of edge cases in my data (I even had nested serialized strings!).</p>
<p>Note that this will only work when converting <strong>from single-byte encoded data</strong>, since it assumes the stored lengths are the string lengths in characters. Admittedly, it&#8217;s not my best code, it could be optimized in many ways. It was something I had to write quickly and was only going to be used by me in a one-time conversion process. However, it works smoothly and has been tested with lots of different serialized data. I know that not many people will find it useful, but it&#8217;s going to be a lifesaver for the few ones that need it.</p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2011/02/convert-php-serialized-data-to-unicode/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Checkerboard, striped &amp; other background patterns with CSS3 gradients</title>
		<link>http://lea.verou.me/2010/12/checkered-stripes-other-background-patterns-with-css3-gradients/</link>
		<comments>http://lea.verou.me/2010/12/checkered-stripes-other-background-patterns-with-css3-gradients/#comments</comments>
		<pubDate>Wed, 22 Dec 2010 22:23:03 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Original]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[background-size]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[css3 gradients]]></category>
		<category><![CDATA[CSS3 values]]></category>
		<category><![CDATA[multiple backgrounds]]></category>
		<category><![CDATA[patterns]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=775</guid>
		<description><![CDATA[You&#8217;re probably familiar with CSS3 gradients by now, including the closer to the standard Mozilla syntax and the ugly verbose Webkit one. I assume you know how to add multiple color stops, make your gradients angled or create radial gradients. What you might not be aware of, is that CSS3 gradients can be used to [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2010%252F12%252Fcheckered-stripes-other-background-patterns-with-css3-gradients%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FgI2SdY%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Checkerboard%2C%20striped%20%26%20other%20background%20patterns%20with%20CSS3%20gradients%22%20%7D);"></div>
<p><a href="http://lea.verou.me/demos/css3-patterns.html"><img class="size-large alignleft" title="The CSS3 patterns I came up with" src="http://lea.verou.me/wp-content/uploads/2010/12/css3-patterns-1024x480.png" alt="Screenshot of the CSS3 patterns I came up with" width="300" /></a>You&#8217;re probably familiar with CSS3 gradients by now, including the closer to the standard Mozilla syntax and the ugly verbose Webkit one. I assume you know how to add multiple color stops, make your gradients angled or create radial gradients. What you might not be aware of, is that CSS3 gradients can be used to create many kinds of commonly needed patterns, including checkered patterns, stripes and more.</p>
<p><a class="view-demo" href="http://lea.verou.me/demos/css3-patterns.html">View demo</a> (Works in Webkit, Firefox 3.6+, Opera 11.50+ and IE10+)</p>
<p>The main idea behind the technique is the following, taken from the <a href="http://dev.w3.org/csswg/css3-images/#color-stop-syntax" target="_blank">CSS3 Images spec</a>:</p>
<blockquote><p>If multiple color-stops have the same position, they produce an infinitesimal transition from the one specified first in the rule to the one specified last. <strong>In effect, the color suddenly changes at that position rather than smoothly transitioning.</strong></p></blockquote>
<p>I guess this makes it obvious how to create the tile for the stripes (unless you&#8217;ve never created a striped background before, but teaching you this is beyond the scope of this post). For example the gradient for the horizontal stripes is:</p>
<pre>background-color: #0ae;
background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(.5, rgba(255, 255, 255, .2)), color-stop(.5, transparent), to(transparent));
background-image: -moz-linear-gradient(rgba(255, 255, 255, .2) 50%, transparent 50%, transparent);
background-image: -o-linear-gradient(rgba(255, 255, 255, .2) 50%, transparent 50%, transparent);
background-image: linear-gradient(rgba(255, 255, 255, .2) 50%, transparent 50%, transparent);</pre>
<p>Why <code>transparent</code> instead of the actual colors we want? For flexibility. <code>background-color</code> serves two purposes here: Setting the color of half the stripes and serving as a fallback for browsers that don&#8217;t support gradients.</p>
<p>However, without anything else, the tile will occupy the whole container. To control the size of each tile, you can use background-size:</p>
<pre>-webkit-background-size: 50px 50px;
-moz-background-size: 50px 50px;
background-size: 50px 50px;</pre>
<p>To create the picnic-style pattern, you just overlay horizontal stripes on vertical stripes.</p>
<p>The hardest one to figure out was the checkered pattern. It consists of two 45° linear gradients and two -45° linear gradients, each containing ¼ of the dark squares. I still haven&#8217;t managed to think of a way to create a regular checkerboard (not at 45°) without needing an unacceptably large number of gradients. It will be very easily possible if conical gradients start being supported (currently they&#8217;re not even in the spec yet).</p>
<p>Can you think of any other popular patterns that can be created with CSS3 and no images? If so, let me know with a comment. Cheers! <img src='http://lea.verou.me/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Added afterwards: Other patterns</h3>
<p>There are far more pattern designs possible with CSS3 gradients than I originally thought. For more details, see <a href="http://lea.verou.me/2011/04/css3-patterns-gallery-and-a-new-pattern/">this later post</a>.</p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2010/12/checkered-stripes-other-background-patterns-with-css3-gradients/feed/</wfw:commentRss>
		<slash:comments>138</slash:comments>
		</item>
		<item>
		<title>rgba.php v1.2: Improved URL syntax, now at Github</title>
		<link>http://lea.verou.me/2010/12/rgba-php-v1-2-improved-url-syntax-now-at-github/</link>
		<comments>http://lea.verou.me/2010/12/rgba-php-v1-2-improved-url-syntax-now-at-github/#comments</comments>
		<pubDate>Wed, 08 Dec 2010 03:05:31 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Original]]></category>
		<category><![CDATA[colors]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[CSS3 values]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[RGBA]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=763</guid>
		<description><![CDATA[I wrote the first version of rgba.php as a complement to an article on RGBA that I posted on Februrary 2009. Many people seemed to like the idea and started using it. With their valuable input, I made many changes and released v.1.1 (1.1.1 shortly after I posted the article due to another little fix) [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2010%252F12%252Frgba-php-v1-2-improved-url-syntax-now-at-github%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FuRFbVR%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22rgba.php%20v1.2%3A%20Improved%20URL%20syntax%2C%20now%20at%20Github%22%20%7D);"></div>
<p><a href="http://lea.verou.me/wp-content/uploads/2010/12/Screen-shot-2011-11-15-at-15.19.14-.png"><img src="http://lea.verou.me/wp-content/uploads/2010/12/Screen-shot-2011-11-15-at-15.19.14--300x187.png" alt="" title="rgba.php project page screenshot" width="300" height="187" class="alignleft size-medium wp-image-1449" /></a>I wrote the first version of rgba.php as a complement to <a href="http://lea.verou.me/2009/02/bulletproof-cross-browser-rgba-backgrounds/">an article on RGBA that I posted on Februrary 2009</a>.<br />
Many people seemed to like the idea and started using it. With their valuable input, I made many changes and <a href="http://lea.verou.me/2009/10/new-version-of-rgba-php-is-out/">released v.1.1</a> (1.1.1 shortly after I posted the article due to another little fix) on October 2009.<br />
More than a year after, quite a lot of people still ask me about it and use it, so I decided to make <a href="https://github.com/LeaVerou/rgba.php" target="_blank">a github repo for it </a>and release a new version, with a much easier to use syntax for the URL, which lets you just copy and paste the color instead of rewriting it:</p>
<pre>background: url('rgba.php/rgba(255, 255, 255, 0.3)');
background: rgba(255, 255, 255, 0.3);</pre>
<p>instead of:</p>
<pre>background: url('rgba.php?r=255&amp;g=255&amp;b=255&amp;a=30');
background: rgba(255, 255, 255, 0.3);</pre>
<p>I also made <a href="http://lea.verou.me/rgba.php/">a quick about/demo page for it</a>.<br />
Enjoy <img src='http://lea.verou.me/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2010/12/rgba-php-v1-2-improved-url-syntax-now-at-github/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>My FT2010 slides and CSSS: My presentation framework</title>
		<link>http://lea.verou.me/2010/10/my-ft2010-slides-and-csss-my-presentation-framework/</link>
		<comments>http://lea.verou.me/2010/10/my-ft2010-slides-and-csss-my-presentation-framework/#comments</comments>
		<pubDate>Fri, 29 Oct 2010 04:02:22 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Apps & scripts]]></category>
		<category><![CDATA[Original]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[conferences]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[CSSS]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=676</guid>
		<description><![CDATA[About a week ago, I was in Warsaw, Poland to give my first talk at a big conference, Front Trends 2010. As every first-time speaker, I was extremely nervous and worried that everything would go bad. That my talk would be boring or too basic or that I would just freeze at stage, unable to [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2010%252F10%252Fmy-ft2010-slides-and-csss-my-presentation-framework%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FuZoyvB%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22My%20FT2010%20slides%20and%20CSSS%3A%20My%20presentation%20framework%22%20%7D);"></div>
<p><a href="http://lea.verou.me/wp-content/uploads/2010/10/cover-screenshot.png"><img class="alignleft size-full wp-image-689" title="cover-screenshot" src="http://lea.verou.me/wp-content/uploads/2010/10/cover-screenshot.png" alt="Screenshot of the first slide" width="300" height="188" /></a>About a week ago, I was in Warsaw, Poland to give <a href="http://lea.verou.me/2010/08/lea-verou-at-front-trends-2010/">my first talk</a> at a big conference, <a href="http://front-trends.com/">Front Trends 2010</a>. As every first-time speaker, I was extremely nervous and worried that everything would go bad. That my talk would be boring or too basic or that I would just freeze at stage, unable to say a word. It was a 2-hour talk with a break in between, so I was also terrified that nobody would show up the second hour.</p>
<p>Contrary to my fears and insecurities, it went better than I could have ever hoped. The feedback on twitter and in general was enthusiastic! There wasn&#8217;t a single negative comment. Even people I look up to, like <a href="http://twitter.com/#!/t/status/28020396001" target="_blank">Tantek Çelik</a>, <a href="http://twitter.com/ppk/status/28018480426" target="_blank">PPK</a>, <a href="http://twitter.com/jaffathecake/status/28016064374" target="_blank">Jake Archibald</a> or <a href="http://twitter.com/robertnyman/status/28016285089" target="_blank">Robert Nyman</a> had something good to say! And instead of nobody showing up the second hour, the audience almost doubled!</p>
<p>At this point, I would like to thank <a href="http://www.wait-till-i.com/2010/10/25/fronttrends2010-in-warsaw-poland-my-impressions-slides-and-audio/">Christian Heilmann</a> for helping me become less nervous before my talk by going through all my slides with me and offering his invaluable advice for every part (I forgot to follow most of it, but it really helped in my attitude). I can&#8217;t thank you enough Christian!<span id="more-676"></span></p>
<p>Many attendees asked me for my slides and presentation framework. You can find my slides <a href="http://lea.verou.me/ft2010/" target="_blank">online here</a> or <a href="http://lea.verou.me/wp-content/uploads/2010/10/ft2010.zip">download</a> them. However, <strong>before you follow those links, read below</strong>:</p>
<ul>
<li>I originally ran my presentation in <strong>Firefox 4 beta</strong> so I was testing mainly in that and Minefield (Firefox&#8217;s nightly releases). It supports other browsers too (Chrome 7, Opera 10.6+), but it still displays better in Firefox or Minefield and is (surprisingly) faster in them.</li>
<li><strong>Opera</strong> has issues with a few unicode characters I used in some places and won&#8217;t display Helvetica Neue even if it&#8217;s installed (@font-face is not an option with that font, for legal reasons)</li>
<li><strong>Any non-Gecko browser </strong>will not display <strong>CSS gradients</strong>, since Gecko is the only engine so far that supports the standard syntax. Therefore the gradient demos and the multiple backgrounds demo won&#8217;t work in non-Gecko browsers.</li>
<li>Some slides are a bit slow on <strong>Webkit</strong>. <strong>The first slide is extremely slow in it,</strong> you have been warned.</li>
<li><strong>Opera</strong> and <strong>Webkit</strong> have (different) bugs with border-radius: 50%, so some things using it will look funny.</li>
<li>I have <strong>only tested in OSX browsers</strong>. I have no idea how it will perform on Windows or Linux distros yet.</li>
<li>It&#8217;s a 2-hour talk and the presentation was designed to run locally. <strong>It&#8217;s not small and it will take a while to load</strong>. That&#8217;s due to the images used, as you can easily see from the zip archive.</li>
<li>The <strong>editable examples</strong> many of you liked are based on this <a href="http://annevankesteren.nl/2010/03/css-wg-brainstorming">CSS mindfuck by Anne van Kesteren</a>. It&#8217;s smart and convenient, but beware: It breaks really, really easily. It&#8217;s good for <em>changing</em> the code realtime, but it will most likely break if you try to <em>add</em> extra code.</li>
</ul>
<p>In case you&#8217;re not feeling very adventurous today, or you&#8217;re just using a computer with only unsupported browsers, here&#8217;s the presentation as a series of images (not interactive, but still the same info):</p>
<div style="width:598px" id="__ss_5637358"><strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/LeaVerou/css3-a-practical-introduction-ft2010-talk" title="CSS3: A practical introduction (FT2010 talk)">CSS3: A practical introduction (FT2010 talk)</a></strong><object id="__sse5637358" width="598" height="481"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=talk-101101162127-phpapp01&#038;stripped_title=css3-a-practical-introduction-ft2010-talk&#038;userName=LeaVerou" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse5637358" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=talk-101101162127-phpapp01&#038;stripped_title=css3-a-practical-introduction-ft2010-talk&#038;userName=LeaVerou" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="598" height="481"></embed></object></div>
<p><a href="http://lea.verou.me/wp-content/uploads/2010/10/logo-small.png"><img class="alignright size-full wp-image-686" title="CSSS" src="http://lea.verou.me/wp-content/uploads/2010/10/logo-small.png" alt="CSSS logo" width="299" height="156" /></a>By popular demand, I&#8217;m also releasing my presentation framework, for which in the meantime I found a name (<strong>CSSS</strong>, inspired by S5), designed a logo and made a simpler, <a href="http://lea.verou.me/csss/sample-slideshow.html" target="_blank">sample presentation</a> with a different, simpler theme. I released it in <a href="http://github.com/LeaVerou/CSSS">a public repo on Github</a> (finally got around to learning the basics of Github and loved it!). Please note that this is a very first version and I haven&#8217;t been able to test it much, especially on Windows, since my Mac is quite new and I keep postponing to install some virtualization software. A friend reported that <strong>Firefox 3.6 on Windows has serious issues </strong>with it, although it runs fine on my FF3.6 copy for Mac. It doesn&#8217;t work at all in IE, even IE9, as I don&#8217;t yet have IE to test it out. Please report any issues on Github&#8217;s bug tracker and eventually I &#8211;or someone else, you&#8217;re all welcome :p&#8211; will fix them (don&#8217;t forget to mention exact browser version and OS). If you&#8217;re using Safari, press Ctrl+H for something cool <img src='http://lea.verou.me/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  (it works on the others too, but it&#8217;s slower and not smooth)</p>
<p><a href="http://lea.verou.me/wp-content/uploads/2010/10/csss-logo.jpg"><img src="http://lea.verou.me/wp-content/uploads/2010/10/csss-logo-300x187.jpg" alt="" title="csss-logo" width="300" height="187" class="alignleft size-medium wp-image-1446" /></a>Some may ask: <em>&#8220;If CSS3 degrades so gracefully and we can use it today as you told us in your talk, then why all these issues with different browsers in CSSS or your FT presentation?&#8221;</em>. First of all, these are not everyday use cases. Projects like CSSS or my FT presentation are quite experimental, use a lot of CSS3, including many edge cases and I could have devoted more time to make them degrade more gracefully, but given the target audience, I don&#8217;t think it&#8217;s worth it much. It&#8217;s expected that  there might be rendering problems in some browsers or that they might be slow, browsers need edge cases to highlight problems in their implementations of the new stuff before it&#8217;s finalized. Every time I experiment with CSS3, I find at least one browser bug, which I generally try to report (don&#8217;t let that scare you though, as I said, I have a penchant for edge cases).</p>
<p>You may have also noticed I redesigned my blog. As you may have noticed, I have fallen in love with that <a href="http://lukeroberts.us/2008/12/wallpaper-colourful-wood/" target="_blank">Rainbow Wood wallpaper by Luke Roberts</a> and I just <strong><em>had</em></strong> to put it in my blog too <img src='http://lea.verou.me/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  The new design has a few issues with Opera at the moment, but I hope to fix them soon. It will also look better to those that have Helvetica Neue installed.</p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2010/10/my-ft2010-slides-and-csss-my-presentation-framework/feed/</wfw:commentRss>
		<slash:comments>38</slash:comments>
		</item>
		<item>
		<title>Organizing a university course on modern Web development</title>
		<link>http://lea.verou.me/2010/07/organizing-a-university-course-on-modern-web-development/</link>
		<comments>http://lea.verou.me/2010/07/organizing-a-university-course-on-modern-web-development/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 12:03:27 +0000</pubDate>
		<dc:creator>Lea Verou</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Original]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[education]]></category>
		<category><![CDATA[ES5]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[SVG]]></category>
		<category><![CDATA[teaching]]></category>
		<category><![CDATA[XPath]]></category>
		<category><![CDATA[XSLT]]></category>

		<guid isPermaLink="false">http://leaverou.me/?p=576</guid>
		<description><![CDATA[About a year ago, prof. Vasilis Vassalos of Athens University of Economics and Business approached me and asked for my help in a new course they were preparing for their Computer Science department, which would introduce 4th year undergrads to various web development aspects. Since I was always complaining about how outdated higher education is when [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_hot-pink" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Flea.verou.me%252F2010%252F07%252Forganizing-a-university-course-on-modern-web-development%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2F9j5Bz7%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Organizing%20a%20university%20course%20on%20modern%20Web%20development%22%20%7D);"></div>
<p>About a year ago, prof. <a href="http://twitter.com/vassalos" target="_blank">Vasilis Vassalos</a> of <a title="The university official website (yeah, I know...)" href="http://aueb.gr" target="_blank">Athens University of Economics and Business</a> approached me and asked for my help in a new course they were preparing for their <a href="http://www.cs.aueb.gr" target="_blank">Computer Science department</a>, which would introduce 4th year undergrads to various web development aspects. Since I was always complaining about how outdated higher education is when it comes to web development, I saw it as my chance to help things change for the better, so I agreed without a second thought.</p>
<p>This is one of the main reasons I didn&#8217;t have time to write many blog posts for the past months: This activity took up all my spare time. However, it proved to be an interesting and enlightening experience, in more than one ways. In this blog post I&#8217;ll describe the dilemmas we faced, the decisions we made and the insights I gained throughout these 6 months, with the hope that they&#8217;ll prove to be useful for anyone involved in something similar.</p>
<h3>Table of contents</h3>
<ol>
<li><a href="#course-content">Content</a></li>
<li><a href="#homework">Homework</a></li>
<li><a href="#labs">Labs</a></li>
<li><a href="#aftermath">Personal aftermath</a></li>
</ol>
<p><span id="more-576"></span></p>
<h3 id="course-content">Content</h3>
<p>The goals of a university course differ from the ones of a professional seminar or conference session in many ways, the key one being that most of its students will (professionally) utilize the things they learned in the future and not right after they walk away from class. So, the stuff being taught must be useful even after a couple years have passed. Also, issues of the present might not be issues of the future and what isn&#8217;t possible today (due to browser support issues) will probably be tomorrow.  These observations led us to decide <strong>against teaching proprietary stuff. Instead, we only included  things which come with a specification that has reached a fairly stable state</strong> (with the exception of <strong>very </strong>widespread non-standard stuff, such as <code>innerHTML</code>). We also decided <strong>not to address workarounds and browser incompatibilities at all</strong>, since these would probably be out of date in a few years. Also because, if we teach everything else right, they should be able to learn these by themselves, if needed (we did teach feature detection techniques though, those are timeless <img src='http://lea.verou.me/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> ). We also included <strong>many cutting edge topics (CSS3, HTML5, ES5, SVG&#8230;) since we believe that they will be necessary tools of the trade tomorrow</strong>. To be pragmatic however, <strong>we did not teach stuff that no browser has implemented yet</strong>, besides perhaps a brief mention.</p>
<p>To make things easier for the students, we used <strong>Firefox 3.6</strong> for everything. We tested their assignments there, we used it to present something in the labs etc. Why Firefox?</p>
<ul>
<li>It&#8217;s at a quite good level of standards compliance and implements many modern technologies &amp; features</li>
<li>Fewer bugs (Webkit implements stuff faster, but in more buggy ways)</li>
<li>It has the best development tools (Firebug)</li>
<li>With Brendan Eich being Mozilla&#8217;s CTO, we all know how progressive Firefox is when it comes to JavaScript.</li>
</ul>
<p>Of course, this doesn&#8217;t mean it&#8217;s the only right choice. Google Chrome for example would be another good pick.</p>
<p>Another useful observation was that 4th year Computer Science students already know programming quite well, especially Java. So, <strong>we did not need to go through the basics of programming syntax</strong> like introductory books or seminars frequently do. Consequently, <strong>we skipped explaining how control structures or operators work</strong> in JavaScript or PHP and just <strong>focused on their differences</strong> from Java and other languages.</p>
<p>Another dilemma we faced was whether we should teach stuff on popular frameworks and whether we should allow them in the homeworks. We decided <strong>against allowing them in the homeworks</strong> because I believe that someone must not use a framework just to skip learning about the intricacies of a language. They should be used after the basics have been consolidated, in order to save time. Also because if everyone skips learning and just uses an abstraction to do the heavy lifting from the very beginning, who will write the abstractions after all? Another reason was that a large portion of every JavaScript framework is about handling cross-browser differences. However, these had no place in our course, so a JS framework wasn&#8217;t as necessary as it is in day to day web development. Regarding teaching them, <strong>we thought it would be a good idea to introduce students to the popular JS &amp; PHP frameworks in the last lectures</strong>, but there was no time left. Maybe next year.</p>
<p>To sum up, the course content ended up being (I&#8217;m listing client-side matters more extensively, since they are also the focus of this blog):</p>
<ul>
<li>General stuff about web application architecture and how the HTTP protocol works</li>
<li>We presented a small web application example (an AJAX shopping cart) in order for the students to get an idea about how everything clicks together</li>
<li>Markup languages
<ul>
<li>SGML</li>
<li>DTDs</li>
<li>HTML and XHTML
<ul>
<li>Basic structure of an (X)HTML document</li>
<li>Content model, block vs inline elements</li>
<li>Basic HTML elements
<ul>
<li>headings &amp; paragraphs</li>
<li>lists (ordered, unordered, definition lists)</li>
<li>tables</li>
<li>grouping elements (div &amp; span)</li>
</ul>
</li>
<li>Doctypes, the HTML5 doctype</li>
<li>The incentives behind XHTML &amp; the future ((X)HTML 5)</li>
<li>(X)HTML Validation</li>
<li>HTML forms
<ul>
<li>How forms work, GET vs POST</li>
<li>Form controls, shared attributes</li>
<li>The various input types (+ the new ones HTML5 brings)</li>
<li>Other form controls (buttons, &lt;select&gt; lists, textareas)</li>
<li>Basic form accessibility (labels &amp; fieldsets)</li>
</ul>
</li>
<li>Working with Multimedia (old methods, HTML5 video &amp; audio elements, comparison)</li>
</ul>
</li>
<li>XML and XPath, XQuery, XSLT</li>
</ul>
</li>
<li>CSS
<ul>
<li>CSS standards</li>
<li>CSS rules</li>
<li>Validation</li>
<li>Adding CSS to a page (linking/embedding methods)</li>
<li>Media targeting (The media attribute, @media rules, media queries)</li>
<li>CSS selectors
<ul>
<li>Introduction to the DOM</li>
<li>Basic selectors (Universal selector, Type selector, Class selector, Id selector)</li>
<li>Classes vs Ids</li>
<li>Attribute selectors (all 6)</li>
<li>Pseudo-classes (including most of the CSS3 ones)</li>
<li>Pseudo-elements</li>
<li>Simple selectors &amp; simple selector sequences</li>
<li>Combinators (all 4)</li>
<li>Selector grouping</li>
<li>XML namespaces &amp; CSS</li>
</ul>
</li>
<li>Cascading &amp; Inheritance
<ul>
<li>The problem: Conflicts</li>
<li>Specificity</li>
<li>Origin</li>
<li>!important</li>
<li>Inheritance</li>
<li>The special value <em>inherit</em></li>
</ul>
</li>
<li>Properties &amp; values
<ul>
<li>Keywords</li>
<li>Numerical values &amp; units</li>
<li>Colors (including CSS3 colors)</li>
<li>How shorthands work</li>
<li>Unsupported values &amp; providing fallbacks</li>
</ul>
</li>
<li>Box model
<ul>
<li>width &amp; height</li>
<li>Block level &amp; inline level elements (reminder from the HTML lectures)</li>
<li>The <em>display </em>property</li>
<li>border</li>
<li>padding</li>
<li>margin</li>
</ul>
</li>
<li>Positioning
<ul>
<li>The <em>position </em>property</li>
<li>Positioning types (absolute, relative, fixed)</li>
<li>z-index</li>
<li>float</li>
<li>Problems with floats, the <em>clear </em>property</li>
</ul>
</li>
<li>Generated content
<ul>
<li>::before and ::after</li>
<li>Static generated content</li>
<li>Dynamic generated content (attributes &amp; counters)</li>
</ul>
</li>
</ul>
</li>
<li>JavaScript
<ul>
<li>Adding JS to a document</li>
<li>Separation of concerns</li>
<li>A first, annotated, example (a simple script that generates tables of content from &lt;h2&gt; headings)</li>
<li>Basic syntax rules (including semicolons &amp; semicolon insertion)</li>
<li>Variables</li>
<li>Operators (including typeof, the comma operator, strict operators, differences of &amp;&amp;/|| in JS)</li>
<li>Primitives (String, Number, Boolean, null, undefined)</li>
<li>Conversion across primitives</li>
<li>Objects</li>
<li>The <em>in</em> &amp; <em>delete</em> operators</li>
<li>for&#8230;in loops</li>
<li>Native objects for primitives (eg the literal 5 vs new Number(5))</li>
<li>The global object</li>
<li>Functions (including function expressions vs function declarations)</li>
<li><em>this</em> &amp; changing execution context</li>
<li>Arrays (including .forEach() traversal)</li>
<li>Regular expressions in JavaScript</li>
<li>OOP in JavaScript
<ul>
<li>OOP concepts in JS</li>
<li>Constructors</li>
<li>Inheritance</li>
<li>Encapsulation (private, priviledged &amp; public properties)</li>
<li>Method overloading</li>
<li>JavaScript shortcomings when it comes to OOP</li>
<li>for&#8230;in loops, inherited properties &amp; [[Enumerable]], .hasOwnProperty()</li>
<li>Type detection based on [[Class]] detection (using Object.prototype.toString())</li>
</ul>
</li>
<li>DOM
<ul>
<li>Traversal</li>
<li>Node types</li>
<li>Selecting elements (getElementById, getElementsByClassName, getElementsByName, querySelector, using XPath to select elements)</li>
<li>DOM Manipulation</li>
<li>innerHTML, advantages &amp; criticism</li>
</ul>
</li>
<li>Events
<ul>
<li>Binding &amp; Removing event handlers</li>
<li>Traditional event binding</li>
<li>Capturing &amp; bubbling</li>
<li>Event objects</li>
<li>Event delegation</li>
<li>Firing events</li>
<li>Custom events</li>
<li>What if there&#8217;s no mouse?</li>
</ul>
</li>
<li>Client side storage
<ul>
<li>Cookies via HTTP headers, cookies in JavaScript</li>
<li>Problems with cookies</li>
<li>Web storage (localStorage, sessionStorage)</li>
<li>Client-side databases</li>
</ul>
</li>
<li>BOM
<ul>
<li>The window object, window names</li>
<li>Opening new windows</li>
<li>Cross-window communication</li>
<li>Closing windows, Focusing on windows</li>
<li>Cross-origin window communication</li>
<li><em>location</em> &amp; it&#8217;s components</li>
<li>The <em>history</em>, <em>screen</em> &amp; <em>navigator</em> objects</li>
<li>User Agent strings</li>
<li>Why you shouldn&#8217;t use browser detection</li>
<li>Built-in modal windows (alert, confirm, prompt)</li>
</ul>
</li>
<li>JavaScript &amp; CSS
<ul>
<li>CSS modification (className &amp; classList, inline styles)</li>
<li><em>CSSStyleDeclaration</em> objects</li>
<li>The document.styleSheets collection</li>
<li>Switching stylesheets</li>
<li><em>StyleSheet</em> objects</li>
<li><em>CSSStyleRule</em> objects</li>
<li>Computed style, getting the computed style</li>
</ul>
</li>
<li>Asynchronous execution
<ul>
<li>Timeouts &amp; Intervals</li>
<li>Background workers</li>
</ul>
</li>
<li>Graphics creation (canvas)</li>
<li>A brief mention of WebGL (we also showed the video of Google&#8217;s web based DOOM game)</li>
<li>Best practices
<ul>
<li>When JS is disabled</li>
<li>Feature detection</li>
</ul>
</li>
</ul>
</li>
<li>Regular expressions</li>
<li>Ajax (including data interchange formats, like JSON, other async data transmission techniques, including dynamic script loading &amp; JSONP, usability concerns)</li>
<li>SVG</li>
<li>Server side web development
<ul>
<li>PHP (also covering OOP in PHP extensively)</li>
<li>Database driven websites</li>
<li>State &amp; session management</li>
<li>REST</li>
<li>SOAP</li>
</ul>
</li>
<li>Web application security</li>
</ul>
<p><strong><em>Note:</em></strong><em> For brevity reasons, the lists above do not include introductory stuff such as:</em></p>
<ul>
<li><em>What&#8217;s X?</em></li>
<li><em>A brief history of X</em></li>
<li><em>Why use X?</em></li>
<li><em>etc</em></li>
</ul>
<h4>Lessons learned</h4>
<p>It&#8217;s very hard to momentarily change your mindset and try to imagine that you live in a modern, fully standards-based web development world, where old browsers, proprietary stuff, hacks and compatibility workarounds have no place. A world where IE doesn&#8217;t exist. However, it&#8217;s the world that all our material assumed, for the reasons stated above. And it&#8217;s beautiful, so much that it becomes addictive and makes you hate all these bugs &amp; incompatibilities that we have to face today even more.</p>
<h3 id="homework">Homework</h3>
<p>The students were given 3 assignments throughout the semester, each covering:</p>
<ul>
<li>1st assignment: HTML, CSS, XPath, XSLT</li>
<li>2nd assignment: JavaScript, Ajax, SVG</li>
<li>3rd assignment: Server side web dev + CSS, JavaScript, Ajax</li>
</ul>
<p>These homeworks accounted for 30% of their final grade (10% each), which probably should have been more.</p>
<p>We searched for exercises on these topics from other universities but couldn&#8217;t find anything, so we made our own. I&#8217;ve translated them, in case someone finds them useful, given that there&#8217;s a great shortage of such material in the intertubes. You can get them through the links below, along with their complementary files.</p>
<h4>1st assignment [<a href="http://lea.verou.me/wdclass/assignment1_en.pdf" target="_blank">pdf</a>] [<a href="http://lea.verou.me/wdclass/assignment1_en.zip" target="_blank">files</a>]</h4>
<ul>
<li> I think 1.A and 1.B are excellent exercises to make the students fully understand how CSS selectors work and avoid them resulting to only use the 4-5 basic ones just because they don&#8217;t understand the rest (like many web developers do). It&#8217;s a pity that many of them resulted to online scripts for the conversion (but luckily it was easy to spot: These answers were way more verbose than the corresponding &#8220;handmade&#8221; ones, and in some cases even incorrect!)</li>
<li>I also think 1.C is an excellent exercise for cascading &amp; inheritance practice. Some of the cases were even quite tricky (for instance, the way specificity works for :not() or how grouping works if one of the selectors is invalid) and treated almost all factors that someone should know to predict which rule &#8230;overrules. It&#8217;s important however that the student justifies the answer, because otherwise they can just test it in a browser and write down the result, without understanding why.</li>
<li>I&#8217;m not sure yet if freeform questions were a good idea, but (hopefully) they got them to practice their critical thinking and do some research (we hadn&#8217;t presented :checked and :lang() in class). We didn&#8217;t expect many to get the 3rd one right, but we were pleasantly surprised.</li>
<li>What I like in 3.A is that I believe it enforces the Separation of Concerns guideline, since they cannot alter the HTML file (something even professionals commonly do to get something done, the quick &amp; dirty way&#8230;) so they <strong>have</strong> to move all presentation to the CSS file. It also contained a quite tricky part: Maintaining state without JavaScript, by utilizing the <strong>:checked</strong> pseudo-class and some combinators (a technique made popular quite recently by <a href="http://www.thecssninja.com/">Ryan Seddon</a>). Obviously, this is not a good way to change views in a photo gallery (too much wasted bandwidth), but it was perfect as a CSS exercise. To my surprise, more than half of the students got it right, which indicates that we probably did a good job explaining CSS Selectors <img src='http://lea.verou.me/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
<h4>2nd assignment [<a href="http://lea.verou.me/wdclass/assignment2_en.pdf" target="_blank">pdf</a>] [<a href="http://lea.verou.me/wdclass/assignment2_en.zip" target="_blank">files</a>]</h4>
<ul>
<li>I like exercise 1 because it teaches them how they can take somebody else&#8217;s work, extend it and make it more generic and useful. This is something that&#8217;s frequently done in web development. By the way, the deviation in the solutions was quite interesting. Others had implemented a recursive algorithm, others approached it in an Object Oriented manner and others took the classic iterative route.</li>
<li>Exercise 2 lets them practice event delegation, unobtrusive progressive enhancement via JavaScript, decisions to improve performance (and still, it&#8217;s unbelievable how many students made choices that were obviously terrible performance-wise. I still remember one script that created another DOM element <strong>on every mouseover</strong>!)</li>
<li>Exercise 3 combines many of the technologies they learned in the previous lectures. It also lets them practice their critical thinking by comparing the methods afterwards. Most students picked the CSS method, which would also be my choice, for such a simple bar chart (however, anything rational got full points, I don&#8217;t think there&#8217;s a correct answer here, it depends on many factors).</li>
<li>I like exercise 4 because it introduces them to the concept of writing JavaScript that is intended to be used by other developers, and not just in a particular project (along with 2 perhaps). However, none of the students fully understood what it was about. All of them fired the HTTP request when ajaxForm() was called and most of them also implemented callback() and errorCallback(), which wasn&#8217;t supposed to be their job.</li>
<li>Exercise 5, besides serving well as regular JavaScript practice, it also lets them learn more about cutting edge technologies such as <strong>localStorage</strong>, <strong>Web databases</strong> or <strong>offline web apps</strong>.</li>
</ul>
<h4>3rd assignment [<a href="http://lea.verou.me/wdclass/assignment3_en.pdf" target="_blank">pdf</a>] [<a href="http://lea.verou.me/wdclass/assignment3_en.zip" target="_blank">files</a>]</h4>
<p>In this assignment, the students practiced in PHP, combined everything else they&#8217;ve learned and understood better how everything clicks together to bring a fully-fledged web application to life. We didn&#8217;t get many submissions, since most students were busy with other assignments these days but most of the ones we got were awesome, I had an extremely hard time picking the best one.</p>
<h4>Lessons learned</h4>
<ul>
<li>Most mistakes are not very original: They tend to appear over and over again in unrelated assignments. Most of them are caused either by ambiguities in the description or because the student didn&#8217;t bother to read all of it. Also, the most frequent excuse for not doing something right is &#8220;it wasn&#8217;t in the description!&#8221;. So, they have to be as detailed as possible, including even stuff that&#8217;s obvious to someone more experienced.</li>
<li>Plagiarism is not a myth, but a real and frequent problem. Students copy from other students, from scripts posted online and from any source they can get their hands on. <img src='http://lea.verou.me/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  However, only teaching the standards makes it much easier to spot (at least when it comes to copying from the internet) since most scripts posted online have to account for browser incompatibilities.</li>
</ul>
<h3 id="labs">Labs</h3>
<p>We only held 3 hands-on lectures (2 hours each), due to time availability issues of everyone involved in the course. I taught the first 2 and another TA was responsible for the 3rd one. Details below:</p>
<h4>1st lab [<a href="http://lea.verou.me/wdclass/lab1/">final result</a>]</h4>
<p>The students had to write an HTML file for the single page personal website of some fictional web developer and then use CSS to style it in a certain way. The process was guided, in order to keep all of them on the same track. The site was carefully designed to demonstrate many key CSS concepts &amp; features at once.</p>
<h4>2nd lab [<a href="http://lea.verou.me/wdclass/rating-widget/" target="_blank">final result</a>] [<a href="http://lea.verou.me/wdclass/rating-widget/rating-widget.js">JS code</a>] [<a href="http://lea.verou.me/wdclass/rating-widget/rating-widget-incomplete.js" target="_blank">incomplete JS code</a>]</h4>
<p>The students were given an HTML and a CSS file and they had to fill in a .js file that had some parts missing (replaced by TODO comments as placeholders) to complete a very simple ajax rating widget.</p>
<h4>Lessons learned</h4>
<ul>
<li>Never provide downloadable slides with the things the students must write by themselves prior to the lecture. They&#8217;ll just copy-paste everything from the pdf, even if they have to fix spacing afterwards. If you absolutely have to, make sure the text is not selectable.</li>
<li>It takes students far more time to write code than you planned for</li>
<li>When the students don&#8217;t understand something, most of them won&#8217;t ask. <img src='http://lea.verou.me/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  It&#8217;s best if you personally explain things to anyone having difficulties, but there&#8217;s usually not enough time for that</li>
</ul>
<h3 id="aftermath">Personal aftermath</h3>
<ul>
<li>I found out that I <strong>love</strong> teaching. Successfully helping a student with a problem they had or something they did not understand was sometimes enough to make my day. Preparing material for the course &#8211;although exhausting&#8211; was one of the most interesting and creative things I have ever done. Even the actual teaching is thrilling. It&#8217;s very challenging to try to keep the students&#8217; interest, since most of them will resort to chatting with their buddies instead of paying attention way more easily than professionals would during a conference talk. However, if you manage to do so, it can be quite rewarding.</li>
<li>I <strong>hate</strong> grading. It&#8217;s boring, time-consuming, carries a lot of responsibility and you have to ensure every point you deduct is justified, because you might have to defend your judgement in case a student complains. Sometimes it can also freak you out completely (&#8220;OMGWTF, how could they understand it so wrong?? Why didn&#8217;t they ask?&#8221;) These strips sum it up perfectly (and with a good dose of humor):</li>
</ul>
<p><a href="http://www.phdcomics.com/comics.php?f=1319"><img class="alignnone" title="Grading Rubric" src="http://www.phdcomics.com/comics/archive/phd051910s.gif" alt="Grading Rubric" width="600" height="500" /></a></p>
<p><a href="http://www.phdcomics.com/comics.php?f=1320"><img class="alignnone" title="If only" src="http://www.phdcomics.com/comics/archive/phd052110s.gif" alt="If only" width="600" height="260" /></a></p>

]]></content:encoded>
			<wfw:commentRss>http://lea.verou.me/2010/07/organizing-a-university-course-on-modern-web-development/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
	</channel>
</rss>

