<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/css/rss20.xsl" type="text/xsl"?>
<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/" xmlns:pheedo="http://www.pheedo.com/namespace/pheedo">
	<channel>
		<title>SitePoint &#187; JavaScript &amp; CSS</title>
		<atom:link href="http://www.sitepoint.com/blogs/category/dhtml-css/feed/" rel="self" type="application/rss+xml"/>
		<link>http://www.sitepoint.com/blogs</link>
		<description>News, opinion, and fresh thinking for web developers and designers. The official podcast of sitepoint.com.</description>
		<lastBuildDate>Mon, 15 Mar 2010 10:07:16 +0000</lastBuildDate>
		<generator>http://wordpress.org/?v=2.8.6</generator>
		<language>en</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
		<item>
			<title>Creating Beveled Images with CSS</title>
			<link>http://www.pheedcontent.com/click.phdo?i=4d3982c5fd12610aefc0298b16b6b928</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2010/03/05/creating-beveled-images-with-css/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2010/03/05/creating-beveled-images-with-css/#comments</comments>
			<pubDate>Fri, 05 Mar 2010 02:23:44 +0000</pubDate>
			<dc:creator>brothercake</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=18830</guid>
			<description><![CDATA[In this post, James shows us several variations of a technique for using pure CSS to create a beveled effect on images -- with no Photoshop in sight!


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/06/02/css-sizing-absolute-position/' rel='bookmark' title='Permanent Link: The Two Ways of Sizing Absolute Elements in CSS'>The Two Ways of Sizing Absolute Elements in CSS</a> <small>Most developers have used left, right, top and bottom properties...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/01/18/how-to-create-a-cool-halftone-effect-with-text-images-in-photoshop/' rel='bookmark' title='Permanent Link: How To Create A Cool Halftone Effect With Text &#038; Images In Photoshop'>How To Create A Cool Halftone Effect With Text &#038; Images In Photoshop</a> <small>Jennifer demonstrates how to create the retro print effect of...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/01/26/censor-your-images-with-a-mosaic-in-photoshop/' rel='bookmark' title='Permanent Link: Censor Your Images With A Mosaic In Photoshop'>Censor Your Images With A Mosaic In Photoshop</a> <small>Jennifer shows you how to apply a pixelated mosaic effect...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=4d3982c5fd12610aefc0298b16b6b928&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=4d3982c5fd12610aefc0298b16b6b928&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p>Recently, I wanted a simple <abbr title="Cascading Style Sheets">CSS</abbr> method for adding a beveled effect to images. It&#8217;s easy enough to create a sense of depth with normal outset borders (<em>below left</em>), but I was after an effect that would <strong>actually look like part of the image</strong>, as though it were a bevel on the image itself (<em>below right</em>).</p>
<div style="margin: 0pt; padding: 5px 10px 15px; float: left; width: 420px;"><img style="float:right" src="http://www.sitepoint.com/blogs/wp-content/uploads/2010/03/rgbaborders-eg2.jpg" alt="Demo 2: The borders look like bevelling on the image itself." width="200" height="200" /><br />
<img style="float:left" src="http://www.sitepoint.com/blogs/wp-content/uploads/2010/03/rgbaborders-eg11.jpg" alt="Demo 1: The image has gray outset borders around it." width="200" height="200" /></div>
<p style="clear:both">In the end I found <em>four</em> different ways of doing it, each with different levels of support: from the cleanest approach that only worked in one browser, to the most robust that works in everything back to <abbr title="Internet Explorer 6">IE6</abbr>.</p>
<p>All of them work on the same core principal; black borders for shade and white borders for highlighting are overlaid on top of an image, and then blended with some form of opacity. In each case, browsers without support for that technique will simply show the image as normal.</p>
<h2>Technique 1: Using Generated Content on the Image (<a title="View a working demo of “Technique 1: Using generated content on the image”" href="http://www.sitepoint.com/examples/rgbaborders/technique1.html">Demo</a>)</h2>
<ul>
<li><strong>Pros:</strong> Ultra-clean technique requires no additional markup</li>
<li><strong>Cons:</strong> Only works in Opera</li>
</ul>
<p>With this first technique we create a pseudo-element using <code>:after</code>,   then style it to be <strong>perfectly overlaid</strong> on top of the image. Then we add borders to the overlaid element, and use <abbr title="Red Green Blue Aplha">RGBA</abbr> to define each border color: the top and left borders are <code>rgba(255,255,255,0.4),</code> white with 40% opacity; and the bottom and right borders are <code>rgba(0,0,0,0.4),</code> black with 40% opacity:</p>
<pre><code>img.beveled
{
    position:relative;
}
img.beveled:after
{
    position:absolute;
    left:0;
    top:0;
    display:block;
    content:"\00a0";
    box-sizing:border-box;
    width:100%;
    height:100%;
    border:5px solid;
    border-color:rgba(255,255,255,0.4)
                 rgba(0,0,0,0.4)
                 rgba(0,0,0,0.4)
                 rgba(255,255,255,0.4);
}</code></pre>
<pre><code>&lt;img class="beveled" src="stormtroopers.jpg"
     alt="A legion of Lego Stormtroopers, standing in formation." /&gt;</code></pre>
<p>This technique only works in Opera because no other browser supports generated content on multimedia replacement elements like <code>&lt;img&gt;</code> and <code>&lt;object&gt;</code>. But since we&#8217;re only addressing Opera, we have the freedom to use <code>box-sizing</code> and <code>100%</code> dimensions, rather than having to define the dimensions explicitly.</p>
<div id="adz" class="vertical"></div><p>(Note: the value of the <code>content</code> property in all these examples is a unicode non-breaking space. This is added because pseudo-elements have to contain <em>something</em> or they&#8217;re not rendered.)</p>
<h2>Technique 2: Using Generated Content on a Wrapper Element (<a title="View a working demo of “Technique 2: Using generated content on a wrapper element”" href="http://www.sitepoint.com/examples/rgbaborders/technique2.html">Demo</a>)</h2>
<ul>
<li><strong>Pros:</strong> Wider range of supported browsers</li>
<li><strong>Cons:</strong> Requires additional markup and explicit dimensions</li>
</ul>
<p>The second technique is essentially the same as the first, but this time we create the overlay element using generated content on a wrapper <code>&lt;span&gt;</code> for browsers that don&#8217;t support generated content on the <code>&lt;img&gt;</code> itself. For this technique we also need to begin defining explicit dimensions on the wrapper element and the generated content (although we could use vendor-specific versions of <code>box-sizing</code> on the generated content, we&#8217;d still have to define the dimensions of the wrapper, so we may as well do the same for both):</p>
<pre><code>span.beveled
{
    position:relative;
    width:200px;
    height:200px;
    display:block;
}
span.beveled:after
{
    position:absolute;
    left:0;
    top:0;
    display:block;
    content:"\00a0";
    width:190px;
    height:190px;
    border:5px solid;
    border-color:rgba(255,255,255,0.4)
                 rgba(0,0,0,0.4)
                 rgba(0,0,0,0.4)
                 rgba(255,255,255,0.4);
}</code></pre>
<pre><code>&lt;span class="beveled"&gt;
    &lt;img src="stormtroopers.jpg"
         alt="A legion of Lego Stormtroopers, standing in formation." /&gt;
&lt;/span&gt;</code></pre>
<h2>Technique 3: Using Shadows instead of Borders (<a title="View a working demo of “Technique 3: Using shadows instead of borders”" href="http://www.sitepoint.com/examples/rgbaborders/technique3.html">Demo</a>)</h2>
<ul>
<li><strong>Pros:</strong> The most visually attractive technique</li>
<li><strong>Cons:</strong> Only works in Firefox 3.5 or later</li>
</ul>
<p>The third technique is a diversion from the second, where instead of using <abbr title="Red Green Blue Aplha">RGBA</abbr> borders we&#8217;re using <code>-moz-box-shadow:inset</code> to create the beveling effect. Since box shadow effects have an alpha <em>gradient</em> (rather than the same opacity at all points), the overall effect is much prettier and more rounded; and the spread radius parameter can be subtly used to blend away the corner sharpness.</p>
<p>This effect is only supported in Firefox 3.5 or later; although Safari does implement box-shadow (as <code>-webkit-box-shadow</code>), there&#8217;s no support for <code>inset</code>:</p>
<pre><code>span.beveled
{
    position:relative;
    width:200px;
    height:200px;
    display:block;
}
span.beveled:after
{
    position:absolute;
    left:0;
    top:0;
    display:block;
    content:"\00a0";
    width:200px;
    height:200px;
    -moz-box-shadow:-5px -5px 2px rgba(0,0,0,0.4) inset,
                    5px 5px 2px rgba(255,255,255,0.4) inset;
}</code></pre>
<pre><code>&lt;span class="beveled"&gt;
    &lt;img src="stormtroopers.jpg"
         alt="A legion of Lego Stormtroopers, standing in formation." /&gt;
&lt;/span&gt;</code></pre>
<p>I suppose we could have added a <code>-webkit</code> version anyway, in the hope of forward compatibility, but that would be a risk since we can&#8217;t know what any future implementation will be like — it might be worse than nothing!</p>
<h2>Technique 4: Everybody&#8217;s Happy (<a title="View a working demo of “Technique 4: Everybody's happy”" href="http://www.sitepoint.com/examples/rgbaborders/technique4.html">Demo</a>)</h2>
<ul>
<li><strong>Pros:</strong> Works in all modern browsers</li>
<li><strong>Cons:</strong> Requires more additional markup and explicit dimensions</li>
</ul>
<p>The fourth and final technique is the most cross-browser compatible, but also requires the most <abbr title="HyperText Markup Language">HTML</abbr> modification. It&#8217;s essentially the same as the second technique, but with two important differences: firstly, it uses a second physical <code>&lt;span&gt;</code> rather than generated content; and secondly, it uses ordinary <abbr title="hexadecimal">hex</abbr> border colors rather than <abbr title="Red Green Blue Aplha">RGBA</abbr>, and then <strong>blends the whole element</strong> with opacity. Even Internet Explorer can handle this:</p>
<pre><code>span.beveled
{
    position:relative;
    width:200px;
    height:200px;
    display:block;
}
span.beveled span
{
    position:absolute;
    left:0;
    top:0;
    display:block;
    width:190px;
    height:190px;
    border:5px solid;
    border-color:#fff #000 #000 #fff;
    filter:alpha(opacity=40);
    opacity:0.4;
}</code></pre>
<pre><code>&lt;span class="beveled"&gt;
    &lt;img src="stormtroopers.jpg"
         alt="A legion of Lego Stormtroopers, standing in formation." /&gt;
    &lt;span&gt;&lt;/span&gt;
&lt;/span&gt;</code></pre>
<h2>Further Development</h2>
<p>You could take this further by <a title="View a working demo of “Technique 4b: Using colourful borders”" href="http://www.sitepoint.com/examples/rgbaborders/technique4b.html">using colorful borders</a> for a gel-like effect, or even <a title="View a working demo of “Technique 4c: Multiple staggered overlays”" href="http://www.sitepoint.com/examples/rgbaborders/technique4c.html">multiple staggered overlays</a> to create effects that are more subtle or intricate.</p>
<p>But the basic idea is here, and I hope you find it useful. It&#8217;s certainly been great fun to play with!</p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/06/02/css-sizing-absolute-position/' rel='bookmark' title='Permanent Link: The Two Ways of Sizing Absolute Elements in CSS'>The Two Ways of Sizing Absolute Elements in CSS</a> <small>Most developers have used left, right, top and bottom properties...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/01/18/how-to-create-a-cool-halftone-effect-with-text-images-in-photoshop/' rel='bookmark' title='Permanent Link: How To Create A Cool Halftone Effect With Text &#038; Images In Photoshop'>How To Create A Cool Halftone Effect With Text &#038; Images In Photoshop</a> <small>Jennifer demonstrates how to create the retro print effect of...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/01/26/censor-your-images-with-a-mosaic-in-photoshop/' rel='bookmark' title='Permanent Link: Censor Your Images With A Mosaic In Photoshop'>Censor Your Images With A Mosaic In Photoshop</a> <small>Jennifer shows you how to apply a pixelated mosaic effect...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=4d3982c5fd12610aefc0298b16b6b928&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=4d3982c5fd12610aefc0298b16b6b928&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2010/03/05/creating-beveled-images-with-css/feed/</wfw:commentRss>
			<slash:comments>14</slash:comments>
		</item>
		<item>
			<title>What&#8217;s the difference between function.call and function.apply?</title>
			<link>http://www.pheedcontent.com/click.phdo?i=c40caee575f4af3b7cb7ab3352c255f3</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2010/03/02/whats-the-difference-between-function-call-and-function-apply/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2010/03/02/whats-the-difference-between-function-call-and-function-apply/#comments</comments>
			<pubDate>Tue, 02 Mar 2010 04:03:55 +0000</pubDate>
			<dc:creator>Andrew Tetlaw</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=18694</guid>
			<description><![CDATA[Function.call and function.apply are a couple of very useful methods, but do you know the difference?


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/' rel='bookmark' title='Permanent Link: Cross-browser JSON Serialization in JavaScript'>Cross-browser JSON Serialization in JavaScript</a> <small>JSON serialization can be incredibly useful, but few browsers support...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/11/12/getty-images-call-for-artists-on-flickr/' rel='bookmark' title='Permanent Link: Getty Images Call For Artists On Flickr'>Getty Images Call For Artists On Flickr</a> <small>Getty Images are making a formal call for artists through...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/01/14/pareto-principle-80-20-rule/' rel='bookmark' title='Permanent Link: The Pareto Principle: Does the 80/20 Rule Apply to Your Life?'>The Pareto Principle: Does the 80/20 Rule Apply to Your Life?</a> <small>The 80/20 Rule states that 80% of the output comes...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=c40caee575f4af3b7cb7ab3352c255f3&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=c40caee575f4af3b7cb7ab3352c255f3&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.sitepoint.com/blogs/wp-content/uploads/2010/03/javascript_call_array.jpg" alt="Butterfly" title="Butterfly" width="184" height="190" class="alignright size-full wp-image-18704" />Today I read a great blog post by Mark Needham titled <em><a href="http://www.markhneedham.com/blog/2010/02/28/javascript-confusing-call-and-apply/">JavaScript: Confusing &#8216;call&#8217; and &#8216;apply&#8217;</a></em>. A while back I wrote an article for our <a href="http://www.sitepoint.com/newsletter/"><em>Tech Times</em> newsletter</a> about the JavaScript <code>arguments</code> object. It was called <em><a href="http://www.sitepoint.com/newsletter/viewissue.php?id=3&amp;issue=215&amp;format=html"><code>arguments</code>: A JavaScript Oddity</a></em> because it has all sorts of interesting behaviors that are useful to know about. I realized that although I&#8217;d used both <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Function/call"><code>call</code></a> and <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Function/apply"><code>apply</code></a> in that article I hadn&#8217;t talked about the difference.</p>
<p>Well it&#8217;s actually quite simple. First of all, both methods expect a <code>thisArg</code> as the first argument. This is the argument that gives the function a context; it determines the value of the JavaScript keyword <code>this</code> inside the function that is called or applied. The single difference is that the <code>call</code> method requires that arguments are specified separately; the <code>apply</code> method takes them as an array. It&#8217;s clearer if you see the syntax:</p>
<pre><code>function.call(thisArg[, argument1[, argument2[, ...]]]);</code></pre>
<pre><code>function.apply(thisArg[, argumentArray]);</code></pre>
<p>So if you&#8217;re working with the <code>arguments</code> object in your JavaScript, you can call any function by using the apply method and simply pass in the existing <code>arguments</code> object as the array argument.</p>
<p>Hope that&#8217;s useful to you!</p>
<div id="adz" class="horizontal"></div><p><em><a href="http://www.flickr.com/photos/sudhamshu/3344816160/">Feature image by Sudhamshu</a>. Can you work out the significance?</em></p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=horizontal" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/' rel='bookmark' title='Permanent Link: Cross-browser JSON Serialization in JavaScript'>Cross-browser JSON Serialization in JavaScript</a> <small>JSON serialization can be incredibly useful, but few browsers support...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/11/12/getty-images-call-for-artists-on-flickr/' rel='bookmark' title='Permanent Link: Getty Images Call For Artists On Flickr'>Getty Images Call For Artists On Flickr</a> <small>Getty Images are making a formal call for artists through...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/01/14/pareto-principle-80-20-rule/' rel='bookmark' title='Permanent Link: The Pareto Principle: Does the 80/20 Rule Apply to Your Life?'>The Pareto Principle: Does the 80/20 Rule Apply to Your Life?</a> <small>The 80/20 Rule states that 80% of the output comes...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=c40caee575f4af3b7cb7ab3352c255f3&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=c40caee575f4af3b7cb7ab3352c255f3&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2010/03/02/whats-the-difference-between-function-call-and-function-apply/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		</item>
		<item>
			<title>Keep Your Font Stacks from Falling Over</title>
			<link>http://www.pheedcontent.com/click.phdo?i=221ea7f9807e8d4d07cbdd8f6e231462</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2010/03/02/keep-your-font-stacks-from-falling-over/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2010/03/02/keep-your-font-stacks-from-falling-over/#comments</comments>
			<pubDate>Tue, 02 Mar 2010 03:04:57 +0000</pubDate>
			<dc:creator>Louis Simoneau</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=18649</guid>
			<description><![CDATA[One key element of site testing is font stacks. Louis takes a look at common problems.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/09/01/ikea-and-the-font-fiasco/' rel='bookmark' title='Permanent Link: IKEA and the Font Fiasco'>IKEA and the Font Fiasco</a> <small>IKEA have recently changed their font from Futura to Verdana,...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/10/16/the-sans-serif-typeface/' rel='bookmark' title='Permanent Link: The Sans Serif Typeface'>The Sans Serif Typeface</a> <small>Continuing our ongoing series on Typefaces, Jennifer takes a look...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/03/18/serif-fonts-vs-sans-serif-fonts-a-working-case-study/' rel='bookmark' title='Permanent Link: Serif Fonts Vs. Sans Serif Fonts: A Working Case Study'>Serif Fonts Vs. Sans Serif Fonts: A Working Case Study</a> <small>Sans serif fonts are the norm for web sites, but...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=221ea7f9807e8d4d07cbdd8f6e231462&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=221ea7f9807e8d4d07cbdd8f6e231462&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img class="imgright" title="Alphabet Blocks" src="http://www.sitepoint.com/blogs/wp-content/uploads/2010/03/iStock_000010708502XSmall.jpg" alt="Alphabet Blocks" width="236" height="201" />For most web designers and developers, testing is a huge part of the job. They&#8217;ll devote a considerable amount of time ensuring that their sites appear similar, if not identical, in a wide range of browsers. One key part of site testing, however, seems to be all too frequently forgotten: font stack testing.</p>
<p><strong>The Problem</strong></p>
<p>Most web designers rely largely on a set of free, widely distributed fonts for much of their site&#8217;s text content. Yet, no matter how widely available a font is, there&#8217;s still a chance it will be absent from a given visitor&#8217;s system. Fortunately, CSS lets us specify a stack of fonts to use in case the preferred font is missing. By specifying three or four fonts in this manner, followed by a generic catch-all <code>serif</code> or <code>sans-serif</code>, we ensure that our content is displayed in a font that at least resembles the one we wanted. In theory that&#8217;s great, but if the appearance of the site isn&#8217;t tested with each of the potential fallback fonts, problems can arise. For example, when viewing the PharmQD website on my home machine (running Ubuntu Linux), I see the following:</p>
<p><img class="alignnone size-full wp-image-18709" title="PharmQD website, broken due to a missing font" src="http://www.sitepoint.com/blogs/wp-content/uploads/2010/03/pharmqd_broken1.png" alt="PharmQD website, broken due to a missing font" width="350" height="310" /></p>
<p>As you can see, the titles break onto an extra line, which was clearly not anticipated by the designers when they were putting together the layout. Why? Because the font stack used for these titles is <code>Tahoma, Verdana, Arial, Helvetica, sans-serif;</code>, and Tahoma is significantly narrower (at the same font size and weight) than Verdana or Arial. So when viewed on a system without Tahoma, the fallback font is used, and since all the fallbacks are wider, the text takes up more space than was anticipated in the design. Here&#8217;s what the design was intended to look like, this time viewed on my work machine, running OS X:</p>
<p><img class="alignnone size-full wp-image-18653" title="The correct appearance of the PharmQD website" src="http://www.sitepoint.com/blogs/wp-content/uploads/2010/03/pharmqd_correct.png" alt="The correct appearance of the PharmQD website" width="345" height="320" /></p>
<div id="adz" class="vertical"></div><p>Tahoma isn&#8217;t the only font vulnerable to this kind of breakdown. Microsoft&#8217;s Vista fonts (Calibri, Cambria, Candara, and Constantia) are significantly smaller than most others fonts at the same point size, so using any of these in a stack can result in similar issues.<br />
<strong><br />
Testing Tools</strong></p>
<p>Strangely enough, despite the wealth of testing tools available for web developers, there&#8217;s no simple answer for testing font stacks. One less-than-ideal solution is to use Firebug to manually edit the <code>font-family</code> declarations associated with the parts of the page that are highly dependent on font size: buttons, navigation items, headings, and so on.</p>
<p>A quick Google search also revealed this promising-looking project on Github: <a href="http://github.com/leeky/Font-Stack-Tester">Font Stack Tester</a>, by Robert Lee-Cann. It&#8217;s a jQuery script that adds an overlay at the top of a page with buttons to disable any of the fonts found on the page. The developer wants to eventually turn it into a bookmarklet, but at the moment it&#8217;s definitely in its infancy.</p>
<p><em><strong>Update: </strong>In the few days since I originally posted this, an enterprising individual has registered <a href="http://fontstacktester.com/">http://fontstacktester.com/</a> and put up a hosted version of that GitHub project. Just enter your site URL, and it will take you there, adding a bar along the top that you can use to disable fonts one by one to test how your stacks hold up. Kudos to Chris for the speed with which this was developed!</em></p>
<p>No matter how you go about it, font stack testing should definitely not be neglected: when something breaks as badly as the example above, it can really damage that visitor&#8217;s impression of your site.</p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/09/01/ikea-and-the-font-fiasco/' rel='bookmark' title='Permanent Link: IKEA and the Font Fiasco'>IKEA and the Font Fiasco</a> <small>IKEA have recently changed their font from Futura to Verdana,...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/10/16/the-sans-serif-typeface/' rel='bookmark' title='Permanent Link: The Sans Serif Typeface'>The Sans Serif Typeface</a> <small>Continuing our ongoing series on Typefaces, Jennifer takes a look...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/03/18/serif-fonts-vs-sans-serif-fonts-a-working-case-study/' rel='bookmark' title='Permanent Link: Serif Fonts Vs. Sans Serif Fonts: A Working Case Study'>Serif Fonts Vs. Sans Serif Fonts: A Working Case Study</a> <small>Sans serif fonts are the norm for web sites, but...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=221ea7f9807e8d4d07cbdd8f6e231462&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=221ea7f9807e8d4d07cbdd8f6e231462&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2010/03/02/keep-your-font-stacks-from-falling-over/feed/</wfw:commentRss>
			<slash:comments>18</slash:comments>
		</item>
		<item>
			<title>jQTouch Makes Web Development on the iPhone and iPod Touch a Snap</title>
			<link>http://www.pheedcontent.com/click.phdo?i=e179f5e62097d9c42a086f4f7e83719e</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2010/02/24/jqtouch-makes-web-development-on-the-iphone-and-ipod-touch-a-snap/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2010/02/24/jqtouch-makes-web-development-on-the-iphone-and-ipod-touch-a-snap/#comments</comments>
			<pubDate>Wed, 24 Feb 2010 05:31:57 +0000</pubDate>
			<dc:creator>Andrew Tetlaw</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=18526</guid>
			<description><![CDATA[jQTouch is a jQuery plugin for web development on the iPhone and iPod Touch. But it’s more than just a plugin; its simplified development approach helps you rapidly create great looking apps. It's well worth a look.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/06/12/ui-stencil-kit-for-iphone-app-designers/' rel='bookmark' title='Permanent Link: UI Stencil Kit for iPhone App Designers'>UI Stencil Kit for iPhone App Designers</a> <small>iPhone interface design is über-cool right now, as is hand...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/01/27/7-reasons-developers-desert-iphone-apps/' rel='bookmark' title='Permanent Link: 7 Reasons Why Developers are Deserting iPhone Apps'>7 Reasons Why Developers are Deserting iPhone Apps</a> <small>Are developers being enticed away from bespoke mobile application development...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/06/15/40-iphone-applications-for-designers/' rel='bookmark' title='Permanent Link: 40 Essential iPhone Applications For Web Designers'>40 Essential iPhone Applications For Web Designers</a> <small>With an iPhone or iPod Touch, web designers can finally...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=e179f5e62097d9c42a086f4f7e83719e&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=e179f5e62097d9c42a086f4f7e83719e&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.sitepoint.com/blogs/wp-content/uploads/2010/02/jqtouch-screen.png" alt="jqtouch-screen" title="jqtouch-screen" width="164" height="200" class="alignright size-full wp-image-18529 imgright" />
<p>
  <a href="http://jqtouch.com/"><strong>jQTouch is described on the site</strong></a><strong> as a jQuery plugin for web development on the iPhone and iPod Touch. But it&#8217;s more than just a plugin; its simplified development approach helps you create and theme the various screens of your web app and apply animated transitions between them.</strong>
</p>
<p>
  It will help in all manner of ways, but app development using jQTouch is quick if you follow a simple recipe. You create a series of <code>div</code> elements (one for each screen in your application), give each one an <code>id</code>, and give the home screen the class of <code>current</code>. You then place an unordered list within the home screen <code>div</code>. In each list item you place an anchor tag with a <code>href</code> that links to one of the other <code>div</code>s.
</p>
<p>
  With just that simple recipe jQTouch will hide all the <code>div</code>s except the home screen, and render your list with attractive gradients as the main menu. It&#8217;ll also wire up the tap action so that a tap on one of the list items will make the home screen slide off and the linked <code>div</code> element slide on. This is very similar to the style of the default menus.
</p>
<p>
  It&#8217;s definitely worth checking out. <a href="http://www.campaignmonitor.com/blog/post/3029/campaign-monitor-for-your-iphone/">Campaign Monitor revealed recently</a> that they used jQTouch on their recent iPhone app, and there&#8217;s <a href="http://jqtouch.com/preview/demos/main/">a demo on the jQTouch site</a> that&#8217;ll also work in desktop Safari.
</p>
<div id="adz" class="horizontal"></div><p>
  With RIM announcing that it&#8217;s developed a WebKit-based browser for BlackBerry devices, it&#8217;s probably not a stretch to imagine this library could eventually be used to develop for iPhone, iPod Touch, Android, and Blackberry.</p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=horizontal" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/06/12/ui-stencil-kit-for-iphone-app-designers/' rel='bookmark' title='Permanent Link: UI Stencil Kit for iPhone App Designers'>UI Stencil Kit for iPhone App Designers</a> <small>iPhone interface design is über-cool right now, as is hand...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/01/27/7-reasons-developers-desert-iphone-apps/' rel='bookmark' title='Permanent Link: 7 Reasons Why Developers are Deserting iPhone Apps'>7 Reasons Why Developers are Deserting iPhone Apps</a> <small>Are developers being enticed away from bespoke mobile application development...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/06/15/40-iphone-applications-for-designers/' rel='bookmark' title='Permanent Link: 40 Essential iPhone Applications For Web Designers'>40 Essential iPhone Applications For Web Designers</a> <small>With an iPhone or iPod Touch, web designers can finally...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=e179f5e62097d9c42a086f4f7e83719e&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=e179f5e62097d9c42a086f4f7e83719e&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2010/02/24/jqtouch-makes-web-development-on-the-iphone-and-ipod-touch-a-snap/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		</item>
		<item>
			<title>Improve Your jQuery Knowledge with the Source Viewer</title>
			<link>http://www.pheedcontent.com/click.phdo?i=8f4d5f972949f03aca27b7778a981f26</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2010/02/18/jquery-source-viewer-tool/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2010/02/18/jquery-source-viewer-tool/#comments</comments>
			<pubDate>Thu, 18 Feb 2010 00:33:29 +0000</pubDate>
			<dc:creator>Craig Buckler</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<category><![CDATA[javascript]]></category>
			<category><![CDATA[jquery]]></category>
			<category>javascript</category>
			<category>jquery</category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=17778</guid>
			<description><![CDATA[The jQuery source viewer is a great tool which allows you to easily access methods and jump around the framework's 6,000 lines of code. Craig takes a closer look.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/07/22/how-to-develop-a-jquery-plugin/' rel='bookmark' title='Permanent Link: How To Develop a jQuery Plugin'>How To Develop a jQuery Plugin</a> <small>Creating a jQuery plugin is easier than you might think....</small></li><li><a href='http://www.sitepoint.com/blogs/2009/04/21/make-your-own-web-site-badges-with-jquery-and-json/' rel='bookmark' title='Permanent Link: Make Your Own Web Site Badges with jQuery and JSON'>Make Your Own Web Site Badges with jQuery and JSON</a> <small>Now that most social media sites offer a JSON API,...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/01/18/jquery-14-released/' rel='bookmark' title='Permanent Link: jQuery 1.4 Released'>jQuery 1.4 Released</a> <small>jQuery 1.4 has been released. Craig looks at the new...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=8f4d5f972949f03aca27b7778a981f26&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=8f4d5f972949f03aca27b7778a981f26&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img src="http://blogs.sitepointstatic.com/images/tech/258-jquery-source.png" width="200" height="200" alt="jQuery source viewer" class="imgright" />jQuery is a great JavaScript framework. However, as with any library, sometimes it&#8217;s necessary to get under the hood to discover what&#8217;s going on. Perhaps it&#8217;s because you&#8217;re tracing a bug or are just curious about how jQuery achieves a particular UI effect.</p>
<p>Although jQuery compresses to under 70Kb, the uncompressed file comprises 6,000 lines of JavaScript code. Your text editor or IDE may offer a function list, but there are dozens of methods to wade through and it&#8217;s not always easy to find the code block you need. Fortunately, UK web developer <a href="http://james.padolsey.com/">James Padolsey</a> has come up with a neat solution &#8212; the <a href="http://james.padolsey.com/jquery/">jQuery source viewer</a>.</p>
<p><img src="http://blogs.sitepointstatic.com/images/tech/258-jquery-source-screen.png" width="450" height="320" alt="jQuery source viewer" class="imgcenter" style="display:block;margin:25px auto;" /></p>
<p>The tool will find the code for any function name you enter (note that names are case-sensitive). By default, it will return version 1.4 code, but versions 1.3.2 and 1.2.6 are also available.</p>
<div id="adz" class="horizontal"></div><p>Other jQuery methods are highlighted and click-able so it&#8217;s easy to jump to other code blocks. You can also find functions from the URL, e.g.</p>
<ul>
<li><a href="http://james.padolsey.com/jquery/css">http://james.padolsey.com/jquery/css</a><br />
shows the css method for the latest version of jQuery supported (1.4)</li>
<li><a href="http://james.padolsey.com/jquery/1.3.2/attr">http://james.padolsey.com/jquery/1.3.2/attr</a><br />
shows the attr method for jQuery version 1.3.2</li>
</ul>
<p>The tool&#8217;s a fantastic idea and will certainly save time when hunting through the jQuery source. Thanks James. My only request: a case-insensitive auto-suggest box would make it absolutely perfect.</p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=horizontal" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/07/22/how-to-develop-a-jquery-plugin/' rel='bookmark' title='Permanent Link: How To Develop a jQuery Plugin'>How To Develop a jQuery Plugin</a> <small>Creating a jQuery plugin is easier than you might think....</small></li><li><a href='http://www.sitepoint.com/blogs/2009/04/21/make-your-own-web-site-badges-with-jquery-and-json/' rel='bookmark' title='Permanent Link: Make Your Own Web Site Badges with jQuery and JSON'>Make Your Own Web Site Badges with jQuery and JSON</a> <small>Now that most social media sites offer a JSON API,...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/01/18/jquery-14-released/' rel='bookmark' title='Permanent Link: jQuery 1.4 Released'>jQuery 1.4 Released</a> <small>jQuery 1.4 has been released. Craig looks at the new...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=8f4d5f972949f03aca27b7778a981f26&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=8f4d5f972949f03aca27b7778a981f26&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2010/02/18/jquery-source-viewer-tool/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		</item>
		<item>
			<title>!important is Actually Useful (in Print Style Sheets)</title>
			<link>http://www.pheedcontent.com/click.phdo?i=999a75fadbe9c3a7fb9994f3f4b86f2c</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2010/02/16/important-is-actually-useful-in-print-style-sheets/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2010/02/16/important-is-actually-useful-in-print-style-sheets/#comments</comments>
			<pubDate>Tue, 16 Feb 2010 04:29:52 +0000</pubDate>
			<dc:creator>Andrew Tetlaw</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=18284</guid>
			<description><![CDATA[Wow, !important is actually useful in CSS. Who Knew!?


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2010/03/03/create-inset-style-type-in-photoshop/' rel='bookmark' title='Permanent Link: Create Inset-Style Type In Photoshop'>Create Inset-Style Type In Photoshop</a> <small>Jennifer shows you how to create the popular inset or...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/01/08/9-reasons-why-svgs-are-important-for-the-web/' rel='bookmark' title='Permanent Link: 9 Reasons Why SVGs are Important for the Web'>9 Reasons Why SVGs are Important for the Web</a> <small>Few developers use the SVG format because it's not supported...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/06/22/how-to-style-your-type-with-css/' rel='bookmark' title='Permanent Link: How To Style Your Type With CSS'>How To Style Your Type With CSS</a> <small>Jennifer demonstrates how to use CSS to style type and...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=999a75fadbe9c3a7fb9994f3f4b86f2c&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=999a75fadbe9c3a7fb9994f3f4b86f2c&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-18286 imgright" title="!important" src="http://www.sitepoint.com/blogs/wp-content/uploads/2010/02/important.jpg" alt="!important" width="200" height="40" />The poor old <a href="http://reference.sitepoint.com/css/importantdeclarations"><code>!important</code></a> statement receives a lot of flak in the CSS community, and with good reason. It&#8217;s unnecessary, creates a maintenance nightmare, and makes a hollow mockery of the cascade. I haven&#8217;t thought about using <code>!important</code> in years, until I discovered one very good use for it: print style sheets.</p>
<p>Let&#8217;s pretend that we want to create an image gallery. Doing our best at honoring the ideals of progressive enhancement, we first make sure that the images are contained within an HTML list. Eventually we want to use JavaScript to create a fade-in/fade-out slideshow effect, but our base is a single column of images. If a visitor has JavaScript disabled that&#8217;s what they&#8217;ll see.</p>
<p>Okay, so far so good. When we come to make a print style sheet, however, we&#8217;ll discover a flaw in our plan: when you use JavaScript to animate HTML elements, you inevitably end up modifying the elements&#8217; <code>style</code> attribute. In our slide show, JavaScript has altered the <code>position</code> and <code>opacity</code> of the images, so only one is revealed at a time. When we go to print the gallery page, although we want a single column of images, what we end up printing is only a single image. That&#8217;s because you&#8217;re unable to specify a target media type for CSS declared in an element&#8217;s <code>style</code> attribute; you cannot say that all styles declared in the <code>style</code> attribute are for <code>screen</code> only.</p>
<p>So what you need is a way of specifying print styles that can override the inline styles. There&#8217;s only one way to do that: <code>!important</code>. In your print style sheet, reset the image elements&#8217; <code>position</code> and <code>opacity,</code> and add <code>!important</code>:</p>
<div id="adz" class="horizontal"></div><pre><code>img.gallery {
  position: static !important;
  opacity: 1 !important;
}</code></pre>
<p>That&#8217;s it really; I found a legitimate use for <code>!important</code> and wanted to share it.</p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=horizontal" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2010/03/03/create-inset-style-type-in-photoshop/' rel='bookmark' title='Permanent Link: Create Inset-Style Type In Photoshop'>Create Inset-Style Type In Photoshop</a> <small>Jennifer shows you how to create the popular inset or...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/01/08/9-reasons-why-svgs-are-important-for-the-web/' rel='bookmark' title='Permanent Link: 9 Reasons Why SVGs are Important for the Web'>9 Reasons Why SVGs are Important for the Web</a> <small>Few developers use the SVG format because it's not supported...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/06/22/how-to-style-your-type-with-css/' rel='bookmark' title='Permanent Link: How To Style Your Type With CSS'>How To Style Your Type With CSS</a> <small>Jennifer demonstrates how to use CSS to style type and...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=999a75fadbe9c3a7fb9994f3f4b86f2c&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=999a75fadbe9c3a7fb9994f3f4b86f2c&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2010/02/16/important-is-actually-useful-in-print-style-sheets/feed/</wfw:commentRss>
			<slash:comments>14</slash:comments>
		</item>
		<item>
			<title>Star Wars Makes CSS3 Animations and Transformations Make Sense</title>
			<link>http://www.pheedcontent.com/click.phdo?i=78a95999ccc5d13212492be768af52ce</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2010/02/09/star-wars-makes-css3-animations-and-transformations-make-sense/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2010/02/09/star-wars-makes-css3-animations-and-transformations-make-sense/#comments</comments>
			<pubDate>Tue, 09 Feb 2010 04:44:13 +0000</pubDate>
			<dc:creator>Andrew Tetlaw</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=18060</guid>
			<description><![CDATA[Anthony Calzadilla had made an impressive AT-AT walker animation using only CSS3. Find out how he did it.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/08/04/add-more-sparkle-with-css3/' rel='bookmark' title='Permanent Link: Add More Sparkle with CSS3'>Add More Sparkle with CSS3</a> <small> Have you noticed that when EA Games release a...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/02/24/jqtouch-makes-web-development-on-the-iphone-and-ipod-touch-a-snap/' rel='bookmark' title='Permanent Link: jQTouch Makes Web Development on the iPhone and iPod Touch a Snap'>jQTouch Makes Web Development on the iPhone and iPod Touch a Snap</a> <small>jQTouch is a jQuery plugin for web development on the...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/10/28/brainstorm-evaluation/' rel='bookmark' title='Permanent Link: Brainstorming: Making Sense and Taking Action'>Brainstorming: Making Sense and Taking Action</a> <small>Alyssa wraps up her series on brainstorming with a step-by-step...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=78a95999ccc5d13212492be768af52ce&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=78a95999ccc5d13212492be768af52ce&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-18077 imgright" title="atat-walker-css3" src="http://www.sitepoint.com/blogs/wp-content/uploads/2010/02/atat-walker-css3.jpg" alt="atat-walker-css3" width="250" height="191" />Being a JavaScript guy, I was always uncomfortable with the whole idea of CSS animations. It&#8217;s an interesting experiment, but to me JavaScript is where your animation should be. That was until I found <a href="http://anthonycalzadilla.com/css3-ATAT/index.html">this AT-AT walker animation</a> by Anthony Calzadilla.</p>
<p>Unfortunately, you&#8217;ll need a WebKit-based browser (Safari or Chrome, for example) to see it. So, sure it&#8217;s a WebKit proprietary CSS extension &#8212; the CSS3 <a href="http://www.w3.org/TR/css3-animations/">animation</a> and <a href="http://www.w3.org/TR/css3-transitions/">transformation</a> modules are working drafts at the moment &#8212; but it&#8217;s always fun to experiment. And this experiment sure got me thinking.</p>
<p>But first, how is it done? Each part of the animation is separate; that is, the foot, shin, and thigh of each leg. CSS is then used to define the animation. Here&#8217;s the animation definition for the foot on Leg D, the front right one:</p>
<pre><code>#atat #leg-d .leg-foot {
	-webkit-animation-name: foot-d;
	-webkit-animation-duration: 7s;
	-webkit-animation-iteration-count: infinite;
	-webkit-transform-origin: 50% 0;
}</code></pre>
<p>It&#8217;s given a name, a duration (for how long the animation lasts), an iteration count (how many times the animation is run &#8212; infinitely in this case), and a position of origin. The next piece of the puzzle is the information for key frames:</p>
<div id="adz" class="horizontal"></div><pre><code>@-webkit-keyframes foot-d {
  0% {
    -webkit-transform: rotate(0deg);
  }
  10% {
    -webkit-transform: rotate(-20deg);
  }
  30% {
    -webkit-transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(0deg);
  }
}</code></pre>
<p>With the <code>@-webkit-keyframe</code> at-rule you define the style rules to apply at certain stages of the animation duration. Here we have apply rules at the start of the animation (0%), when it&#8217;s 10% through, 30% through, and then when it&#8217;s finished (100%). In the case of this example, the <code>-webkit-transform</code> declaration is used to apply a rotation, although any CSS property could be applied.</p>
<p>By applying different degrees of rotation, for different animated parts at different times during the animation sequence, the illusion is almost like puppetry.</p>
<p>There&#8217;s also an alternative syntax to use inside a <code>@-webkit-keyframe</code> block; you can specify <code>to</code> and <code>from</code> values like so:</p>
<pre><code>@-webkit-keyframes fade-in {
  from {
    color: #fff
  }
  to {
    color: #000
  }
}</code></pre>
<p>What do you think? To me it looks like a really straightforward syntax for describing animation. But you know what would be really cool? If a jQuery plugin was written that could read CSS3 animation syntax and execute the animation, making it cross-browser compatible.</p>
<p>Now that would rock.</p>
<p>You can <a href="http://webkit.org/blog/324/css-animation-2/">read more about CSS3 animations on the WebKit blog</a>.</p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=horizontal" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/08/04/add-more-sparkle-with-css3/' rel='bookmark' title='Permanent Link: Add More Sparkle with CSS3'>Add More Sparkle with CSS3</a> <small> Have you noticed that when EA Games release a...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/02/24/jqtouch-makes-web-development-on-the-iphone-and-ipod-touch-a-snap/' rel='bookmark' title='Permanent Link: jQTouch Makes Web Development on the iPhone and iPod Touch a Snap'>jQTouch Makes Web Development on the iPhone and iPod Touch a Snap</a> <small>jQTouch is a jQuery plugin for web development on the...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/10/28/brainstorm-evaluation/' rel='bookmark' title='Permanent Link: Brainstorming: Making Sense and Taking Action'>Brainstorming: Making Sense and Taking Action</a> <small>Alyssa wraps up her series on brainstorming with a step-by-step...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=78a95999ccc5d13212492be768af52ce&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=78a95999ccc5d13212492be768af52ce&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2010/02/09/star-wars-makes-css3-animations-and-transformations-make-sense/feed/</wfw:commentRss>
			<slash:comments>11</slash:comments>
		</item>
		<item>
			<title>Introducing Gordon: the Flash Player Written in JavaScript</title>
			<link>http://www.pheedcontent.com/click.phdo?i=8ea6497fc7651e64565c839b20312a6a</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2010/02/02/gordon-javascript-flash-player/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2010/02/02/gordon-javascript-flash-player/#comments</comments>
			<pubDate>Tue, 02 Feb 2010 11:33:55 +0000</pubDate>
			<dc:creator>Craig Buckler</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<category><![CDATA[Flash]]></category>
			<category><![CDATA[iphone]]></category>
			<category><![CDATA[javascript]]></category>
			<category>flash</category>
			<category>iphone</category>
			<category>javascript</category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=17630</guid>
			<description><![CDATA[That's right - it's a Flash player written in JavaScript. So why emulate a browser plugin within a browser? Craig discusses Gordon and its potential impact on Apple's iPhone and iPad.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2010/02/02/ipad-vs-flash-developers-choose-wisely/' rel='bookmark' title='Permanent Link: iPad vs Flash: Developers, Choose Wisely'>iPad vs Flash: Developers, Choose Wisely</a> <small>The newly revealed Apple iPad offers no support for Flash....</small></li><li><a href='http://www.sitepoint.com/blogs/2010/02/11/adobe-apple-flash-criticism/' rel='bookmark' title='Permanent Link: Adobe Hits Back at Apple&#8217;s Criticism of Flash'>Adobe Hits Back at Apple&#8217;s Criticism of Flash</a> <small>Adobe's Kevin Lynch has hit back at Steve Jobs following...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/09/27/jsnes-javascript-nes-emulator/' rel='bookmark' title='Permanent Link: JSNES: a NES Emulator Written in JavaScript'>JSNES: a NES Emulator Written in JavaScript</a> <small>Just when you thought you'd seen everything in JavaScript, along...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=8ea6497fc7651e64565c839b20312a6a&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=8ea6497fc7651e64565c839b20312a6a&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img src="http://blogs.sitepointstatic.com/images/tech/251-js-flash-player.jpg" width="220" height="220" alt="Gordon - the Flash JavaScript player" class="imgright" />JavaScript has been used for a number of unusual projects in the past few years. We&#8217;ve had <a href="http://www.sitepoint.com/blogs/2009/09/27/jsnes-javascript-nes-emulator/">NES emulators</a>, <a href="http://matt.west.co.tt/spectrum/jsspeccy/">Spectrum emulators</a>, and even <a href="http://www.chiptune.com/">Amiga emulators</a>. But a Flash player?&hellip; What&#8217;s the point of emulating a browser plugin within a browser?</p>
<p>It&#8217;s not as bizarre as it sounds. There is one very good reason for a JavaScript-based player: the Flash plugin isn&#8217;t available on all platforms. Most notably, <a href="http://www.sitepoint.com/blogs/2010/02/02/ipad-vs-flash-developers-choose-wisely">you can&#8217;t run Flash on a iPhone</a> or <a href="http://www.sitepoint.com/blogs/2010/01/30/apple-ipad-transitional-or-trashy/">Apple&#8217;s new iPad</a>. </p>
<p>&#8220;<a href="http://github.com/tobeytailor/gordon"><strong>Gordon</strong></a>&#8221; is a cleverly-named project by <a href="http://github.com/tobeytailor">Tobias Schneider</a> which hopes to rectify the situation. It translates Flash SWF files to <a href="http://www.sitepoint.com/blogs/2010/01/08/9-reasons-why-svgs-are-important-for-the-web/">Scalable Vector Graphics</a> which are supported on the iPhone. The project <a href="http://wiki.github.com/tobeytailor/gordon/browser-support-table">runs on most modern browsers</a> with the exception of Internet Explorer (which doesn&#8217;t offer <a href="http://www.sitepoint.com/blogs/2010/01/07/internet-explorer-svg/">native SVG support &hellip; yet</a>).</p>
<p>Gordon currently supports the SWF 1.0 format and SWF 2.0 is in development. There are <a href="http://paulirish.com/work/gordon/demos/">several demonstrations</a> available and, although they&#8217;re simple, they work well and show the potential.</p>
<div id="adz" class="vertical"></div><p>Of course, all this work might be in vain if the real Flash plugin appears on the iPhone. But that seems fairly unlikely &#8212; Steve Jobs has little regard for Flash and states that it runs too slowly on the device. It&#8217;s also a competitor to the standard iPhone/iPad applications platform.</p>
<p>However, Gordon has been tested on the iPhone and it runs fast enough even though it&#8217;s built on interpreted JavaScript code. If the project becomes a success, there will be nothing Apple can do to prevent Flash running on the device. Could that provide developers with another reason to <a href="http://www.sitepoint.com/blogs/2010/01/27/7-reasons-developers-desert-iphone-apps/">desert iPhone applications</a>?</p>
<p>Have you tried Gordon? Could it ever be a viable alternative to the Flash plugin on unsupported browsers? Should Adobe hire the developer immediately?!</p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2010/02/02/ipad-vs-flash-developers-choose-wisely/' rel='bookmark' title='Permanent Link: iPad vs Flash: Developers, Choose Wisely'>iPad vs Flash: Developers, Choose Wisely</a> <small>The newly revealed Apple iPad offers no support for Flash....</small></li><li><a href='http://www.sitepoint.com/blogs/2010/02/11/adobe-apple-flash-criticism/' rel='bookmark' title='Permanent Link: Adobe Hits Back at Apple&#8217;s Criticism of Flash'>Adobe Hits Back at Apple&#8217;s Criticism of Flash</a> <small>Adobe's Kevin Lynch has hit back at Steve Jobs following...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/09/27/jsnes-javascript-nes-emulator/' rel='bookmark' title='Permanent Link: JSNES: a NES Emulator Written in JavaScript'>JSNES: a NES Emulator Written in JavaScript</a> <small>Just when you thought you'd seen everything in JavaScript, along...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=8ea6497fc7651e64565c839b20312a6a&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=8ea6497fc7651e64565c839b20312a6a&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2010/02/02/gordon-javascript-flash-player/feed/</wfw:commentRss>
			<slash:comments>20</slash:comments>
		</item>
		<item>
			<title>How to Fix Randomly Disappearing Absolutely-Positioned Elements in IE</title>
			<link>http://www.pheedcontent.com/click.phdo?i=ed44a997e59342086d1bd7b66260bb7b</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2010/01/21/fix-disappearing-absolute-position-element-ie/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2010/01/21/fix-disappearing-absolute-position-element-ie/#comments</comments>
			<pubDate>Thu, 21 Jan 2010 09:18:01 +0000</pubDate>
			<dc:creator>Craig Buckler</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<category><![CDATA[Web Tech]]></category>
			<category><![CDATA[absolute]]></category>
			<category><![CDATA[bugs]]></category>
			<category><![CDATA[css]]></category>
			<category><![CDATA[html]]></category>
			<category><![CDATA[ie]]></category>
			<category><![CDATA[ie6]]></category>
			<category><![CDATA[IE7]]></category>
			<category><![CDATA[ie8]]></category>
			<category><![CDATA[positioning]]></category>
			<category>absolute</category>
			<category>bugs</category>
			<category>css</category>
			<category>html</category>
			<category>ie</category>
			<category>positioning</category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=16077</guid>
			<description><![CDATA[IE may have some strange bugs but this one is stranger than most. Craig describes the nasty problem and provides a solution for disappearing absolutely-positioned elements which are time-dependent!


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/04/14/ie8-automatic-update/' rel='bookmark' title='Permanent Link: IE8 Automatic Update Starting Soon'>IE8 Automatic Update Starting Soon</a> <small>Internet Explorer 8.0 will shortly be rolled out to IE6...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/12/22/firefox-35-most-popular-browser/' rel='bookmark' title='Permanent Link: Firefox 3.5 is the World&#8217;s Most Popular Browser'>Firefox 3.5 is the World&#8217;s Most Popular Browser</a> <small>Firefox 3.5 has just overtaken IE7 to become the most...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/06/02/css-sizing-absolute-position/' rel='bookmark' title='Permanent Link: The Two Ways of Sizing Absolute Elements in CSS'>The Two Ways of Sizing Absolute Elements in CSS</a> <small>Most developers have used left, right, top and bottom properties...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=ed44a997e59342086d1bd7b66260bb7b&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=ed44a997e59342086d1bd7b66260bb7b&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img src="http://blogs.sitepointstatic.com/images/tech/212-ie6-missing-ap-elements.png" width="200" height="200" alt="IE6 and IE7 disappearing elements" class="imgright" />After 8 years, you&#8217;d have thought all <a href="http://www.sitepoint.com/blogs/2009/03/06/10-fixes-for-ie6-problems/">IE6&#8217;s bugs</a> would be well-documented and understood. Actually, after that time, you&#8217;d have hoped most of the issues would have been fixed in IE7 or IE8!</p>
<p>I was recently contacted by a frustrated developer who&#8217;d experienced disappearing absolutely-positioned elements in IE. The bug is quite bizarre, it&#8217;s not often you experience it, and there&#8217;s little information about it on the web. Hopefully, this article will go some way to rectifying that situation.</p>
<h2>The Problem</h2>
<p>Consider this layout:</p>
<p><img src="http://blogs.sitepointstatic.com/images/tech/212-ie6-missing-ap-elements-screen.png" width="400" height="300" alt="layout" class="imgcenter" style="display:block;margin:15px auto;" /></p>
<div id="adz" class="vertical"></div><p>The HTML elements are coded in the order specified, i.e. content blocks 1 and 2, header 3, right-hand block 4, and footer 5. The outer container is set to position: relative and all items have widths assigned so IE hasLayout. It may not be the most efficient layout but it&#8217;s valid and works in all browsers. Except IE6, IE7, and possibly IE8 &hellip; <em>sometimes</em>.</p>
<p>The first time you visit the page, IE can refuse to show the header. However, the header may re-appear when visiting a similarly-coded page on the same site. It can also re-appear when you return to the first page?</p>
<p>The problem is caused by an IE bug that hides an absolutely-positioned element when it&#8217;s coded immediately before or after a floated element (it&#8217;s next to a floated sibling). Unfortunately, this condition does not necessarily trigger the bug &#8212; it&#8217;s time dependent! The timing of the file downloads and the rendering speed affect whether it occurs or not. In my experience, the bug seemed less likely to occur if some files were cached.</p>
<p>So, here&#8217;s <a href="http://blogs.sitepointstatic.com/examples/tech/missing-ap/index.html"><strong>an example page</strong></a>. </p>
<p>Unfortunately, the bug is so inconsistent that it&#8217;s impossible to create one that&#8217;s guaranteed to work (or fail?)</p>
<p>On my local PC&#8217;s server, the header disappears in IE6, 7 and 8. On the SitePoint server, it only disappears in IE6 and 7. You may have a different experience.</p>
<p>In addition, <em>fake</em> IEs such as <a href="http://www.my-debugbar.com/wiki/IETester/HomePage">IETester</a> do not necessarily exhibit the same problem. I&#8217;d recommend using a <em>real</em> version of IE such as one within a VM (see <a href="http://articles.sitepoint.com/article/ie6-ie7-ie8-win7-xp-mode">Run IE6, IE7, and IE8 on the Same Machine Using Windows 7 XP Mode</a> or <a href="http://www.sitepoint.com/blogs/2009/11/20/ie6-ie7-ie8-windows-7-home/">How to Run IE6, IE7 and IE8 on Windows 7 HOME</a>).</p>
<h2>The Solution</h2>
<p>Fortunately, there is a quick and dirty solution: simply place an empty un-positioned static &lt;div&gt;&lt;/div&gt; immediately before and/or after the absolutely-positioned element. In the <a href="http://blogs.sitepointstatic.com/examples/tech/missing-ap/fixed.html">fixed example</a>, an empty &lt;div&gt;&lt;/div&gt; after the header prevents the problem occurring.</p>
<p>Semantic HTML devotees will be horrified but I&#8217;m afraid there doesn&#8217;t appear to be a CSS-only fix &hellip; unless anyone knows otherwise?</p>
<p>A better solution would be a more efficient layout without the absolutely-positioned header. Unfortunately, that can require a significant amount of code re-factoring if you haven&#8217;t tested IE early and often.</p>
<p>Have you experienced this strange bug before? Or have you given up on IE altogether?</p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/04/14/ie8-automatic-update/' rel='bookmark' title='Permanent Link: IE8 Automatic Update Starting Soon'>IE8 Automatic Update Starting Soon</a> <small>Internet Explorer 8.0 will shortly be rolled out to IE6...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/12/22/firefox-35-most-popular-browser/' rel='bookmark' title='Permanent Link: Firefox 3.5 is the World&#8217;s Most Popular Browser'>Firefox 3.5 is the World&#8217;s Most Popular Browser</a> <small>Firefox 3.5 has just overtaken IE7 to become the most...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/06/02/css-sizing-absolute-position/' rel='bookmark' title='Permanent Link: The Two Ways of Sizing Absolute Elements in CSS'>The Two Ways of Sizing Absolute Elements in CSS</a> <small>Most developers have used left, right, top and bottom properties...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=ed44a997e59342086d1bd7b66260bb7b&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=ed44a997e59342086d1bd7b66260bb7b&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2010/01/21/fix-disappearing-absolute-position-element-ie/feed/</wfw:commentRss>
			<slash:comments>29</slash:comments>
		</item>
		<item>
			<title>jQuery 1.4 Released</title>
			<link>http://www.pheedcontent.com/click.phdo?i=3e430ae7b746868f283d222db7c169f2</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2010/01/18/jquery-14-released/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2010/01/18/jquery-14-released/#comments</comments>
			<pubDate>Sun, 17 Jan 2010 17:43:07 +0000</pubDate>
			<dc:creator>Craig Buckler</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<category><![CDATA[javascript]]></category>
			<category><![CDATA[jquery]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=17189</guid>
			<description><![CDATA[jQuery 1.4 has been released. Craig looks at the new version of the web's most popular JavaScript framework.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/07/29/build-auto-expanding-textarea-1/' rel='bookmark' title='Permanent Link: How to Build an Auto-Expanding Textarea jQuery Plugin, Part 1'>How to Build an Auto-Expanding Textarea jQuery Plugin, Part 1</a> <small>Auto-expanding HTML textarea boxes have become popular on many web...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/04/21/make-your-own-web-site-badges-with-jquery-and-json/' rel='bookmark' title='Permanent Link: Make Your Own Web Site Badges with jQuery and JSON'>Make Your Own Web Site Badges with jQuery and JSON</a> <small>Now that most social media sites offer a JSON API,...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/07/30/build-auto-expanding-textarea-3/' rel='bookmark' title='Permanent Link: How to Build an Auto-Expanding Textarea jQuery Plugin, Part 3'>How to Build an Auto-Expanding Textarea jQuery Plugin, Part 3</a> <small>Auto-expanding HTML textarea boxes have become popular on many web...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=3e430ae7b746868f283d222db7c169f2&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=3e430ae7b746868f283d222db7c169f2&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img src="http://blogs.sitepointstatic.com/images/tech/241-jquery14.png" width="215" height="215" alt="jQuery 1.4" class="imgright" />It&#8217;s been some time coming, but jQuery 1.4 was released last week. Note that it&#8217;s not yet available from the main <a href="http://jquery.com/">jQuery website</a>, but you can find it at <a href="http://jquery14.com/day-01">jquery14.com</a>. Here are the main links if you&#8217;re eager to get your hands on it:</p>
<ul>
<li><a href="http://code.jquery.com/jquery-1.4.min.js">jQuery 1.4 minified</a> (23kb)</li>
<li><a href="http://code.jquery.com/jquery-1.4.js">jQuery 1.4 regular</a> (154kb)</li>
<li>Google-hosted: <a href="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js">http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js</a></li>
<li><a href="http://api.jquery.com/category/version/1.4/">jQuery 1.4 documentation</a></li>
</ul>
<h2>What&#8217;s New in jQuery 1.4?</h2>
<p>jQuery is probably the most popular JavaScript framework on the web. Many developers insert the script by habit (yes <a href="http://www.w3.org/">W3C.org</a>, I&#8217;m referring to you!), so the jQuery team needs to be extremely cautious when creating new releases.</p>
<div id="adz" class="vertical"></div><p>The code base has been heavily restructured to reduce complexity and increase performance. There are some impressive bar charts on <a href="http://jquery14.com/day-01">jquery14.com</a> which highlight how good the optimizations are.</p>
<p>207 bugs have been fixed and the framework now passes 100% of all tests in IE6, IE7, IE8, Firefox 2, Firefox 3, Firefox 3.5, Safari 3.2, Safari 4, Opera 10.10, and Chrome.</p>
<p>There is a substantial number of new methods and two new events: <code>focusin</code> and <code>focusout</code>. These are equivalent to focus and blur, but they implement an event bubbling-like technique (focus and blur do not normally bubble). For example, you can attach a handler to all your forms which is fired when any of the internal controls receive focus, e.g.</p>
<pre><code class="javascript">
$("form").focusin(function(event) {
	alert("event fired!");
});
</code></pre>
<p>Useful stuff.</p>
<h2>What Will Break If You Upgrade?</h2>
<p>The jQuery team has provided a <a href="http://jquery14.com/day-01#backwards">list of the most likely problems</a>. I suspect the following issues will cause the most confusion:</p>
<p><strong>1. jQuery() returns an empty set</strong><br />
In previous versions of the library, running <code>jQuery()</code> (no arguments) returned <code>jQuery(document)</code>. It now returns an empty set, although the <code>jQuery().ready()</code> event will still fire as expected.</p>
<p><strong>2. Ajax requests must use valid JSON</strong><br />
If you&#8217;re passing JSON data in Ajax calls, you must ensure it&#8217;s not malformed.jQuery now use the browser&#8217;s native <code>JSON.parser</code> in preference to <code>eval</code> when possible.</p>
<p><strong>3. jQuery.browser returns the engine version</strong><br />
If you&#8217;re sniffing for browsers, jQuery.browser now returns the rendering engine version rather than a specific browser type, e.g. &#8220;webkit&#8221; rather than &#8220;chrome&#8221;.</p>
<p>I mentioned how difficult user agent parsing had become in <a href="http://www.sitepoint.com/blogs/2009/05/31/why-browser-sniffing-stinks/">a previous post</a>. The jQuery developers have reduced complexity and increased speed by simplifying the returned information.</p>
<p>Although jQuery still supports browser-like detection, I strongly recommend you avoid it and use feature/object detection instead.</p>
<h2>Is jQuery 1.4 For You?</h2>
<p>If you&#8217;re after a solid JavaScript library, jQuery remains one of the obvious choices. It&#8217;s lightweight, functional, and supports the majority of modern browsers. For those upgrading from previous versions, it might be advisable to wait a few weeks to ensure there are no major problems.</p>
<p>Have you tried jQuery 1.4? Comments welcome.</p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/07/29/build-auto-expanding-textarea-1/' rel='bookmark' title='Permanent Link: How to Build an Auto-Expanding Textarea jQuery Plugin, Part 1'>How to Build an Auto-Expanding Textarea jQuery Plugin, Part 1</a> <small>Auto-expanding HTML textarea boxes have become popular on many web...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/04/21/make-your-own-web-site-badges-with-jquery-and-json/' rel='bookmark' title='Permanent Link: Make Your Own Web Site Badges with jQuery and JSON'>Make Your Own Web Site Badges with jQuery and JSON</a> <small>Now that most social media sites offer a JSON API,...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/07/30/build-auto-expanding-textarea-3/' rel='bookmark' title='Permanent Link: How to Build an Auto-Expanding Textarea jQuery Plugin, Part 3'>How to Build an Auto-Expanding Textarea jQuery Plugin, Part 3</a> <small>Auto-expanding HTML textarea boxes have become popular on many web...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=3e430ae7b746868f283d222db7c169f2&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=3e430ae7b746868f283d222db7c169f2&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2010/01/18/jquery-14-released/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		</item>
		<item>
			<title>Google Releases its JavaScript Closure Tools</title>
			<link>http://www.pheedcontent.com/click.phdo?i=9b0709b4f355f9d4b88d49568848c4fc</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2009/11/12/google-open-source-javascript-closure-library/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2009/11/12/google-open-source-javascript-closure-library/#comments</comments>
			<pubDate>Thu, 12 Nov 2009 07:52:52 +0000</pubDate>
			<dc:creator>Craig Buckler</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<category><![CDATA[google]]></category>
			<category><![CDATA[javascript]]></category>
			<category><![CDATA[library]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=15743</guid>
			<description><![CDATA[Do we need more JavaScript libraries and tools? Perhaps not, but since these power Google Search, GMail, Docs and Maps, they're worth another look.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/' rel='bookmark' title='Permanent Link: Google Closure: How not to write JavaScript'>Google Closure: How not to write JavaScript</a> <small>What if Google released a JavaScript library that sucked, and...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/11/16/sitepoint-roundup-1-rip-dan-schulz-google-closure-debate-and-the-podcast-turns-one/' rel='bookmark' title='Permanent Link: SitePoint Roundup #1: RIP Dan Schulz, Google Closure Debate, and the Podcast Turns One'>SitePoint Roundup #1: RIP Dan Schulz, Google Closure Debate, and the Podcast Turns One</a> <small>Is Dmitry Baranovskiy's critique of Closure valid, or just nitpicking?...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/07/26/bbc-glow-javascript-library/' rel='bookmark' title='Permanent Link: BBC Glow – a New JavaScript Library'>BBC Glow – a New JavaScript Library</a> <small>The British Broadcasting Corporation has released a new open source...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=9b0709b4f355f9d4b88d49568848c4fc&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=9b0709b4f355f9d4b88d49568848c4fc&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img src="http://blogs.sitepointstatic.com/images/tech/197-google-closure-tools.png" width="125" height="125" alt="Google Closure" class="imgright" />New JavaScript libraries and frameworks appear all the time, but it&#8217;s not every day that Google release the client-side code that powers Search, GMail, Google Maps, Google Docs, and more. The company has open-sourced their Closure Tools and they are now available to download from <a href="http://code.google.com/closure/">Google Code Labs</a>.</p>
<p>Three systems are provided for eager client-side developers:</p>
<h2>1. The Google Closure Compiler</h2>
<p>&#8220;Compiler&#8221; is a confusing term &#8212; this is a Java-powered JavaScript optimizer that reduces file sizes by removing dead code, renaming variables, and removing whitespace and comments. </p>
<div id="adz" class="vertical"></div><p>You can either:</p>
<ol>
<li><a href="http://code.google.com/p/closure-compiler/downloads/list">download the Closure Compiler</a>, or</li>
<li><a href="http://closure-compiler.appspot.com/">use the online Closure Compiler tool</a>.</li>
</ol>
<p>In my brief tests, a 28Kb JavaScript file was reduced to 15Kb (46% reduction) using &#8220;Simple&#8221; compression to remove white-space and comments. The reduction factor was almost identical to <a href="http://developer.yahoo.com/yui/compressor/">Yahoo&#8217;s YUI Compressor</a>. </p>
<p>&#8220;Advanced&#8221; compression with variable and function renaming reduced the file size to a little under 10Kb (64% reduction). The code continued to work correctly, although a couple JavaScript warnings were generated about uninitialized variables which were not evident in the uncompressed version.</p>
<p>The Closure Compiler is certainly worth trying if you want to speed up your web page&#8217;s download speeds. However, be careful to fully test the resulting JavaScript code.</p>
<h2>2. The Google Closure Library</h2>
<p>The <a href="http://code.google.com/closure/library/">Closure library</a> is an alternative to <a href="http://jquery.com/">jQuery</a> or the <a href="http://developer.yahoo.com/yui/">YUI Library</a>. The usual features are available, e.g. helper functions, Ajax, DOM manipulation, event handlers, CSS control, animation, effects, etc.</p>
<p>The code, comments, and <a href="http://closure-library.googlecode.com/svn/trunk/closure/goog/docs/index.html">documentation</a> are generally good, although I could not find information about browser support. Some of the examples are a little basic but I suspect they will be improved over time.</p>
<p><a href="http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/">Kevin Yank&#8217;s recent article</a> features comments from Dmitry Baranovskiy who has expressed concerns about the quality of the code. They are valid criticisms and I doubt the Closure will win over many jQuery aficionados, but choice is always a good thing and the library is will improve now it&#8217;s in the public domain.</p>
<h2>3. Google Closure Templates</h2>
<p><a href="http://code.google.com/closure/templates/">Closure Templates</a> is a templating system for client-side JavaScript and server-side Java. It&#8217;s a system that allows you to add small language-neutral components that create a full user interface.</p>
<p>Documentation is sparse and there are few examples. Server-side Java developers may adopt the system, but I&#8217;m not convinced it will appeal to ASP.NET or PHP developers.</p>
<p>Will you try Google&#8217;s Closure Tools? Or has the choice of tools become so bewildering you&#8217;ll stick with what you know?</p>
<p>See also: <a href="http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/">Google Closure: How not to write JavaScript</a></p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/' rel='bookmark' title='Permanent Link: Google Closure: How not to write JavaScript'>Google Closure: How not to write JavaScript</a> <small>What if Google released a JavaScript library that sucked, and...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/11/16/sitepoint-roundup-1-rip-dan-schulz-google-closure-debate-and-the-podcast-turns-one/' rel='bookmark' title='Permanent Link: SitePoint Roundup #1: RIP Dan Schulz, Google Closure Debate, and the Podcast Turns One'>SitePoint Roundup #1: RIP Dan Schulz, Google Closure Debate, and the Podcast Turns One</a> <small>Is Dmitry Baranovskiy's critique of Closure valid, or just nitpicking?...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/07/26/bbc-glow-javascript-library/' rel='bookmark' title='Permanent Link: BBC Glow – a New JavaScript Library'>BBC Glow – a New JavaScript Library</a> <small>The British Broadcasting Corporation has released a new open source...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=9b0709b4f355f9d4b88d49568848c4fc&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=9b0709b4f355f9d4b88d49568848c4fc&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/11/12/google-open-source-javascript-closure-library/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		</item>
		<item>
			<title>Google Closure: How not to write JavaScript</title>
			<link>http://www.pheedcontent.com/click.phdo?i=6a00fd034f6a8cf464e2d9fbb83dc321</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/#comments</comments>
			<pubDate>Thu, 12 Nov 2009 03:38:19 +0000</pubDate>
			<dc:creator>Kevin Yank</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<category>development</category>
			<category>Google</category>
			<category>JavaScript</category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=15780</guid>
			<description><![CDATA[What if Google released a JavaScript library that sucked, and no one noticed? JavaScript expert Dmitry Baranovskiy has peeked under the hood of Google’s new Closure Library, and he doesn’t like what he sees. Follow along as he points out a few of the library’s many failings, and why the Web deserves better from Google.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/11/12/google-open-source-javascript-closure-library/' rel='bookmark' title='Permanent Link: Google Releases its JavaScript Closure Tools'>Google Releases its JavaScript Closure Tools</a> <small>Do we need more JavaScript libraries and tools? Perhaps not,...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/09/03/javascript-session-variable-library/' rel='bookmark' title='Permanent Link: How to Write a Cookie-less Session Library for JavaScript'>How to Write a Cookie-less Session Library for JavaScript</a> <small>Craig provides the code for a stand-alone JavaScript session variable...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/10/21/javascript-object-instances/' rel='bookmark' title='Permanent Link: Fixing Object Instances in JavaScript'>Fixing Object Instances in JavaScript</a> <small>Even experienced coders can get caught out by object handling...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=6a00fd034f6a8cf464e2d9fbb83dc321&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=6a00fd034f6a8cf464e2d9fbb83dc321&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p>At the <a href="http://www.edgeoftheweb.org.au/">Edge of the Web</a> conference in Perth last week I got to catch up with <a href="http://dmitry.baranovskiy.com/">Dmitry Baranovskiy</a>, the creator of the <a href="http://raphaeljs.com/">Raphaël</a> and <a href="http://g.raphaeljs.com/">gRaphaël</a> JavaScript libraries. Perhaps the most important thing these libraries do is make sophisticated vector graphics possible in Internet Explorer, where JavaScript performance is relatively poor. Dmitry, therefore, has little patience for poorly-written JavaScript like the code he found in Google’s just-released <a href="http://googlecode.blogspot.com/2009/11/introducing-closure-tools.html">Closure Library</a>.</p>
<p>Having delivered a talk on <a href="http://www.slideshare.net/Dmitry.Baranovskiy/your-javascript-library">how to write your own JavaScript library</a> (<a href="http://passingcuriosity.com/2009/notes-on-dmitry-baranovskiys-talk-on-your-javascript-library/">detailed notes</a>) at the conference, Dmitry shared his thoughts on the new library over breakfast the next morning. “Just what the world needs—another sucky JavaScript library,” he said. When I asked him what made it ‘sucky’, he elaborated. “It’s a JavaScript library written by Java developers who clearly don’t <em>get</em> JavaScript.”</p>
<p>For the rest of the day, to anyone who would listen, Dmitry cited example after example of the terrible code he had found when he went digging through Closure. His biggest fear, he told me, was that people would switch from truly excellent JavaScript libraries like <a href="http://jquery.com/">jQuery</a> to Closure on the strength of the Google name.</p>
<p>“I’ll make you a deal,” I told him. “Send me some examples of this terrible code and I’ll publish it on SitePoint.”</p>
<h2>The Slow Loop</h2>
<p>From <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/array/array.js?r=2">array.js</a>, line 63:</p>
<pre><code class="javascript">for (var i = fromIndex; i &lt; arr.length; i++) {</code></pre>
<p>This <code>for</code> loop looks up the <code>.length</code> property of the array (<code>arr</code>) each time through the loop. Simply by setting a variable to store this number at the start of the loop, you can make the loop run much faster:</p>
<pre><code class="javascript">for (var i = fromIndex, ii = arr.length; i &lt; ii; i++) {</code></pre>
<p>Google’s developers seem to have figured this trick out later on in the same file. From <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/array/array.js?r=2">array.js</a>, line 153:</p>
<pre><code class="javascript">var l = arr.length;  // must be fixed during loop... see docs
⋮
for (var i = l - 1; i >= 0; --i) {</code></pre>
<p>This loop is better in that it avoids a property lookup each time through the loop, but this particular <code>for</code> loop is so simple that it could be further simplified into a <code>while</code> loop, which will run much faster again:</p>
<pre><code class="javascript">var i = arr.length;
⋮
while (i--) {</code></pre>
<p>But not all of Closure Library’s performance woes are due to poorly optimized loops. From <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/dom/dom.js?r=2">dom.js</a>, line 797:</p>
<pre><code class="javascript">switch (node.tagName) {
  case goog.dom.TagName.APPLET:
  case goog.dom.TagName.AREA:
  case goog.dom.TagName.BR:
  case goog.dom.TagName.COL:
  case goog.dom.TagName.FRAME:
  case goog.dom.TagName.HR:
  case goog.dom.TagName.IMG:
  case goog.dom.TagName.INPUT:
  case goog.dom.TagName.IFRAME:
  case goog.dom.TagName.ISINDEX:
  case goog.dom.TagName.LINK:
  case goog.dom.TagName.NOFRAMES:
  case goog.dom.TagName.NOSCRIPT:
  case goog.dom.TagName.META:
  case goog.dom.TagName.OBJECT:
  case goog.dom.TagName.PARAM:
  case goog.dom.TagName.SCRIPT:
  case goog.dom.TagName.STYLE:
    return false;
}
return true;</code></pre>
<p>This kind of code is actually pretty common in Java, and will perform just fine there. In JavaScript, however, this <code>switch</code> statement will perform like a dog each and every time a developer checks if a particular HTML element is allowed to have children.</p>
<p>Experienced JavaScript developers know that it’s much quicker to create an object to encapsulate this logic:</p>
<pre><code class="javascript">var takesChildren = {}
takesChildren[goog.dom.TagName.APPLET] = 1;
takesChildren[goog.dom.TagName.AREA] = 1;
⋮</code></pre>
<p>With that object set up, the function to check if a tag accepts children can run much quicker:</p>
<pre><code class="javascript">return !takesChildren[node.tagName];</code></pre>
<p>This code can be further bulletproofed against outside interference using <code>hasOwnProperty</code> (see below for a full explanation of this).</p>
<pre><code class="javascript">return !takesChildren.hasOwnProperty(node.tagName);</code></pre>
<p>If there’s one thing we expect from Google it’s a focus on performance. Heck, Google released its own browser, Google Chrome, primarily to take JavaScript performance to the next level!</p>
<p>Seeing code like this, one has to wonder if Google could have achieved the same thing by teaching its engineers to write better JavaScript code.</p>
<h2>Six Months in a Leaky Boat</h2>
<p>It would be unfair to suggest that Google has <em>ignored</em> performance in building Closure. In fact, the library provides a generic method for caching the results of functions that run slowly, but which will always return the same result for a given set of arguments. From <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/memoize/memoize.js?r=2">memoize.js</a>, line 39:</p>
<pre><code class="javascript">goog.memoize = function(f, opt_serializer) {
  var functionHash = goog.getHashCode(f);
  var serializer = opt_serializer || goog.memoize.simpleSerializer;
  
  return function() {
    // Maps the serialized list of args to the corresponding return value.
    var cache = this[goog.memoize.CACHE_PROPERTY_];
    if (!cache) {
      cache = this[goog.memoize.CACHE_PROPERTY_] = {};
    }
    var key = serializer(functionHash, arguments);
    if (!(key in cache)) {
      cache[key] = f.apply(this, arguments);
    }
    return cache[key];
  };
};</code></pre>
<p>This is a clever performance trick employed in a number of major JavaScript libraries; the problem is, Google has not provided any means of limiting the size of the cache! This is fine if a cached function is only ever called with a small collection of different arguments, but this is a dangerous assumption to make in general.</p>
<div id="adz" class="vertical"></div><p>Used to cache a function’s results based on, say, the coordinates of the mouse pointer, this code’s memory footprint will rapidly grow out of control, and slow the browser to a crawl.</p>
<p>In Dmitry’s words, “I’m not sure what this pattern is called in Java, but in JavaScript it’s called a ‘memory leak’.”</p>
<h2>Code in a Vacuum</h2>
<p>In his talk on building JavaScript libraries, Dmitry compared JavaScript’s global scope to a public toilet. “You can’t avoid going in there,” he said. “But try to limit your contact with surfaces when you do.”</p>
<p>For a general-purpose JavaScript library to be reliable, it must not only avoid interfering with any other JavaScript code that might be running alongside it, but it must also protect itself from other scripts that aren’t so polite. </p>
<p>From <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/object/object.js?r=2">object.js</a>, line 31:</p>
<pre><code class="javascript">goog.object.forEach = function(obj, f, opt_obj) {
  for (var key in obj) {
    f.call(opt_obj, obj[key], key, obj);
  }
};</code></pre>
<p><code>for</code>-<code>in</code> loops like this one are inherently dangerous in JavaScript libraries, because you never know what other JavaScript code might be running in the page, and what it might have added to JavaScript’s standard <code>Object.prototype</code>.</p>
<p><code>Object.prototype</code> is the JavaScript object that contains the properties shared by all JavaScript objects. Add a new function to <code>Object.prototype</code>, and every JavaScript object running in the page will have that function added to it—even if it was created beforehand! Early JavaScript libraries like <a href="http://www.prototypejs.org/">Prototype</a> made a big deal of adding all sorts of convenience features to <code>Object.prototype</code>.</p>
<p>Unfortunately, unlike the built-in properties supplied by <code>Object.prototype</code>, custom properties added to <code>Object.prototype</code> will show up as an object property in any <code>for</code>-<code>in</code> loop in the page.</p>
<p>In short, Closure Library cannot coexist with any JavaScript code that adds features to <code>Object.prototype</code>.</p>
<p>Google could have made its code more robust by using <code>hasOwnProperty</code> to check each item in the <code>for</code>-<code>in</code> loop to be sure it belongs to the object itself:</p>
<pre><code class="javascript">goog.object.forEach = function(obj, f, opt_obj) {
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      f.call(opt_obj, obj[key], key, obj);
    }
  }
};</code></pre>
<p>Here’s another especially fragile bit of Closure Library. From <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/base.js?r=2">base.js</a>, line 677:</p>
<pre><code class="javascript">goog.isDef = function(val) {
 return val !== undefined;
};</code></pre>
<p>This function checks if a particular variable has a value defined. Or it does, unless a 3rd party script sets the global <code>undefined</code> variable to something else. This single line of code anywhere in the page will bring Closure Library crashing down:</p>
<pre><code class="javascript">var undefined = 5;</code></pre>
<p>Relying on the global <code>undefined</code> variable is another rookie mistake for JavaScript library authors.</p>
<p>You might think that anyone who assigns a value to <code>undefined</code> deserves what they get, but the fix in this case is trivial: simply declare a local <code>undefined</code> variable for use within the function!</p>
<pre><code class="javascript">goog.isDef = function(val) {
  var undefined;
  return val !== undefined;
};</code></pre>
<h2>Typical Confusion</h2>
<p>One of the most confusing aspects of JavaScript for developers coming from other languages is its system of data types. Closure Library contains plenty of bloopers that further reveal that its authors lack extensive experience with the finer points of JavaScript.</p>
<p>From <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/string/string.js?r=2">string.js</a>, line 97:</p>
<pre><code class="javascript">// We cast to String in case an argument is a Function. …
var replacement = String(arguments[i]).replace(…);</code></pre>
<p>This code converts <code>arguments[i]</code> to a string object using the <code>String</code> conversion function. This is possibly the slowest way to perform such a conversion, although it would be the most obvious to many developers coming from other languages.</p>
<p>Much quicker is to add an empty string (<code>""</code>) to the value you wish to convert:</p>
<pre><code class="javascript">var replacement = (arguments[i] + "").replace(…);</code></pre>
<p>Here’s some more string-related type confusion. From <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/base.js?r=2">base.js</a>, line 742:</p>
<pre><code class="javascript">goog.isString = function(val) {
  return typeof val == 'string';
};</code></pre>
<p>JavaScript actually represents text strings in two different ways—as primitive string values, and as string objects:</p>
<pre><code class="javascript">var a = "I am a string!";
alert(typeof a); // Will output "string"
var b = new String("I am also a string!");
alert(typeof b); // Will output "object"</code></pre>
<p>Most of the time strings are efficiently represented as primitive values (<code>a</code> above), but to call any of the built-in methods on a string (e.g. <code>toLowerCase</code>) it must first be converted to a string object (<code>b</code> above). JavaScript converts strings back and forth between these two representations automatically as needed. This feature is called “autoboxing”, and appears in many other languages.</p>
<p>Unfortunately for Google’s Java-savvy developers, Java only ever represents strings as objects. That’s my best guess for why Closure Library overlooks the second type of string in JavaScript:</p>
<pre><code class="javascript">var b = new String("I am also a string!");
alert(goog.isString(b)); // Will output FALSE</code></pre>
<p>Here’s another example of Java-inspired type confusion. From <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/color/color.js?r=2">color.js</a>, line 633:</p>
<pre><code class="javascript">return [
  Math.round(factor * rgb1[0] + (1.0 - factor) * rgb2[0]),
  Math.round(factor * rgb1[1] + (1.0 - factor) * rgb2[1]),
  Math.round(factor * rgb1[2] + (1.0 - factor) * rgb2[2])
];</code></pre>
<p>Those <code>1.0</code>s are telling. Languages like Java represent integers (<code>1</code>) differently from floating point numbers (<code>1.0</code>). In JavaScript, however, numbers are numbers. <code>(1 - factor)</code> would have worked just as well.</p>
<p>Yet another example of JavaScript code with a whiff of Java about it can be seen in <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/fx/fx.js?r=2">fx.js</a>, line 465:</p>
<pre><code class="javascript">goog.fx.Animation.prototype.updateCoords_ = function(t) {
  this.coords = new Array(this.startPoint.length);
  for (var i = 0; i < this.startPoint.length; i++) {
    this.coords[i] = (this.endPoint[i] - this.startPoint[i]) * t +
        this.startPoint[i];
  }
};</code></code></pre>
<p>See how they create an array on the second line?</p>
<pre><code class="javascript">this.coords = new Array(this.startPoint.length);</code></pre>
<p>Although it is necessary in Java, it is entirely pointless to specify the length of an array ahead of time in JavaScript. It would make just as much sense to create a new variable for storing numbers with <code>var i = new Number(0);</code> instead of <code>var i = 0;</code>.</p>
<p>Rather, you can just set up an empty array and allow it to grow as you fill it in. Not only is the code shorter, but it runs faster too:</p>
<pre><code class="javascript">this.coords = [];</code></pre>
<p>Oh, and did you spot yet another inefficient <code>for</code> loop in that function?</p>
<h2>API Design</h2>
<p>If all the low-level code quality nitpicks above don’t convince you, I defy you to try using some of the APIs Google has built into Closure Library.</p>
<p>Closure’s <a href="http://closure-library.googlecode.com/svn/trunk/closure/goog/docs/closure_goog_graphics_graphics.js.html">graphics classes</a>, for example, are modeled around the <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html">HTML5 canvas API</a>, which is about what you’d expect from a JavaScript API designed by an HTML standards body. In short, it’s repetitive, inefficient, and downright unpleasant to code against.</p>
<p>As the author of <a href="http://raphaeljs.com/">Raphaël</a> and <a href="http://g.raphaeljs.com/">gRaphaël</a>, Dmitry has plenty of experience designing usable JavaScript APIs. If you want to grasp the full horror of the canvas API (and by extension, Closure’s graphics API), check out the audio and slides from <a href="http://www.webdirections.org/resources/dmitry-baranovskiy-canvas/">Dmitry’s Web Directions South 2009 talk</a> on the subject.</p>
<h2>Google’s Responsibility to Code Quality</h2>
<p>By this point I hope you’re convinced that Closure Library is not a shining example of the best JavaScript code the Web has to offer. If you’re looking for that, might I recommend more established players like <a href="http://jquery.com/">jQuery</a>?</p>
<p>But you might be thinking “So what? Google can release crappy code if it wants to—nobody’s forcing <em>you</em> to use it.” And if this were a personal project released by some googler on the side under his or her own name, I’d agree with you, but Google has endorsed Closure Library by stamping it with the Google brand.</p>
<p>The truth is, developers <em>will</em> switch to Closure because it bears the Google name, and that’s the real tragedy here. Like it or not, Google is a trusted name in the development community, and it has a responsibility to that community to do a little homework before deciding a library like Closure deserves public exposure.</p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/11/12/google-open-source-javascript-closure-library/' rel='bookmark' title='Permanent Link: Google Releases its JavaScript Closure Tools'>Google Releases its JavaScript Closure Tools</a> <small>Do we need more JavaScript libraries and tools? Perhaps not,...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/09/03/javascript-session-variable-library/' rel='bookmark' title='Permanent Link: How to Write a Cookie-less Session Library for JavaScript'>How to Write a Cookie-less Session Library for JavaScript</a> <small>Craig provides the code for a stand-alone JavaScript session variable...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/10/21/javascript-object-instances/' rel='bookmark' title='Permanent Link: Fixing Object Instances in JavaScript'>Fixing Object Instances in JavaScript</a> <small>Even experienced coders can get caught out by object handling...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=6a00fd034f6a8cf464e2d9fbb83dc321&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=6a00fd034f6a8cf464e2d9fbb83dc321&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/feed/</wfw:commentRss>
			<slash:comments>119</slash:comments>
		</item>
		<item>
			<title>Video: CSS Frameworks – Make the Right Choice</title>
			<link>http://www.pheedcontent.com/click.phdo?i=2bacd1eaa18f45cd6961f62fd142be39</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2009/11/10/video-css-frameworks-%e2%80%93-make-the-right-choice/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2009/11/10/video-css-frameworks-%e2%80%93-make-the-right-choice/#comments</comments>
			<pubDate>Tue, 10 Nov 2009 08:11:00 +0000</pubDate>
			<dc:creator>Kevin Yank</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<category>CSS</category>
			<category>video</category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=15746</guid>
			<description><![CDATA[Choose the right framework and you’ll save yourself a lot of work. Choose the wrong one, and you’ll find your projects weighed down by restrictive assumptions and masses of code that you don’t understand. When it comes to CSS frameworks, making the right choice is everything.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/10/06/css-frameworks-semantic-class-names/' rel='bookmark' title='Permanent Link: CSS Frameworks and Semantic Class Names'>CSS Frameworks and Semantic Class Names</a> <small>CSS frameworks often contain crufty, non-semantic code. Does it have...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/10/09/win-signed-sitepoint-books-at-web-directions-south/' rel='bookmark' title='Permanent Link: Win Signed SitePoint Books at Web Directions South'>Win Signed SitePoint Books at Web Directions South</a> <small>If you're at the Web Directions South conference in Sydney...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/06/16/first-look-object-oriented-css/' rel='bookmark' title='Permanent Link: First Look: Object Oriented CSS'>First Look: Object Oriented CSS</a> <small>Nicole Sullivan's Object Oriented CSS aims to make your styles...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=2bacd1eaa18f45cd6961f62fd142be39&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=2bacd1eaa18f45cd6961f62fd142be39&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p>In the past couple of months, I have had the great pleasure of presenting a talk entitled “CSS Frameworks: Make the Right Choice” at both of Australia’s premier web design conferences: <a href="http://south09.webdirections.org/">Web Directions South 2009</a> and <a href="http://www.edgeoftheweb.org.au/">Edge of the Web 2009</a>.</p>
<p>Of course, even the most dedicated SitePoint fan could find it hard to justify a trip to Australia to see me speak; thankfully, the folks at Web Directions were kind enough to share the audio recorded at the event under a Creative Commons license that enables me to share it with you in a richer format.</p>
<p>I am delighted, therefore, to present this video re-creation of the talk including my animated slides, a screencast video demo, and the audio recorded live at Web Directions South 2009. Be sure to visit <a href="http://www.webdirections.org/">the Web Directions site</a> for the accumulated audio and slides from the entire conference series!</p>
<p><object width="640" height="480"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=7530607&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=7530607&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="640" height="480"></embed></object>
<p><a href="http://vimeo.com/7530607">CSS Frameworks: Make the Right Choice (WDS09)</a> from <a href="http://vimeo.com/sitepoint">SitePoint Staff</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
<div id="adz" class="vertical"></div><blockquote>
<p>SitePoint CTO Kevin Yank presented this talk at Web Directions South 2009 in Sydney, Australia on Friday, October 9th, 2009.</p>
<p>With the proliferation and widespread adoption of JavaScript frameworks, smart developers have wondered if a similar approach to smoothing over the rough spots of CSS might work. Thus, CSS frameworks like Blueprint, YUI Library CSS Tools, Boilerplate, and many others were born. In this session, we will survey the landscape of CSS frameworks and consider how each of them deals with the unique challenge of creating generalised, reusable CSS styles.</p>
<p>There are a number of different approaches, and some are better than others. Choose the right framework and you’ll save yourself a lot of work. Choose the wrong one, and you’ll find your projects weighed down by restrictive assumptions and masses of code that you don’t understand. When it comes to CSS frameworks, making the right choice is everything. By the end of this session, you might just decide that the right framework for you is no framework at all.</p>
</blockquote>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/10/06/css-frameworks-semantic-class-names/' rel='bookmark' title='Permanent Link: CSS Frameworks and Semantic Class Names'>CSS Frameworks and Semantic Class Names</a> <small>CSS frameworks often contain crufty, non-semantic code. Does it have...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/10/09/win-signed-sitepoint-books-at-web-directions-south/' rel='bookmark' title='Permanent Link: Win Signed SitePoint Books at Web Directions South'>Win Signed SitePoint Books at Web Directions South</a> <small>If you're at the Web Directions South conference in Sydney...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/06/16/first-look-object-oriented-css/' rel='bookmark' title='Permanent Link: First Look: Object Oriented CSS'>First Look: Object Oriented CSS</a> <small>Nicole Sullivan's Object Oriented CSS aims to make your styles...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=2bacd1eaa18f45cd6961f62fd142be39&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=2bacd1eaa18f45cd6961f62fd142be39&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/11/10/video-css-frameworks-%e2%80%93-make-the-right-choice/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		</item>
		<item>
			<title>Fixing Object Instances in JavaScript</title>
			<link>http://www.pheedcontent.com/click.phdo?i=0db6ca4b30c8a06738f901a20f546712</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2009/10/21/javascript-object-instances/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2009/10/21/javascript-object-instances/#comments</comments>
			<pubDate>Tue, 20 Oct 2009 15:59:34 +0000</pubDate>
			<dc:creator>Craig Buckler</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<category><![CDATA[javascript]]></category>
			<category>javascript</category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=15206</guid>
			<description><![CDATA[Even experienced coders can get caught out by object handling in JavaScript, and handing your code to other developers can intensify problems. Craig looks at the problem of creating object instances and provides a quick solution.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/' rel='bookmark' title='Permanent Link: Cross-browser JSON Serialization in JavaScript'>Cross-browser JSON Serialization in JavaScript</a> <small>JSON serialization can be incredibly useful, but few browsers support...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/07/01/javascript-truthy-falsy/' rel='bookmark' title='Permanent Link: Truthy and Falsy: When All is Not Equal in JavaScript'>Truthy and Falsy: When All is Not Equal in JavaScript</a> <small>Anything in JavaScript can be considered to be either truthy...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/' rel='bookmark' title='Permanent Link: Google Closure: How not to write JavaScript'>Google Closure: How not to write JavaScript</a> <small>What if Google released a JavaScript library that sucked, and...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=0db6ca4b30c8a06738f901a20f546712&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=0db6ca4b30c8a06738f901a20f546712&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img class="imgright" src="http://blogs.sitepointstatic.com/images/tech/179-js-object-instance.jpg" alt="JavaScript objects" width="190" height="190" />Do you know your JavaScript? Take a look at the following code sample and work out what value is shown in the final alert statement …</p>
<pre><code class="javascript">
// object constructor
function ObjectConstructor(a, b, c) {

	this.A = a;
	this.B = b;
	this.C = c;
	this.Total = a + b + c;

}

var obj = ObjectConstructor(1, 2, 3);

alert(obj.Total);
</code></pre>
<p>Hands up everyone who answered &#8220;6.&#8221;</p>
<p>Sorry, you&#8217;re wrong. The answer is … nothing &#8212; or an error stating that &#8216;obj&#8217; is undefined. So what&#8217;s gone wrong?</p>
<p>The simple answer is that we&#8217;ve forgotten the &#8216;new&#8217; operator so an object instance is never created. The statement should be:</p>
<div id="adz" class="horizontal"></div><pre><code class="javascript">
var obj = new ObjectConstructor(1, 2, 3);
</code></pre>
<p>It&#8217;s an easy mistake to make. Novice developers are unlikely to spot the missing operator because the code looks almost identical. Even experienced coders could find it tough to debug (especially since many assume JavaScript is a <a href="http://en.wikipedia.org/wiki/Procedural_language">procedural programming language</a> … which it can be, if you choose to write it that way).</p>
<p>The main problem is that <code>var obj = ObjectConstructor(1, 2, 3);</code> is a perfectly valid JavaScript statement and the interpretor engine will not throw an error. In that context, the value of obj is set to the value returned from the function ObjectConstructor; since no value is returned, obj remains &#8220;undefined&#8221; (a top-level JavaScript property).</p>
<p>This is unlikely to become a major problem if you&#8217;re developing, testing and debugging your own code. However, it could be a different matter when you&#8217;re providing a library or API to thousands of third-party developers. At some point, someone, somewhere, will miss that &#8216;new&#8217; operator and they will blame your code rather than theirs.</p>
<p>Fortunately, JavaScript is a flexible language. We can fix our constructor so an object is correctly created even when the &#8216;new&#8217; operator is omitted:</p>
<pre><code class="javascript">
// object constructor
function ObjectConstructor(a, b, c) {

	if (!(this instanceof arguments.callee)) {
		return new ObjectConstructor(a, b, c);
	}

	this.A = a;
	this.B = b;
	this.C = c;
	this.Total = a + b + c;

}
</code></pre>
<p>The additional &#8216;if&#8217; statement at the top of the constructor checks whether &#8216;this&#8217; is an instance of the object and returns one if necessary. The code <code>var obj = ObjectConstructor(1, 2, 3);</code> will now set obj to an object instance and &#8220;6&#8243; will be output by the alert statement.</p>
<p>Have you ever encountered this problem in your code or when using another library?</p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=horizontal" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/' rel='bookmark' title='Permanent Link: Cross-browser JSON Serialization in JavaScript'>Cross-browser JSON Serialization in JavaScript</a> <small>JSON serialization can be incredibly useful, but few browsers support...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/07/01/javascript-truthy-falsy/' rel='bookmark' title='Permanent Link: Truthy and Falsy: When All is Not Equal in JavaScript'>Truthy and Falsy: When All is Not Equal in JavaScript</a> <small>Anything in JavaScript can be considered to be either truthy...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/' rel='bookmark' title='Permanent Link: Google Closure: How not to write JavaScript'>Google Closure: How not to write JavaScript</a> <small>What if Google released a JavaScript library that sucked, and...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=0db6ca4b30c8a06738f901a20f546712&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=0db6ca4b30c8a06738f901a20f546712&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/10/21/javascript-object-instances/feed/</wfw:commentRss>
			<slash:comments>23</slash:comments>
		</item>
		<item>
			<title>CSS Frameworks and Semantic Class Names</title>
			<link>http://www.pheedcontent.com/click.phdo?i=adadb8e65cb945f6761aac2a903d57d7</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2009/10/06/css-frameworks-semantic-class-names/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2009/10/06/css-frameworks-semantic-class-names/#comments</comments>
			<pubDate>Mon, 05 Oct 2009 23:17:53 +0000</pubDate>
			<dc:creator>Kevin Yank</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<category>CSS</category>
			<category>design</category>
			<category>frameworks</category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=14814</guid>
			<description><![CDATA[CSS frameworks often contain crufty, non-semantic code. Does it have to be that way? Kevin shows us how semantic markup and CSS frameworks can coexist happily.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/11/10/video-css-frameworks-%e2%80%93-make-the-right-choice/' rel='bookmark' title='Permanent Link: Video: CSS Frameworks – Make the Right Choice'>Video: CSS Frameworks – Make the Right Choice</a> <small>Choose the right framework and you’ll save yourself a lot...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/01/12/how-semantic-markup-helps-server-side-developers-write-reusable-code/' rel='bookmark' title='Permanent Link: How Semantic Markup Helps Server-side Developers Write Reusable Code'>How Semantic Markup Helps Server-side Developers Write Reusable Code</a> <small>As front-end developers, we know how much easier maintenance, testing,...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/03/31/techy-treasures-5-fudging-css-counters-in-internet-explorer/' rel='bookmark' title='Permanent Link: Techy Treasures #5: Fudging CSS Counters in Internet Explorer'>Techy Treasures #5: Fudging CSS Counters in Internet Explorer</a> <small>CSS Counters are a useful but under-used feature of CSS2...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=adadb8e65cb945f6761aac2a903d57d7&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=adadb8e65cb945f6761aac2a903d57d7&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img class="imgright size-thumbnail wp-image-14817" title="CSS Dozer" src="http://www.sitepoint.com/blogs/wp-content/uploads/2009/10/dozer-150x150.png" alt="A bulldozer pushing the letters C S S" width="150" height="150" /></p>
<p><strong>One of the most common complaints about CSS frameworks like <a href="http://blueprintcss.org/">Blueprint</a>, <a href="http://developer.yahoo.com/yui/grids/">YUI Grids</a>, and <a href="http://960.gs/">960.gs</a> is that they require designers to dirty their fingers by adding presentational class names to their HTML documents, like so:</strong></p>
<pre><code>&lt;div class="span-9 last"&gt;
&lt;div class="grid_6 alpha"&gt;</code></pre>
<p>Class names like <code>"span-9"</code> really bother designers who care about the quality of their HTML code, because they describe the <strong>appearance</strong> of an element; this should really be left to the CSS properties defined in your site&#8217;s style sheets. The problem with presentational class names is explained especially well by the W3C QA tip, <a href="http://www.w3.org/QA/Tips/goodclassnames"><cite>Use <code>class</code> with semantics in mind</cite></a>:</p>
<blockquote cite="http://www.w3.org/QA/Tips/goodclassnames"><p><strong>Good names don&#8217;t change.</strong> Think about <em>why</em> you want something to look a certain way, and not really about <em>how</em> it should look. Looks can always change, but the reasons for giving something a look stay the same.</p></blockquote>
<div id="adz" class="vertical"></div><p>Maybe you&#8217;re the pragmatic type who takes no issue with this sort of thing, or decides that it&#8217;s a necessary evil given the limitations of the CSS language. Nevertheless, there are plenty of front-end ninjas out there who refuse to use CSS frameworks for this very reason.</p>
<p>It turns out, however, that the latest crop of CSS frameworks provide clever solutions to the problem of presentational class names.</p>
<p><a href="http://blueprintcss.org/">Blueprint CSS</a>, the granddaddy of CSS layout frameworks, now includes a clever Ruby script called compress.rb in its download package. In <a href="http://www.jdclayton.com/blueprints_compress_a_walkthrough.html"><cite>Blueprint&#8217;s compress.rb: A Walkthrough</cite></a>, Blueprint author Joshua Clayton explains how to use the script to generate a custom version of the Blueprint style sheets using your own semantic class names.</p>
<p>The process boils down to writing a simple configuration file that tells the script how to map Blueprint&#8217;s presentational class names to your own semantically meaningful class names. The file will look like this:</p>
<pre><code>demo:
  path: /Users/kyank/Documents/myproject
  semantic_classes:
    ".header, .footer": ".span-24, div.span-24"
    ".content": ".span-18, div.span-18"
    ".sidebar": ".span-6, div.span-6,
                 .last, div.last"</code></pre>
<p>The <code>semantic_classes</code> section provides the mapping. In this example, the <code>header</code> and <code>footer</code> classes will be 24 grid units wide and the <code>content</code> class will be 18 grid units wide. The <code>sidebar</code> class will be 6 grid units wide and the last block in its row.</p>
<p>With this configuration file written, you simply run the compress.rb script, and the customized version of the Blueprint style sheet files (screen.css, print.css, and ie.css) will be generated in the specified path. The style sheet will contain rules like this one, that apply the grid dimensions to your custom class names:</p>
<pre><code>/* semantic class names */
.content {float:left;margin-right:10px;
  width:710px;}</code></pre>
<p>&#8230; and just like that, you gain all the layout facilities of Blueprint CSS with none of the HTML cruft!</p>
<p>If manually compiling your style sheets with a Ruby script sounds like a bit of a pain (which it can be &#8212; especially if you develop on a Windows computer without Ruby installed), a server-side CSS framework might be a better option for you.</p>
<p>CSS frameworks are popping up for all the major server-side programming languages. Two prominent examples include <a href="http://compass-style.org/">Compass</a> (for Ruby), and <a href="http://wiki.github.com/anthonyshort/csscaffold">Scaffold</a> (for PHP). These frameworks let you write your style sheets with extra language features, and automatically compile them to standard CSS code when sending them to the browser.</p>
<p>Using Scaffold, for example, you could write your style sheet like this:</p>
<pre><code>@grid {
  column-width:30;
  column-count:24;
  right-gutter-width:20;
  baseline:20;
  unit:px;
}
.header, .footer {
  +columns(24);
}
.content {
  +columns(18);
}
.sidebar {
  +columns(6);
  +last;
}</code></pre>
<p>The <code>@grid</code> at-rule sets up the options for Scaffold&#8217;s <a href="http://wiki.github.com/anthonyshort/csscaffold/layout-plugin">layout plugin</a>, and then lines like <code>+columns(24);</code> (called <strong>mixins</strong>) are compiled into standard CSS properties when the browser requests the style sheet.</p>
<p>These are just a couple of the ways that the latest CSS frameworks respond to those critics who complain about having to sacrifice HTML code quality to use them. Now you can have all the benefits of a well-tested layout framework, and apply them to your HTML code on your terms.</p>
<p style="text-align: right;"><cite>(photo: <a href="http://www.sxc.hu/photo/858987">Nbauer</a>)</cite></p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/11/10/video-css-frameworks-%e2%80%93-make-the-right-choice/' rel='bookmark' title='Permanent Link: Video: CSS Frameworks – Make the Right Choice'>Video: CSS Frameworks – Make the Right Choice</a> <small>Choose the right framework and you’ll save yourself a lot...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/01/12/how-semantic-markup-helps-server-side-developers-write-reusable-code/' rel='bookmark' title='Permanent Link: How Semantic Markup Helps Server-side Developers Write Reusable Code'>How Semantic Markup Helps Server-side Developers Write Reusable Code</a> <small>As front-end developers, we know how much easier maintenance, testing,...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/03/31/techy-treasures-5-fudging-css-counters-in-internet-explorer/' rel='bookmark' title='Permanent Link: Techy Treasures #5: Fudging CSS Counters in Internet Explorer'>Techy Treasures #5: Fudging CSS Counters in Internet Explorer</a> <small>CSS Counters are a useful but under-used feature of CSS2...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=adadb8e65cb945f6761aac2a903d57d7&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=adadb8e65cb945f6761aac2a903d57d7&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/10/06/css-frameworks-semantic-class-names/feed/</wfw:commentRss>
			<slash:comments>11</slash:comments>
		</item>
		<item>
			<title>Interesting CSS Quirks: Border-spacing</title>
			<link>http://www.pheedcontent.com/click.phdo?i=558f1069b5c6530ec1bf9b59f02ec856</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2009/10/01/interesting-css-quirks-border-spacing/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2009/10/01/interesting-css-quirks-border-spacing/#comments</comments>
			<pubDate>Thu, 01 Oct 2009 01:50:54 +0000</pubDate>
			<dc:creator>AlexW</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=14646</guid>
			<description><![CDATA[I came across a CSS peculiarity recently that had me scratching my head, so I thought it was worth popping in a little post here for future Googling head-scratchers. 


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/04/15/5-rarely-used-css-properties/' rel='bookmark' title='Permanent Link: 5 Rarely-Used CSS Properties'>5 Rarely-Used CSS Properties</a> <small>It is easy to forget CSS that you don't use...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/08/11/css-system-styles/' rel='bookmark' title='Permanent Link: How to Use Operating System Styles in CSS'>How to Use Operating System Styles in CSS</a> <small>CSS can reference fonts and colors defined for the underlying...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/03/31/techy-treasures-5-fudging-css-counters-in-internet-explorer/' rel='bookmark' title='Permanent Link: Techy Treasures #5: Fudging CSS Counters in Internet Explorer'>Techy Treasures #5: Fudging CSS Counters in Internet Explorer</a> <small>CSS Counters are a useful but under-used feature of CSS2...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=558f1069b5c6530ec1bf9b59f02ec856&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=558f1069b5c6530ec1bf9b59f02ec856&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p>I came across a CSS peculiarity recently that had me scratching my head, so I thought it was worth popping in a little post here for future Googling head-scratchers. </p>
<p>The <a href="http://webstandardsgroup.org/mail/">WSG mailing list</a> gets a lot of CSS layout questions sent to it and last week I noticed <a href="http://www.mail-archive.com/wsg@webstandardsgroup.org/msg39800.html">this query</a>. Tee wanted to visually reproduce the table layout shown below without adding extra wrapping DIVs or other non-semantic markup.</p>
<p><img src="http://www.sitepoint.com/examples/tabletest/example.png" alt="Example table layout" width="363px" height="188px" class="imgright" /></p>
<p>It&#8217;s not quite as simple as it looks. </p>
<div id="adz" class="horizontal"></div><p>Anyway, playing around <a href="http://www.sitepoint.com/examples/tabletest/tabletest.html">my approach</a>, I came across a CSS property I&#8217;ve rarely seen in use: <code>border-spacing</code>. </p>
<p>Now if you&#8217;re not super familiar with <code>border-spacing</code>, it&#8217;s essentially a better version of the old &#8216;cellspacing&#8217; table attribute (i.e. <code>&lt;table cellspacing="3px" ..</code>) , and controls the space *between* your table cells. Of course, if you set the table&#8217;s border to collapse (i.e. <code>border-collapse:collapse;</code>) there *is* no space between your table cells, so setting <code>border-spacing</code> becomes redundant.</p>
<p>The key advantage that CSS&#8217;s border-spacing has over HTML&#8217;s cellspacing (besides cleaner markup) is it allows you to set <em>different</em> horizontal and vertical spacing widths &#8212; seemingly perfect for creating the 5 pixel row separations required in the example. <code><a href="http://reference.sitepoint.com/html/table/cellspacing">Cellspacing</a></code> only accepts a single value.</p>
<p>Guessing the CSS, I didn&#8217;t get the result I expected when I tried (<a href="http://reference.sitepoint.com/css/border-spacing/demo">try for yourself</a>): </p>
<pre>
<code class="css">
table#grid {
	border-collapse:separate;
	border-spacing:  5px 0px ;
}
</code>
</pre>
<p><img src="http://i2.sitepoint.com/images/blogs/border-spacing.png" alt="Border-spacing in action" class="imgleft" />Counter-intuitively to the way <code>margin</code>, <code>padding</code>, <code>border</code> and every other CSS property I can think of operates, <code>border-spacing</code> asks for it&#8217;s horizontal value <em>before</em> it&#8217;s vertical value. Strange.</p>
<p>Other points to note with <code>border-spacing</code>:</p>
<ul>
<li>You aren&#8217;t able to assign different top, bottom, right and left values. This makes sense if you think about it, as we&#8217;re actually talking about an attribute of the TABLE, but I think it&#8217;s easy to trick yourself into thinking it&#8217;s part of the TD &#8212; it wraps around the TD borders after all.</li>
<li>Support is perfect in all modern browsers, but old IE6 &#038; 7 don&#8217;t support this property at all.</li>
</ul>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=horizontal" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/04/15/5-rarely-used-css-properties/' rel='bookmark' title='Permanent Link: 5 Rarely-Used CSS Properties'>5 Rarely-Used CSS Properties</a> <small>It is easy to forget CSS that you don't use...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/08/11/css-system-styles/' rel='bookmark' title='Permanent Link: How to Use Operating System Styles in CSS'>How to Use Operating System Styles in CSS</a> <small>CSS can reference fonts and colors defined for the underlying...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/03/31/techy-treasures-5-fudging-css-counters-in-internet-explorer/' rel='bookmark' title='Permanent Link: Techy Treasures #5: Fudging CSS Counters in Internet Explorer'>Techy Treasures #5: Fudging CSS Counters in Internet Explorer</a> <small>CSS Counters are a useful but under-used feature of CSS2...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=558f1069b5c6530ec1bf9b59f02ec856&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=558f1069b5c6530ec1bf9b59f02ec856&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/10/01/interesting-css-quirks-border-spacing/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		</item>
		<item>
			<title>JSNES: a NES Emulator Written in JavaScript</title>
			<link>http://www.pheedcontent.com/click.phdo?i=8c20aee44fe4db6ce2ddc242a97ca30c</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2009/09/27/jsnes-javascript-nes-emulator/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2009/09/27/jsnes-javascript-nes-emulator/#comments</comments>
			<pubDate>Sat, 26 Sep 2009 17:29:30 +0000</pubDate>
			<dc:creator>Craig Buckler</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<category><![CDATA[development]]></category>
			<category><![CDATA[javascript]]></category>
			<category>development</category>
			<category>game</category>
			<category>JavaScript</category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=14340</guid>
			<description><![CDATA[Just when you thought you'd seen everything in JavaScript, along comes a full NES emulator that is actually playable in a browser. Craig takes a look at JSNES.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/10/16/ben-firshman-jsnes-interview/' rel='bookmark' title='Permanent Link: Exclusive Interview With Ben Firshman, Creator of JSNES'>Exclusive Interview With Ben Firshman, Creator of JSNES</a> <small>Craig interviews Ben Firshman, developer of the JavaScript-based NES emulator...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/02/02/gordon-javascript-flash-player/' rel='bookmark' title='Permanent Link: Introducing Gordon: the Flash Player Written in JavaScript'>Introducing Gordon: the Flash Player Written in JavaScript</a> <small>That's right - it's a Flash player written in JavaScript....</small></li><li><a href='http://www.sitepoint.com/blogs/2009/09/28/google-chrome-frame-technical-details/' rel='bookmark' title='Permanent Link: Google Chrome Frame: the Technical Details'>Google Chrome Frame: the Technical Details</a> <small>Google's Chrome Frame announcement has been surrounded by hype, fabrication,...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=8c20aee44fe4db6ce2ddc242a97ca30c&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=8c20aee44fe4db6ce2ddc242a97ca30c&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img src="http://blogs.sitepointstatic.com/images/tech/162-javascript-nes.png" width="256" height="256" alt="JSNES" class="imgright" />Today&#8217;s award for the most unlikely, probably pointless, but simply stunning use of JavaScript goes to Ben Firshman and his Nintendo Entertainment System emulator, JSNES.</p>
<p><a href="http://benfirshman.com/projects/jsnes/"><strong>Visit the JSNES page&#8230;</strong></a></p>
<p>The emulator is port of the Java-based <a href="http://www.virtualnes.com/">vNES</a> project. It uses the HTML <code>canvas</code> element for screen rendering (sorry Internet Explorer users) although sound is not supported yet.</p>
<p>There are 17 working games to try. Most will run in Firefox 3.5 or Safari 4, but neither browser offers a playable gaming experience. You&#8217;ll be lucky to achieve 10 frames per second on the highest-specification liquid-nitrogen-cooled ninja PC.</p>
<div id="adz" class="horizontal"></div><p>The real revelation, however, is Google Chrome &#8212; it runs the emulator at full speed (50-60 fps) on a modest PC. Google&#8217;s <code>canvas</code> performance optimization appears to be out-pacing the competition by a considerable margin. Both <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=509986">Mozilla</a> and <a href="https://bugs.webkit.org/show_bug.cgi?id=29534">WebKit</a> have raised bugs to investigate why there is such a noticeable speed difference.</p>
<p>Although JSNES is little more than an interesting experiment, it illustrates what can be achieved with modern JavaScript engines, some ingenuity, and lots of caffeine. Ben Firshman &#8212; you are a genius. My only question is &hellip; why?!!</p>
<p>See also: <a href="http://www.sitepoint.com/blogs/2009/10/16/ben-firshman-jsnes-interview/">SitePoint&#8217;s Exclusive Interview With Ben Firshman, Creator of JSNES</a></p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=horizontal" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/10/16/ben-firshman-jsnes-interview/' rel='bookmark' title='Permanent Link: Exclusive Interview With Ben Firshman, Creator of JSNES'>Exclusive Interview With Ben Firshman, Creator of JSNES</a> <small>Craig interviews Ben Firshman, developer of the JavaScript-based NES emulator...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/02/02/gordon-javascript-flash-player/' rel='bookmark' title='Permanent Link: Introducing Gordon: the Flash Player Written in JavaScript'>Introducing Gordon: the Flash Player Written in JavaScript</a> <small>That's right - it's a Flash player written in JavaScript....</small></li><li><a href='http://www.sitepoint.com/blogs/2009/09/28/google-chrome-frame-technical-details/' rel='bookmark' title='Permanent Link: Google Chrome Frame: the Technical Details'>Google Chrome Frame: the Technical Details</a> <small>Google's Chrome Frame announcement has been surrounded by hype, fabrication,...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=8c20aee44fe4db6ce2ddc242a97ca30c&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=8c20aee44fe4db6ce2ddc242a97ca30c&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/09/27/jsnes-javascript-nes-emulator/feed/</wfw:commentRss>
			<slash:comments>15</slash:comments>
		</item>
		<item>
			<title>Who&#8217;s Using ARIA?</title>
			<link>http://www.pheedcontent.com/click.phdo?i=d8da1e69874b77babf0db07a58a810b5</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2009/09/16/whos-using-aria/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2009/09/16/whos-using-aria/#comments</comments>
			<pubDate>Wed, 16 Sep 2009 06:50:26 +0000</pubDate>
			<dc:creator>brothercake</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=14171</guid>
			<description><![CDATA[In this post, James discusses the concept of Accessible Rich Internet Applications, and asks "where are the users?"


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2010/02/16/killer-offline-web-applications/' rel='bookmark' title='Permanent Link: 5 Reasons Why There are no Killer Offline Web Applications'>5 Reasons Why There are no Killer Offline Web Applications</a> <small>Technologies that implement offline web functionality have been around for...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/09/22/progressive-enhancement-graceful-degradation-basics/' rel='bookmark' title='Permanent Link: Progressive Enhancement and Graceful Degradation: an Overview'>Progressive Enhancement and Graceful Degradation: an Overview</a> <small>It is possible to create a fantastic-looking Ajax-powered Internet application...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=d8da1e69874b77babf0db07a58a810b5&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=d8da1e69874b77babf0db07a58a810b5&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-14172" src="http://www.sitepoint.com/blogs/wp-content/uploads/2009/09/pegs.jpg" alt="A square peg in a round hole" width="200" height="200" /></p>
<p>And I don&#8217;t mean developers, I mean <em>real people</em> — actual users, who are browsing the Web with assistive devices and making use of <a href="http://www.w3.org/WAI/intro/aria"><abbr title="Accessible Rich Internet Application">ARIA</abbr></a> enabled applications?</p>
<p>See, when I first researched the question of accessible Ajax for <a href="http://www.sitepoint.com/books/jsant1/">The JavaScript Anthology</a>, back in 2006, there was no such thing as <abbr title="Accessible Rich Internet Application">ARIA</abbr>; there was only the early draft ideas that would eventually become it, based largely on work done at IBM.</p>
<p>And I was unimpressed. Not because of any specific details, but over the entire concept behind it — the idea that all <abbr title="Rich Internet Applications">RIAs</abbr> needed to make them usable for screenreaders is <strong>more information</strong> seemed naïve.</p>
<div id="adz" class="vertical"></div><p>And now that we have a <a href="http://www.w3.org/TR/wai-aria/">formal specification</a>, with browsers and screenreaders that have working implementations, I ask the same question — are <abbr title="Rich Internet Applications">RIAs</abbr> really appropriate to assistive devices if only they had that role and state information, or are we trying to force a square peg into a round hole? Are we just adding layers of information on top of a paradigm that is fundamentally incompatible with the target devices?</p>
<p>What my question really comes down to is, can any Ajax-based application which requires an <abbr title="Application Programming Interface">API</abbr> to give the consuming device enough information to make sense of it, possibly be better than what we had before — where you submit a form and you get a new page in response — something that generations of devices were well able to comprehend.</p>
<p>I&#8217;m not trying to dredge up my <a href="http://dev.opera.com/articles/view/stop-using-ajax/">stop using Ajax</a> argument again — not at all, I accept that Ajax is here to stay, and welcome it as a valuable addition to the programmer&#8217;s toolkit. But the hype has yet to calm down, and Ajax is still over-used. The question of <strong>to what extent Ajax applications are expected to progressively enhance from static applications</strong> is still very much an issue, as the bulk of the comments in <a title="SitePoint blog post: 5 Reasons Why You Should Not Publish Supported Browser Lists, by Craig Buckler" href="http://www.sitepoint.com/blogs/2009/09/10/5-reasons-to-avoid-supported-browser-lists/">one of Craig&#8217;s recent posts</a> highlighted all too sharply.</p>
<p>So where are the <abbr title="Accessible Rich Internet Application">ARIA</abbr> users? And what do <em>they</em> think?</p>
<p>It&#8217;s an honest question, because I really don&#8217;t know. Is there any information? Have any studies been carried out, that convincingly answer the question of whether <abbr title="Accessible Rich Internet Application">ARIA</abbr> enabled applications are a better user experience for people using assistive technologies, compared with conventional post-and-response style applications, that <abbr title="Rich Internet Applications">RIAs</abbr> should otherwise be  expected to degrade to?</p>
<p>Is <abbr title="Accessible Rich Internet Application">ARIA</abbr> really the way forward, or is it just a solution looking for a problem?</p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2010/02/16/killer-offline-web-applications/' rel='bookmark' title='Permanent Link: 5 Reasons Why There are no Killer Offline Web Applications'>5 Reasons Why There are no Killer Offline Web Applications</a> <small>Technologies that implement offline web functionality have been around for...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/09/22/progressive-enhancement-graceful-degradation-basics/' rel='bookmark' title='Permanent Link: Progressive Enhancement and Graceful Degradation: an Overview'>Progressive Enhancement and Graceful Degradation: an Overview</a> <small>It is possible to create a fantastic-looking Ajax-powered Internet application...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=d8da1e69874b77babf0db07a58a810b5&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=d8da1e69874b77babf0db07a58a810b5&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/09/16/whos-using-aria/feed/</wfw:commentRss>
			<slash:comments>18</slash:comments>
		</item>
		<item>
			<title>How to Write a Cookie-less Session Library for JavaScript</title>
			<link>http://www.pheedcontent.com/click.phdo?i=caab1f39362d4318b3df8c719a535b2d</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2009/09/03/javascript-session-variable-library/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2009/09/03/javascript-session-variable-library/#comments</comments>
			<pubDate>Wed, 02 Sep 2009 16:29:26 +0000</pubDate>
			<dc:creator>Craig Buckler</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<category>cookies</category>
			<category>javascript</category>
			<category>sessions</category>
			<category>variables</category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=13335</guid>
			<description><![CDATA[Craig provides the code for a stand-alone JavaScript session variable handling system that does not require cookies or third-party libraries.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/09/02/cookieless-javascript-session-variables/' rel='bookmark' title='Permanent Link: Cookie-less Session Variables in JavaScript'>Cookie-less Session Variables in JavaScript</a> <small>Cookies may be delicious, but they can be clumsy if...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/' rel='bookmark' title='Permanent Link: Cross-browser JSON Serialization in JavaScript'>Cross-browser JSON Serialization in JavaScript</a> <small>JSON serialization can be incredibly useful, but few browsers support...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/07/26/bbc-glow-javascript-library/' rel='bookmark' title='Permanent Link: BBC Glow – a New JavaScript Library'>BBC Glow – a New JavaScript Library</a> <small>The British Broadcasting Corporation has released a new open source...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=caab1f39362d4318b3df8c719a535b2d&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=caab1f39362d4318b3df8c719a535b2d&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img src="http://blogs.sitepointstatic.com/images/tech/135-javascript-sessions.jpg" width="250" height="250" alt="the (JavaScript) Cookie Monster" class="imgright" />In my previous post, <a href="http://www.sitepoint.com/blogs/2009/09/02/cookieless-javascript-session-variables/">Cookie-less Session Variables in JavaScript</a>, we discovered how JavaScript session data could be saved to the window.name property. Today, we create a JavaScript library to exploit this property.</p>
<p><a href="http://blogs.sitepointstatic.com/examples/tech/js-session/index.html"><strong>View the JavaScript session library demonstration page&#8230;</strong></a></p>
<p>The code provides three main methods:</p>
<ul>
<li><strong>Session.set(<em>name</em>, <em>object</em>)</strong> &#8212; store a named session value/object</li>
<li><strong>Session.get(<em>name</em>)</strong> &#8212; retrieve a named session value/object</li>
<li><strong>Session.clear()</strong> &#8212; reset all the session data</li>
</ul>
<div id="adz" class="horizontal"></div><p>Another <strong>Session.dump()</strong> method returns all the JSON-encoded session data. This would normally be used for debugging purposes only.</p>
<p>The JavaScript code is loaded just before the closing <code>body</code> tag. First, we load the JSON library:</p>
<pre><code class="javascript">
&lt;script type=&quot;text/javascript&quot; src=&quot;json-serialization.js&quot;&gt;&lt;/script&gt;
</code></pre>
<p>The JSON library provides cross-browser serialization methods that are required by our Session library. For more information, refer to <a href="http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/">Cross-browser JSON Serialization in JavaScript</a>.</p>
<p>The <a href="http://blogs.sitepointstatic.com/examples/tech/js-session/session.js">session.js</a> file is loaded next. This is stand-alone code that can be implemented in any system &#8212; it does not depend on jQuery or any other JavaScript library. Working through the code:</p>
<pre><code class="javascript">
 if (JSON &amp;&amp; JSON.stringify &amp;&amp; JSON.parse) var Session = Session || (function() {

	// window object
	var win = window.top || window;

	// session store
	var store = (win.name ? JSON.parse(win.name) : {});
</code></pre>
<p>The first line defines our Session module. However, it will only be defined if the JSON library has been loaded and there are no other conflicting Session variables or functions.</p>
<p>The second line sets win to &#8216;window.top&#8217;. It is set to &#8216;window&#8217; if that is not available (perhaps if the browser does not support frames).</p>
<p>Next, we define a &#8217;store&#8217; object to hold all our session data. Exisiting JSON-encoded data in the window.name property is parsed but, if that is not available, &#8217;store&#8217; is set to an empty object.</p>
<pre><code class="javascript">
	// save store on page unload
	function Save() {
		win.name = JSON.stringify(store);
	};

	// page unload event
	if (window.addEventListener) window.addEventListener(&quot;unload&quot;, Save, false);
	else if (window.attachEvent) window.attachEvent(&quot;onunload&quot;, Save);
	else window.onunload = Save;
</code></pre>
<p>The private Save() function assigns the serialized the &#8217;store&#8217; object string to the window .name property. The following three lines define a cross-browser event which calls the Save function when the page is unloaded. Your pages can therefore modify the &#8217;store&#8217; as much as necessary, but the heavy work of serializing and saving only occurs at the last possible moment.</p>
<pre><code class="javascript">
	// public methods
	return {

		// set a session variable
		set: function(name, value) {
			store[name] = value;
		},

		// get a session value
		get: function(name) {
			return (store[name] ? store[name] : undefined);
		},

		// clear session
		clear: function() { store = {}; },

		// dump session data
		dump: function() { return JSON.stringify(store); }

	};

 })();
</code></pre>
<p>Finally, we have our four public set, get, clear and dump functions which handle the store object accordingly. The Session.get() method will return a JavaScript &#8216;undefined&#8217; value if a session name can not be found.</p>
<p>I hope you find the code useful. Feel free to use it in your own projects.</p>
<p>Useful resources:</p>
<ul>
<li><a href="http://blogs.sitepointstatic.com/examples/tech/js-session/index.html"><strong>JavaScript session variables demonstration page</strong></a></li>
<li><a href="http://blogs.sitepointstatic.com/examples/tech/js-session/session.js">Full JavaScript session.js code</a></li>
<li><a href="http://blogs.sitepointstatic.com/examples/tech/js-session/js-session.zip">Download full code in a ZIP file</a></li>
</ul>
<p>See also:</p>
<ul>
<li><a href="http://www.sitepoint.com/blogs/2009/09/02/cookieless-javascript-session-variables/">Cookie-less Session Variables in JavaScript</a></li>
<li><a href="http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/">Cross-browser JSON Serialization in JavaScript</a></li>
<li><a href="http://www.sitepoint.com/blogs/2009/07/22/how-to-develop-a-jquery-plugin/">How To Develop a jQuery Plugin</a></li>
<li><a href="http://www.sitepoint.com/blogs/2009/07/29/build-auto-expanding-textarea-1/">How to Build an Auto-Expanding Textarea jQuery Plugin</a></li>
</ul>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=horizontal" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/09/02/cookieless-javascript-session-variables/' rel='bookmark' title='Permanent Link: Cookie-less Session Variables in JavaScript'>Cookie-less Session Variables in JavaScript</a> <small>Cookies may be delicious, but they can be clumsy if...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/' rel='bookmark' title='Permanent Link: Cross-browser JSON Serialization in JavaScript'>Cross-browser JSON Serialization in JavaScript</a> <small>JSON serialization can be incredibly useful, but few browsers support...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/07/26/bbc-glow-javascript-library/' rel='bookmark' title='Permanent Link: BBC Glow – a New JavaScript Library'>BBC Glow – a New JavaScript Library</a> <small>The British Broadcasting Corporation has released a new open source...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=caab1f39362d4318b3df8c719a535b2d&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=caab1f39362d4318b3df8c719a535b2d&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/09/03/javascript-session-variable-library/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		</item>
		<item>
			<title>Cookie-less Session Variables in JavaScript</title>
			<link>http://www.pheedcontent.com/click.phdo?i=ce9dbaea787cd0c979818fc380ea1605</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2009/09/02/cookieless-javascript-session-variables/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2009/09/02/cookieless-javascript-session-variables/#comments</comments>
			<pubDate>Tue, 01 Sep 2009 17:14:10 +0000</pubDate>
			<dc:creator>Craig Buckler</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=13332</guid>
			<description><![CDATA[Cookies may be delicious, but they can be clumsy if you need to store temporary data in a JavaScript application. Craig provides an unlikely alternative...


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/09/03/javascript-session-variable-library/' rel='bookmark' title='Permanent Link: How to Write a Cookie-less Session Library for JavaScript'>How to Write a Cookie-less Session Library for JavaScript</a> <small>Craig provides the code for a stand-alone JavaScript session variable...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/' rel='bookmark' title='Permanent Link: Cross-browser JSON Serialization in JavaScript'>Cross-browser JSON Serialization in JavaScript</a> <small>JSON serialization can be incredibly useful, but few browsers support...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/02/12/offline-web-application-tutorial/' rel='bookmark' title='Permanent Link: How To Create an Offline Web Application'>How To Create an Offline Web Application</a> <small>Craig provides a quick and simple tutorial which explains how...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=ce9dbaea787cd0c979818fc380ea1605&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=ce9dbaea787cd0c979818fc380ea1605&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img src="http://blogs.sitepointstatic.com/images/tech/135-javascript-sessions.jpg" width="250" height="250" alt="the (JavaScript) Cookie Monster" class="imgright" />Cookies may be delicious delicacies, but they can leave a nasty taste if you don&#8217;t cook them correctly! Cookies can be blocked by the user, storage space is limited to four 20Kb cookies per domain, only strings can be used, paths can cause confusion, and the data is normally passed as plain text in the HTTP header. Often, cookies can be overkill for client-side-heavy applications that need to save temporary state data.</p>
<p>Fortunately, there is a solution that allows you to store JavaScript data within the browser. The data is retained between page loads, it&#8217;ll survive page back/next events (even away from the domain), it does not require plugins or off-line storage facilities, it&#8217;ll hold at several megabytes of information, it is never transmitted to the server, and works in every browser. Bizarrely, it works by exploiting the window.name property (or window.top.name if you&#8217;re using multiple frames). </p>
<p>It&#8217;s rare for developers set the window.name property. Generally, it&#8217;s only required when you&#8217;re manipulating frames or pop-up windows. Even though I&#8217;d hope you weren&#8217;t doing that, you do not normally need to define a name for an application&#8217;s starting window. Although the name property is still a string, it can hold several megabytes of data. Some versions of Opera limit it to around 2Mb but most browsers offer 10MB or more.</p>
<p>It&#8217;s easy to try for yourself. Insert the following JavaScript code into a page on your site:</p>
<pre><code class="javascript">
window.name = &quot;This message will survive between page loads.&quot;;
</code></pre>
<p>Now add the following code to any other page:</p>
<div id="adz" class="vertical"></div><pre><code class="javascript">
alert(window.name);
</code></pre>
<p>Navigate from the first page to the second and you&#8217;ll find that the message data is retained.</p>
<p>As normal, there are a number of caveats:</p>
<ol>
<li>The window.name property can be analysed and changed if you navigate to page on another website. That&#8217;s easily thwarted by not providing external links within your application&#8217;s main window. However, to be on the safe side, don&#8217;t use window.name for storing secure data (unlikely to be a major problem for a client-side-only temporary data store).</li>
<li>window.name can only store strings. What if we need to save other data types or even complex objects? Serialization is the answer and, fortunately, we have already developed <a href="http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/">cross-browser code to generate JSON strings from any JavaScript object</a>.</li>
</ol>
<p>See also: <a href="http://www.sitepoint.com/blogs/2009/09/03/javascript-session-variable-library/">How to Write a Cookie-less Session Library for JavaScript</a>.</p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/09/03/javascript-session-variable-library/' rel='bookmark' title='Permanent Link: How to Write a Cookie-less Session Library for JavaScript'>How to Write a Cookie-less Session Library for JavaScript</a> <small>Craig provides the code for a stand-alone JavaScript session variable...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/' rel='bookmark' title='Permanent Link: Cross-browser JSON Serialization in JavaScript'>Cross-browser JSON Serialization in JavaScript</a> <small>JSON serialization can be incredibly useful, but few browsers support...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/02/12/offline-web-application-tutorial/' rel='bookmark' title='Permanent Link: How To Create an Offline Web Application'>How To Create an Offline Web Application</a> <small>Craig provides a quick and simple tutorial which explains how...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=ce9dbaea787cd0c979818fc380ea1605&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=ce9dbaea787cd0c979818fc380ea1605&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/09/02/cookieless-javascript-session-variables/feed/</wfw:commentRss>
			<slash:comments>14</slash:comments>
		</item>
		<item>
			<title>CSS Font-Sizing: a Definitive Guide</title>
			<link>http://www.pheedcontent.com/click.phdo?i=b603e3a1ebb2c7419cb1bdc5f646844d</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2009/08/20/css-font-sizing-tutorial/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2009/08/20/css-font-sizing-tutorial/#comments</comments>
			<pubDate>Thu, 20 Aug 2009 07:43:19 +0000</pubDate>
			<dc:creator>Craig Buckler</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=13101</guid>
			<description><![CDATA[CSS font sizing appears to be easy until you try it. Craig provides a handy guide to the CSS font-size property and makes several useful recommendations.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/06/02/css-sizing-absolute-position/' rel='bookmark' title='Permanent Link: The Two Ways of Sizing Absolute Elements in CSS'>The Two Ways of Sizing Absolute Elements in CSS</a> <small>Most developers have used left, right, top and bottom properties...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/04/15/5-rarely-used-css-properties/' rel='bookmark' title='Permanent Link: 5 Rarely-Used CSS Properties'>5 Rarely-Used CSS Properties</a> <small>It is easy to forget CSS that you don't use...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/03/05/creating-beveled-images-with-css/' rel='bookmark' title='Permanent Link: Creating Beveled Images with CSS'>Creating Beveled Images with CSS</a> <small>In this post, James shows us several variations of a...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=b603e3a1ebb2c7419cb1bdc5f646844d&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=b603e3a1ebb2c7419cb1bdc5f646844d&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img src="http://blogs.sitepointstatic.com/images/tech/129-css-font-sizes.png" width="250" height="250" alt="CSS font sizing" class="imgright" />Font sizing in CSS sounds as though it should be easy. Until you try it. Many developers use the force; they tinker with the font-size property until it looks right only to find it&#8217;s different in another browser. A little understanding can go a long way&#8230;</p>
<h2>The font-size Property</h2>
<p>The <code>font-size</code> property can be set for any HTML tag (even if it would not normally contain textual content like <code>br</code>). It can be assigned a variety of absolute, relative, or length size parameters.</p>
<p>An element will inherit the font-size of its parent unless you override it. This is especially important when you specify relative sizes.</p>
<div id="adz" class="vertical"></div><h2>Absolute Font Sizing Keywords</h2>
<p>Several absolute font-sizing keywords are available. The font size is determined from a browser preset and the element will not inherit its parent&#8217;s size.</p>
<ul>
<li style="font-size: xx-small;">font-size: xx-small;</li>
<li style="font-size: x-small;">font-size: x-small;</li>
<li style="font-size: small;">font-size: small;</li>
<li style="font-size: medium;">font-size: medium;</li>
<li style="font-size: large;">font-size: large;</li>
<li style="font-size: x-large;">font-size: x-large;</li>
<li style="font-size: xx-large;">font-size: xx-large;</li>
</ul>
<p>Although most browsers support these keywords, the exact sizes will differ. They are a fairly crude method of font sizing and are generally avoided by most developers.</p>
<h2>Relative Font Sizing Keywords</h2>
<p>Two relative font-sizing keywords are available. The font is sized according to its parent element:</p>
<ul>
<li style="font-size: smaller;">font-size: smaller;</li>
<li style="font-size: larger;">font-size: larger;</li>
</ul>
<p>For example, if the parent has a font size of &#8216;medium&#8217;, a value of &#8216;larger&#8217; will set the element to &#8216;large&#8217;. Other font units are normally altered by a factor of around 1.2 but, again, there is no standard and browser results will differ.</p>
<h2>Absolute Lengths</h2>
<p>The <code>font-size</code> property can be assigned an absolute length:</p>
<ul>
<li><strong>mm</strong>: millimeters, e.g. 10mm.</li>
<li><strong>cm</strong>: centimeters, e.g. 1cm ( = 10mm).</li>
<li><strong>in</strong>: inches, e.g. 0.39in ( ~= 10mm).</li>
<li><strong>pt</strong>: point, where 1pt is generally assumed to be 1/72 inch e.g. 12pt.</li>
<li><strong>pc</strong>: pica, where 1pc is 12pt</li>
<li><strong>px</strong>: pixel, e.g. 14px.</li>
</ul>
<p>In general, there are issues with all these measurement units. Millimeters, centimeters and inches are inaccurate for a screen-based medium. Points and picas are unreliable since systems can use different <abbr title="dots per inch">dpi</abbr> settings. Pixel appears to be the most suitable, but it can lead to accessibility issues because the <a href="#textpagezoom">text cannot be resized in IE</a>.</p>
<h2>Relative Lengths</h2>
<p>The <code>font-size</code> property can be assigned a unit that it relative to its parent&#8217;s font size:</p>
<ul>
<li><strong>em</strong>: 1em is equivalent to the current font size, so 2em is twice as large.</li>
<li><strong>%</strong>: 100% is equivalent to the current font size, so 200% is twice as large.</li>
<li><strong>ex</strong>: 1ex is equivalent to the height of the letter &#8216;x&#8217; in the current font.</li>
</ul>
<p>Few developers use &#8216;ex&#8217;, but it can be useful in some situations where you need fine-grained font sizes, e.g. 1ex rather than 0.525em.</p>
<p>Percentage and &#8216;em&#8217; sizes are equivalent, e.g. 50% = 0.5em, 100% = 1em, 120% = 1.2em, etc. Some browsers exhibit subtle differences but it&#8217;s rarely a major problem. If you want to save every byte, you could choose the shortest definition, i.e. 50% is shorter than 0.5em and 1em is shorter than 100%.</p>
<h2 id="textpagezoom">Text Sizing and Page Zooming</h2>
<p>This is where additional complexity creeps in. Most browsers allow the user to:</p>
<ol>
<li>increase or decrease the base text size (image dimensions are not changed)</li>
<li>zoom the page in or out so all the text and graphics change accordingly, or</li>
<li>allow both text sizing and page zooming.</li>
</ol>
<p><em>Just to complicate matters further, Internet Explorer does not allow text resizing on elements which have a font size defined in pixels (px).</em></p>
<p>If you&#8217;re a designer moving to the web from a print background, it&#8217;s disconcerting to give the user that much power. Your design could be ruined by a user zooming in 200% but reducing the text size to 50%. And &#8212; no &#8212; there is nothing you can do to prevent it. Nor should you.</p>
<h2>CSS Font Sizing Recommendations</h2>
<p>The general consensus is that &#8216;em&#8217; or &#8216;%&#8217; is the best solution in most situations. Fonts can be finely scaled relative to each other and browser text sizing is supported. I would also recommend using a percentage <code>font-size</code> on the body tag; it results in better text-sizing in some older browsers.</p>
<p>There are a couple of other recommendations I would suggest when you&#8217;re developing a site:</p>
<ol>
<li>reset the font size and page zoom to their default values in all your browsers before testing (it&#8217;s caught me out a few times!)</li>
<li>try <em>reasonable</em> combinations of text sizing and page zooming in a variety of browsers to ensure the text remains readable.</li>
</ol>
<p>Has font sizing ever caused you problems? Do you have any other tips?</p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/06/02/css-sizing-absolute-position/' rel='bookmark' title='Permanent Link: The Two Ways of Sizing Absolute Elements in CSS'>The Two Ways of Sizing Absolute Elements in CSS</a> <small>Most developers have used left, right, top and bottom properties...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/04/15/5-rarely-used-css-properties/' rel='bookmark' title='Permanent Link: 5 Rarely-Used CSS Properties'>5 Rarely-Used CSS Properties</a> <small>It is easy to forget CSS that you don't use...</small></li><li><a href='http://www.sitepoint.com/blogs/2010/03/05/creating-beveled-images-with-css/' rel='bookmark' title='Permanent Link: Creating Beveled Images with CSS'>Creating Beveled Images with CSS</a> <small>In this post, James shows us several variations of a...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=b603e3a1ebb2c7419cb1bdc5f646844d&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=b603e3a1ebb2c7419cb1bdc5f646844d&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/08/20/css-font-sizing-tutorial/feed/</wfw:commentRss>
			<slash:comments>54</slash:comments>
		</item>
		<item>
			<title>Cross-browser JSON Serialization in JavaScript</title>
			<link>http://www.pheedcontent.com/click.phdo?i=1b0f67a32a5ceaeaf1a1ea4ff6f43997</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/#comments</comments>
			<pubDate>Tue, 18 Aug 2009 17:24:27 +0000</pubDate>
			<dc:creator>Craig Buckler</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=13302</guid>
			<description><![CDATA[JSON serialization can be incredibly useful, but few browsers support it. Fortunately, Craig has provided a few lines of code that could be your serialization savior.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/09/03/javascript-session-variable-library/' rel='bookmark' title='Permanent Link: How to Write a Cookie-less Session Library for JavaScript'>How to Write a Cookie-less Session Library for JavaScript</a> <small>Craig provides the code for a stand-alone JavaScript session variable...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/10/21/javascript-object-instances/' rel='bookmark' title='Permanent Link: Fixing Object Instances in JavaScript'>Fixing Object Instances in JavaScript</a> <small>Even experienced coders can get caught out by object handling...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/04/21/make-your-own-web-site-badges-with-jquery-and-json/' rel='bookmark' title='Permanent Link: Make Your Own Web Site Badges with jQuery and JSON'>Make Your Own Web Site Badges with jQuery and JSON</a> <small>Now that most social media sites offer a JSON API,...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=1b0f67a32a5ceaeaf1a1ea4ff6f43997&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=1b0f67a32a5ceaeaf1a1ea4ff6f43997&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img src="http://blogs.sitepointstatic.com/images/tech/133-javascript-serialization.jpg" width="260" height="260" alt="JavaScript JSON serialization" class="imgright" />In this article we will examine the benefits of object serialization, the current browser implementations, and develop some code that could help your Ajax-based projects.</p>
<p>Assume we have a fairly complex JavaScript object defined using literal notation:</p>
<pre><code class="javascript">
var obj1 = {
	b1: true,
	s1: &quot;text string&quot;,
	n1: 12345,
	n2: null,
	n3: undefined,
	a1: [ 1,1,2,3,5,8, [13, 21, 34] ],
	o1: {
		a: [3, 2, 1],
		b: {
			c: 42,
			d: [ 3.14, 1.618 ]
		}
	}
};
</code></pre>
<p>We can access any of the object properties in a variety of ways:</p>
<pre><code class="javascript">
obj1.s1;				// returns &quot;text string&quot;
obj1[&quot;n1&quot;];				// returns 12345
obj1.a1[6][1];			// returns 21
obj1[&quot;o1&quot;][&quot;b&quot;][&quot;c&quot;];	// returns 42
</code></pre>
<p>This object can also be passed to JavaScript functions and methods rather than specifying individual arguments. Useful stuff.</p>
<div id="adz" class="vertical"></div><p>However, what if we need to store this object in a cookie? What if we need to pass the object to a web services via an Ajax request? What if that web service wants to return a modified version of the object? The answer is serialization:</p>
<ul>
<li><strong>Serialization</strong> is the process of turning any object into a string.</li>
<li><strong>De-serialization</strong> turns that string back into a native object.</li>
</ul>
<p>Perhaps the best string notation we can use in JavaScript is JSON &#8212; JavaScript Object Notation. JSON is a lightweight data-interchange format inspired by JavaScript object literal notation as shown above. JSON is supported by PHP and many other server-side languages (refer to <a href="http://www.json.org/">json.org</a>).</p>
<p>There are two JSON methods in JavaScript:</p>
<ol>
<li><strong>JSON.stringify(<em>obj</em>)</strong> &#8212; converts an JavaScript object to a JSON string</li>
<li><strong>JSON.parse(<em>str</em>)</strong> &#8212; converts a JSON string back to a JavaScript object</li>
</ol>
<p>Unfortunately, very few browsers provide these methods. To date, only Firefox 3.5, Internet Explorer 8.0 and Chrome 3 beta offer native support. Some JavaScript libraries offer their own JSON tools (such as <a href="http://developer.yahoo.com/yui/json/">YUI</a>) but many do not (including <a href="http://jquery.com/">jQuery</a>).</p>
<p>However, all is not lost &#8212; JavaScript is flexible and we can implement the JSON stringify and parse methods whenever a browser requires them.</p>
<p>At the top of our code, we will create a JSON variable that points to the native JSON object or an empty object if it is unavailable:</p>
<pre><code class="javascript">
var JSON = JSON || {};
</code></pre>
<p>The JSON.stringify code is a little more complex:</p>
<pre><code class="javascript">
// implement JSON.stringify serialization
JSON.stringify = JSON.stringify || function (obj) {

	var t = typeof (obj);
	if (t != &quot;object&quot; || obj === null) {

		// simple data type
		if (t == &quot;string&quot;) obj = '&quot;'+obj+'&quot;';
		return String(obj);

	}
	else {

		// recurse array or object
		var n, v, json = [], arr = (obj &amp;&amp; obj.constructor == Array);

		for (n in obj) {
			v = obj[n]; t = typeof(v);

			if (t == &quot;string&quot;) v = '&quot;'+v+'&quot;';
			else if (t == &quot;object&quot; &amp;&amp; v !== null) v = JSON.stringify(v);

			json.push((arr ? &quot;&quot; : '&quot;' + n + '&quot;:') + String(v));
		}

		return (arr ? &quot;[&quot; : &quot;{&quot;) + String(json) + (arr ? &quot;]&quot; : &quot;}&quot;);
	}
};
</code></pre>
<p>If JSON.stringify is not available, we define a new function that accepts a single obj parameter. The parameter can be a single value, an array, or a complex object such as obj1 above.</p>
<p>The code examines the object type. Single values are returned immediately and only strings are modified to put quotes around the value.</p>
<p>If an array or object is passed, the code iterates through every property:</p>
<ol>
<li>Strings values have quotes added.</li>
<li>Child arrays or objects are recursively passed to the JSON.stringify function.</li>
<li>The resulting values are added to the end of a json[] array as a &#8220;name : value&#8221; string, or just a single value for array items.</li>
<li>Finally, the json array is converted to a comma-delimited list and returned within array [] or object {} brackets as necessary.</li>
</ol>
<p>If your brain&#8217;s aching, you&#8217;ll be pleased to know that the JSON.parse code is much simpler:</p>
<pre><code class="javascript">
// implement JSON.parse de-serialization
JSON.parse = JSON.parse || function (str) {
	if (str === "") str = '""';
	eval("var p=" + str + ";");
	return p;
};
</code></pre>
<p>This converts a JSON string to an object using eval().</p>
<p>Before you rush off to implement JSON serialization functions in all your projects, there are a few gotchas:</p>
<ul>
<li>This code has been intentionally kept short. It will work in most situations, but there are subtle differences with the native JSON.stringify and JSON.parse methods.</li>
<li>Not every JavaScript object is supported. For example, a Date() will return an empty object, whereas native JSON methods will encode it to a date/time string.</li>
<li>The code will serialize functions, e.g. var obj1 = { myfunc: function(x) {} }; whereas native JSON methods will not.</li>
<li>Very large objects will throw recursion errors.</li>
<li>The use of eval() in JSON.parse is inherently risky. It will not be a problem if you are calling your own web services, but calls to third-party applications could accidentally or intentionally break your page and cause security issues. If necessary, a safer (but longer and slower) JavaScript parser is available from <a href="http://www.json.org/">json.org</a>.</li>
</ul>
<p>I hope you find the code useful. Feel free to use it in your own projects.</p>
<p>Resource files:</p>
<ul>
<li><a href="http://blogs.sitepointstatic.com/examples/tech/json-serialization/index.html"><strong>JSON Serialization demonstration page</strong></a></li>
<li><a href="http://blogs.sitepointstatic.com/examples/tech/json-serialization/json-serialization.js">Full JavaScript code (json-serialization.js)</a></li>
<li><a href="http://blogs.sitepointstatic.com/examples/tech/json-serialization/json-serialization.zip">Download full code in a ZIP file</a></li>
</ul>
<p>Related reading:</p>
<ul>
<li><a href="http://www.sitepoint.com/blogs/2009/07/22/how-to-develop-a-jquery-plugin/">How To Develop a jQuery Plugin</a></li>
<li><a href="http://www.sitepoint.com/blogs/2009/07/29/build-auto-expanding-textarea-1/">How to Build an Auto-Expanding Textarea jQuery Plugin</a></li>
</ul>
<p><em>Coming soon: a useful application of JSON serialization&#8230;</em></p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/09/03/javascript-session-variable-library/' rel='bookmark' title='Permanent Link: How to Write a Cookie-less Session Library for JavaScript'>How to Write a Cookie-less Session Library for JavaScript</a> <small>Craig provides the code for a stand-alone JavaScript session variable...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/10/21/javascript-object-instances/' rel='bookmark' title='Permanent Link: Fixing Object Instances in JavaScript'>Fixing Object Instances in JavaScript</a> <small>Even experienced coders can get caught out by object handling...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/04/21/make-your-own-web-site-badges-with-jquery-and-json/' rel='bookmark' title='Permanent Link: Make Your Own Web Site Badges with jQuery and JSON'>Make Your Own Web Site Badges with jQuery and JSON</a> <small>Now that most social media sites offer a JSON API,...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=1b0f67a32a5ceaeaf1a1ea4ff6f43997&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=1b0f67a32a5ceaeaf1a1ea4ff6f43997&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/feed/</wfw:commentRss>
			<slash:comments>15</slash:comments>
		</item>
		<item>
			<title>How to Use Operating System Styles in CSS</title>
			<link>http://www.pheedcontent.com/click.phdo?i=eb17fdeee48f8b5375301bc3aa16b18b</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2009/08/11/css-system-styles/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2009/08/11/css-system-styles/#comments</comments>
			<pubDate>Mon, 10 Aug 2009 16:18:45 +0000</pubDate>
			<dc:creator>Craig Buckler</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<category>css</category>
			<category>linux</category>
			<category>mac</category>
			<category>os</category>
			<category>os x</category>
			<category>unix</category>
			<category>windows</category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=12911</guid>
			<description><![CDATA[CSS can reference fonts and colors defined for the underlying Operating System (Windows, Mac OS, Linux etc.) Craig discusses when this might be useful and provides a useful list of property values.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/06/02/css-sizing-absolute-position/' rel='bookmark' title='Permanent Link: The Two Ways of Sizing Absolute Elements in CSS'>The Two Ways of Sizing Absolute Elements in CSS</a> <small>Most developers have used left, right, top and bottom properties...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/05/27/override-inline-css/' rel='bookmark' title='Permanent Link: How to Override Inline CSS Styles'>How to Override Inline CSS Styles</a> <small>Inline CSS can be applied to any HTML element using...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/06/30/write-better-css-with-less/' rel='bookmark' title='Permanent Link: Write Better CSS with Less'>Write Better CSS with Less</a> <small>I have a confession: I think parts of CSS suck....</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=eb17fdeee48f8b5375301bc3aa16b18b&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=eb17fdeee48f8b5375301bc3aa16b18b&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img src="http://blogs.sitepointstatic.com/images/tech/123-css-system-styles.jpg" alt="CSS system styles" width="265" height="265" class="imgright" />One of the lesser-known features of CSS2.1 is the ability to define fonts and colors that are in use by the underlying Operating System theme. This can be useful in situations when you require tighter OS integration, e.g. HTML help files, Adobe AIR or perhaps offline web applications.</p>
<p>Before we begin, there are a few caveats:</p>
<ul>
<li>Do not rely on these properties working in all OS/browser combinations. If your application must work in Opera on BeOS, then I&#8217;d recommend you test it first!</li>
<li>The properties have been deprecated in CSS3 in favor of the <a href="http://www.w3.org/TR/css3-ui/#system">appearance value type</a> (although browser support is extremely limited at this time).</li>
<li>There is nothing to prevent the user defining unusual, clashing, or ugly color schemes in their OS. Pages will reflect their choices &#8212; not your designer&#8217;s.</li>
</ul>
<style type="text/css">
.sys { font-size: 1em; }
.sys th { font-weight: bold; color: #fff; background-color: #888; }
.sys, .sys td, .sys th { text-align: left; padding: 1px 3px; border: 1px solid #666; border-collapse: collapse; }
.sys .prop { font-weight: bold; }
</style>
<h2>System Fonts</h2>
<div id="adz" class="horizontal"></div><p>System fonts are assigned using the &#8216;font&#8217; property. Note that the family, size, and style are all assigned as appropriate, e.g.</p>
<pre><code class="css">
body
{
	font: caption;
}
</code></pre>
<p>The following font values are available. The &#8216;Example&#8217; column shows the current font set by your OS.</p>
<table class="sys" summary="CSS2.1 system fonts">
<tr>
<th>Property</th>
<th>Description</th>
<th>Example</th>
</tr>
<tr>
<td class="prop">caption</td>
<td>Controls font (buttons, drop-downs, etc.)</td>
<td style="font:caption;">ABC abc 123</td>
</tr>
<tr>
<td class="prop">icon</td>
<td>Icon label font</td>
<td style="font:icon;">ABC abc 123</td>
</tr>
<tr>
<td class="prop">menu</td>
<td>Menu font</td>
<td style="font:menu;">ABC abc 123</td>
</tr>
<tr>
<td class="prop">message-box</td>
<td>Dialog box font</td>
<td style="font:message-box;">ABC abc 123</td>
</tr>
<tr>
<td class="prop">small-caption</td>
<td>Small control labels</td>
<td style="font:small-caption;">ABC abc 123</td>
</tr>
<tr>
<td class="prop">status-bar</td>
<td>Status bar font</td>
<td style="font:status-bar;">ABC abc 123</td>
</tr>
</table>
<h2>System Colors</h2>
<p>System colors can be assigned to to any property that expects a color value, e.g.</p>
<pre><code class="css">
body
{
	color: WindowText;
	background-color: Window;
	border: 2px solid ActiveBorder;
}
</code></pre>
<p>The following color values are available. They are shown in <a href="http://en.wikipedia.org/wiki/Camel_case">CamelCase</a> for legibility, but any casing is valid. The &#8216;Example&#8217; column shows the color set by your OS.</p>
<table class="sys" summary="CSS2.1 system colors">
<tr>
<th>Property</th>
<th>Description</th>
<th>Example</th>
</tr>
<tr>
<td class="prop">ActiveBorder</td>
<td>Active window border</td>
<td style="background-color:ActiveBorder;">&nbsp;</td>
</tr>
<tr>
<td class="prop">ActiveCaption</td>
<td>Active window caption</td>
<td style="background-color:ActiveCaption;">&nbsp;</td>
</tr>
<tr>
<td class="prop">AppWorkspace</td>
<td>Background color of multiple document interface</td>
<td style="background-color:AppWorkspace;">&nbsp;</td>
</tr>
<tr>
<td class="prop">Background</td>
<td>Desktop background</td>
<td style="background-color:Background;">&nbsp;</td>
</tr>
<tr>
<td class="prop">ButtonFace</td>
<td>Face color for 3D display elements</td>
<td style="background-color:ButtonFace;">&nbsp;</td>
</tr>
<tr>
<td class="prop">ButtonHighlight</td>
<td>Dark shadow for 3D display elements (facing away from light)</td>
<td style="background-color:ButtonHighlight;">&nbsp;</td>
</tr>
<tr>
<td class="prop">ButtonShadow</td>
<td>Shadow color for 3D display elements</td>
<td style="background-color:ButtonShadow;">&nbsp;</td>
</tr>
<tr>
<td class="prop">ButtonText</td>
<td>Text on push buttons</td>
<td style="background-color:ButtonText;">&nbsp;</td>
</tr>
<tr>
<td class="prop">CaptionText</td>
<td>Text in caption, size box, and scrollbar arrow box</td>
<td style="background-color:CaptionText;">&nbsp;</td>
</tr>
<tr>
<td class="prop">GrayText</td>
<td>Grayed (disabled) text (#000 if not supported by OS)</td>
<td style="background-color:GrayText;">&nbsp;</td>
</tr>
<tr>
<td class="prop">Highlight</td>
<td>Item(s) selected in a control</td>
<td style="background-color:Highlight;">&nbsp;</td>
</tr>
<tr>
<td class="prop">HighlightText</td>
<td>Text of item(s) selected in a control</td>
<td style="background-color:HighlightText;">&nbsp;</td>
</tr>
<tr>
<td class="prop">InactiveBorder</td>
<td>Inactive window border</td>
<td style="background-color:InactiveBorder;">&nbsp;</td>
</tr>
<tr>
<td class="prop">InactiveCaption</td>
<td>Inactive window caption</td>
<td style="background-color:InactiveCaption;">&nbsp;</td>
</tr>
<tr>
<td class="prop">InactiveCaptionText</td>
<td>Color of text in an inactive caption</td>
<td style="background-color:InactiveCaptionText;">&nbsp;</td>
</tr>
<tr>
<td class="prop">InfoBackground</td>
<td>Background color for tooltip controls</td>
<td style="background-color:InfoBackground;">&nbsp;</td>
</tr>
<tr>
<td class="prop">InfoText</td>
<td>Text color for tooltip controls</td>
<td style="background-color:InfoText;">&nbsp;</td>
</tr>
<tr>
<td class="prop">Menu</td>
<td>Menu background</td>
<td style="background-color:Menu;">&nbsp;</td>
</tr>
<tr>
<td class="prop">MenuText</td>
<td>Text in menus</td>
<td style="background-color:MenuText;">&nbsp;</td>
</tr>
<tr>
<td class="prop">Scrollbar</td>
<td>Scroll bar gray area</td>
<td style="background-color:Scrollbar;">&nbsp;</td>
</tr>
<tr>
<td class="prop">ThreeDDarkShadow</td>
<td>Dark shadow for 3D display elements</td>
<td style="background-color:ThreeDDarkShadow;">&nbsp;</td>
</tr>
<tr>
<td class="prop">ThreeDFace</td>
<td>Face color for 3D display elements</td>
<td style="background-color:ThreeDFace;">&nbsp;</td>
</tr>
<tr>
<td class="prop">ThreeDHighlight</td>
<td>Highlight color for 3D display elements</td>
<td style="background-color:ThreeDHighlight;">&nbsp;</td>
</tr>
<tr>
<td class="prop">ThreeDLightShadow</td>
<td>Light color for 3D display elements (facing the light)</td>
<td style="background-color:ThreeDLightShadow;">&nbsp;</td>
</tr>
<tr>
<td class="prop">ThreeDShadow</td>
<td>Dark shadow for 3D display elements</td>
<td style="background-color:ThreeDShadow;">&nbsp;</td>
</tr>
<tr>
<td class="prop">Window</td>
<td>Window background</td>
<td style="background-color:Window;">&nbsp;</td>
</tr>
<tr>
<td class="prop">WindowFrame</td>
<td>Window frame</td>
<td style="background-color:WindowFrame;">&nbsp;</td>
</tr>
<tr>
<td class="prop">WindowText</td>
<td>Text in windows</td>
<td style="background-color:WindowText;">&nbsp;</td>
</tr>
</table>
<p>Would these properties be useful in your next project?</p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=horizontal" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/06/02/css-sizing-absolute-position/' rel='bookmark' title='Permanent Link: The Two Ways of Sizing Absolute Elements in CSS'>The Two Ways of Sizing Absolute Elements in CSS</a> <small>Most developers have used left, right, top and bottom properties...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/05/27/override-inline-css/' rel='bookmark' title='Permanent Link: How to Override Inline CSS Styles'>How to Override Inline CSS Styles</a> <small>Inline CSS can be applied to any HTML element using...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/06/30/write-better-css-with-less/' rel='bookmark' title='Permanent Link: Write Better CSS with Less'>Write Better CSS with Less</a> <small>I have a confession: I think parts of CSS suck....</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=eb17fdeee48f8b5375301bc3aa16b18b&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=eb17fdeee48f8b5375301bc3aa16b18b&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/08/11/css-system-styles/feed/</wfw:commentRss>
			<slash:comments>14</slash:comments>
		</item>
		<item>
			<title>Add More Sparkle with CSS3</title>
			<link>http://www.pheedcontent.com/click.phdo?i=512ab089084723af38fb42e80ee91b0f</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2009/08/04/add-more-sparkle-with-css3/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2009/08/04/add-more-sparkle-with-css3/#comments</comments>
			<pubDate>Tue, 04 Aug 2009 04:07:16 +0000</pubDate>
			<dc:creator>Andrew Tetlaw</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=13034</guid>
			<description><![CDATA[ 
  Have you noticed that when EA Games release a new title they often simultaneously release the game for every gaming platform from PS3 to Nintendo DS? 

 
  There are huge differences in the capabilities of those devices…


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/09/10/case-against-official-browser-support/' rel='bookmark' title='Permanent Link: Microsoft Office Online: a Case Against Supported Browser Lists'>Microsoft Office Online: a Case Against Supported Browser Lists</a> <small>Should you publish an official list of supported browsers for...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/10/06/progressive-enhancement-1-html/' rel='bookmark' title='Permanent Link: Progressive Enhancement Techniques 1: the HTML'>Progressive Enhancement Techniques 1: the HTML</a> <small>In the first of a 3-part series, Craig explains how...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/09/10/5-reasons-to-avoid-supported-browser-lists/' rel='bookmark' title='Permanent Link: 5 Reasons Why You Should Not Publish Supported Browser Lists'>5 Reasons Why You Should Not Publish Supported Browser Lists</a> <small>Do you publish a list of supported browsers for your...</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=512ab089084723af38fb42e80ee91b0f&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=512ab089084723af38fb42e80ee91b0f&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.sitepoint.com/blogs/wp-content/uploads/2009/08/css3sparkle.jpg" alt="css3sparkle" title="css3sparkle" width="234" height="205" class="alignright size-full wp-image-13043 imgright" />
<p>
  <strong>Have you noticed that when EA Games release a new title they often simultaneously release the game for every gaming platform from PS3 to Nintendo DS? </strong>
</p>
<p>
  There are huge differences in the capabilities of those devices and yet they adapt the games to suit each one. They change the visual design and gameplay while maintaining the games&#8217; core experiences, themes, and branding. They focus on giving each customer the best experience for their chosen gaming device.
</p>
<p>
  I can relate this to CSS development. Issues regarding IE6 support aside, we seem to be in a fantastic situation where we have a capable collection of browsers, all with a decent level of CSS2.1 support: Safari, Firefox, Opera, Chrome and Internet Explorer. In fact, this is the first time I can remember when there are 5 browsers available, all with a mature and compatible level of CSS support.
</p>
<p>
  Over the last few years, best-practice CSS development has shifted from graceful degradation to progressive enhancement. And buoyed by the progress of modern browsers and the demise of older browsers, the excitement about what is possible right now is increasing. More and more designers are considering how to provide the best user experience possible for each browser without risking compatibility.
</p>
<div id="adz" class="vertical"></div><p>
  Here are a few examples I&#8217;ve come across recently:
</p>
<p>
  <a href="http://reference.sitepoint.com/css/mediaqueries">Media queries</a> allow fine control over how CSS rules are applied based on the features of the device on which your web page is being displayed. Device width, color, resolution and more can all be queried for. <a href="http://reinholdweber.com/css/css3-a-big-storm-is-coming/">Reinhold Weber </a> has created a demonstration of how the combination of media queries and CSS3 columns enables you to provide an optimized experience to Firefox, Safari, and Chrome users. The technique increases the number of text columns according to screen width.
</p>
<p>
  <a href="http://snook.ca/archives/html_and_css/css-text-rotation">Jonathan Snook</a> has demonstrated a text rotation trick using the CSS3 transform extension in Safari, Chrome, and the latest version of Firefox. As a bonus he also demonstrates that by using the proprietary Microsoft filterproperty you can also support Internet Explorer.
</p>
<p>
  <a href="http://nicewebtype.com/notes/2009/07/24/pure-css-text-gradient-no-pngs/">Tim Brown</a> achieves a pure CSS text-gradient in Safari while Markus Stange has some fun with box shadows in his post &#8220;<a href="http://markusstange.wordpress.com/2009/02/15/fun-with-box-shadows/">Fun with Box Shadows</a>.&#8221; Markus produces some impressive effects for buttons in Firefox 3.5 and there is also some support for box shadows in Safari and Chrome.
</p>
<p>
  I used the <a href="http://www.sitepoint.com/article/css-desktop-adobe-air/">-webkit-box-sizing property in my Adobe AIR application</a> in order to force an element to take 100% width while excluding the width of its borders and padding. Ordinarily the borders and padding would have extended the width of the element to greater than 100% &#8212; an often encountered annoyance. Now the box-sizing property has widespread browser support as <a href="http://idreamincode.co.uk/css/css3/the-css3-box-sizing-concept-a-solution-to-a-longstanding-problem">James Hopkins</a> explains.
</p>
<p>
  <a href="http://reference.sitepoint.com/css/text-shadow">CSS text shadows</a>, which have always been supported by Chrome (and much longer by Safari [since version 1.1]), are now supported by the latest versions of Firefox and Opera. Westciv has an excellent <a href="http://westciv.com/tools/shadows/index.html">CSS text shadow generation tool</a> that you can play with. You can also have some fun with the <a href="http://westciv.com/tools/gradients/index.html">CSS gradient generation tools</a>, currently supported by Safari and Chrome.
</p>
<p>
  The list goes on: <a href="http://www.the-art-of-web.com/css/border-radius/">rounded corners</a>, <a href="http://reference.sitepoint.com/css/at-fontface">custom fonts</a>, and <a href="http://www.zurb.com/article/266/super-awesome-buttons-with-css3-and-rgba">RGBA colors</a>. It certainly is exciting!
</p>
<p>
  But, as exciting as this stuff is, it still has to be cost effective to be worth the effort. So I&#8217;d be interested to hear if anyone is using progressive CSS enhancement in any way in their daily work? If you do so in client work, how do you sell the idea to clients? If a client can see an enhancement demonstrated in one browser, do they demand it in all browsers? And if you have any live examples let us know how you did it.</p>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/09/10/case-against-official-browser-support/' rel='bookmark' title='Permanent Link: Microsoft Office Online: a Case Against Supported Browser Lists'>Microsoft Office Online: a Case Against Supported Browser Lists</a> <small>Should you publish an official list of supported browsers for...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/10/06/progressive-enhancement-1-html/' rel='bookmark' title='Permanent Link: Progressive Enhancement Techniques 1: the HTML'>Progressive Enhancement Techniques 1: the HTML</a> <small>In the first of a 3-part series, Craig explains how...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/09/10/5-reasons-to-avoid-supported-browser-lists/' rel='bookmark' title='Permanent Link: 5 Reasons Why You Should Not Publish Supported Browser Lists'>5 Reasons Why You Should Not Publish Supported Browser Lists</a> <small>Do you publish a list of supported browsers for your...</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=512ab089084723af38fb42e80ee91b0f&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=512ab089084723af38fb42e80ee91b0f&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/08/04/add-more-sparkle-with-css3/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		</item>
		<item>
			<title>How to Build an Auto-Expanding Textarea jQuery Plugin, Part 3</title>
			<link>http://www.pheedcontent.com/click.phdo?i=a5850385ed4baa0f7b158986884c0092</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2009/07/30/build-auto-expanding-textarea-3/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2009/07/30/build-auto-expanding-textarea-3/#comments</comments>
			<pubDate>Wed, 29 Jul 2009 15:37:12 +0000</pubDate>
			<dc:creator>Craig Buckler</dc:creator>
			<category><![CDATA[JavaScript & CSS]]></category>
			<category>html</category>
			<category>javascript</category>
			<category>jquery</category>
			<category>textarea</category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=12531</guid>
			<description><![CDATA[Auto-expanding HTML textarea boxes have become popular on many web sites. In the final of a 3-part series, Craig provides the jQuery plugin code that implements the expanding textarea functionality.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/07/29/build-auto-expanding-textarea-2/' rel='bookmark' title='Permanent Link: How to Build an Auto-Expanding Textarea jQuery Plugin, Part 2'>How to Build an Auto-Expanding Textarea jQuery Plugin, Part 2</a> <small>Auto-expanding HTML textarea boxes have become popular on many web...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/07/29/build-auto-expanding-textarea-1/' rel='bookmark' title='Permanent Link: How to Build an Auto-Expanding Textarea jQuery Plugin, Part 1'>How to Build an Auto-Expanding Textarea jQuery Plugin, Part 1</a> <small>Auto-expanding HTML textarea boxes have become popular on many web...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/07/22/how-to-develop-a-jquery-plugin/' rel='bookmark' title='Permanent Link: How To Develop a jQuery Plugin'>How To Develop a jQuery Plugin</a> <small>Creating a jQuery plugin is easier than you might think....</small></li></ol><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=a5850385ed4baa0f7b158986884c0092&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=a5850385ed4baa0f7b158986884c0092&p=1"/></a>
<!-- foo -->]]></description>
			<content:encoded><![CDATA[<p><img src="http://blogs.sitepointstatic.com/images/tech/115-textarea-expander.png" width="260" height="260" class="imgright" alt="Auto-Expanding Textarea" />In <a href="http://www.sitepoint.com/blogs/2009/07/29/build-auto-expanding-textarea-1/">part 1</a> we discovered how an <a href="http://blogs.sitepointstatic.com/examples/tech/textarea-expander/demo.html">auto-expanding textarea</a> could be built and collated the requirements. In <a href="http://www.sitepoint.com/blogs/2009/07/29/build-auto-expanding-textarea-2/">part 2</a> we determined how coders would initialize our component. It&#8217;s now time to get our hands dirty with some JavaScript.</p>
<p>We are building a jQuery plugin named TextAreaExpander. You can <a href="http://www.sitepoint.com/blogs/2009/07/22/how-to-develop-a-jquery-plugin/">read about the intricacies of jQuery plugin development in this tutorial</a>, but the barebones of our code is:</p>
<pre><code class="javascript">
(function($) {

	// jQuery plugin definition
	$.fn.TextAreaExpander = function(minHeight, maxHeight) {

		// ... our code ...

		return this;
	};

})(jQuery);
</code></pre>
<p>The $.fn statement then declares our new jQuery plugin, TextAreaExpander, with the arguments minHeight and maxHeight. We could express these in a JSON object but it&#8217;s unlikely we&#8217;ll need further parameters so we&#8217;ll keep it simple.</p>
<p>Note that &#8216;this&#8217; refers to the jQuery object; we return it to ensure other jQuery effects can be bound to the same DOM elements.</p>
<h2>Initializing the Textarea</h2>
<p>The following initialization code is added to our TextAreaExpander function:</p>
<pre><code class="javascript">
// initialize
this.each(function() {

	// is a textarea?
	if (this.nodeName.toLowerCase() != &quot;textarea&quot;) return;

	// set height restrictions
	var p = this.className.match(/expand(\d+)\-*(\d+)*/i);
	this.expandMin = minHeight || (p ? parseInt('0'+p[1], 10) : 0);
	this.expandMax = maxHeight || (p ? parseInt('0'+p[2], 10) : 99999);

	// initial resize
	ResizeTextarea(this);

	// add events
	if (!this.Initialized) {
		this.Initialized = true;
		$(this).css(&quot;padding-top&quot;, 0).css(&quot;padding-bottom&quot;, 0);
		$(this).bind(&quot;keyup&quot;, ResizeTextarea).bind(&quot;focus&quot;, ResizeTextarea);
	}
});

return this;
};
</code></pre>
<p>This loops through all the jQuery-selected DOM nodes and runs an anonymous function. The value of &#8216;this&#8217; within that function is an individual textarea node. The following initialization occurs:</p>
<div id="adz" class="vertical"></div><ol>
<li>The first line ensures that only textareas have the auto-expanding effect applied.</li>
<li>The next three lines extract the minimum and maximum height values. The arguments passed to the TextAreaExpander function are used by default. If none are specified, the textarea&#8217;s &#8220;expand&#8221; class HTML is analysed with a regular expression. If we still do not have values, 0 and 99999 are assumed (note that the textarea will always have a minimum height of 1 character, so a zero height is never applied). The values are stored as properties of the textarea node object &#8212; we can therefore examine them from any code.</li>
<li>The following line calls a ResizeTextarea function and passes the textarea node. This will set the height to an appropriate size when auto-expanding is initialized.</li>
<li>Finally, we reset any vertical padding and define &#8220;keyup&#8221; and &#8220;focus&#8221; events. The same ResizeTextarea function is called when the textarea receives focus and after text has been updated by the user. The &#8216;if&#8217; condition around these events ensures that they can only be applied once to any textarea. This condition could have been applied to the whole of the initialization function, however, this code allows us to change the minimum and maximum heights at will.</li>
</ol>
<h2>Resizing the Textarea</h2>
<p>We now need to define our ResizeTextarea function.</p>
<p>In <a href="http://www.sitepoint.com/blogs/2009/07/29/build-auto-expanding-textarea-1/">part 1</a>, we discussed browser differences and noted that IE and Opera should never set a <code>textarea</code> height of 0px. Therefore, we will assign a variable that returns false if IE or Opera is being used:</p>
<pre><code class="javascript">
var hCheck = !($.browser.msie || $.browser.opera);
</code></pre>
<p>It&#8217;s dirty, but I&#8217;m afraid that we cannot rely on better methods such as object detection. I&#8217;m open to suggestions, though!</p>
<p>We can now code our ResizeTextarea function:</p>
<pre><code class="javascript">
// resize a textarea
function ResizeTextarea(e) {

	// event or element?
	e = e.target || e;

	// find content length and box width
	var vlen = e.value.length, ewidth = e.offsetWidth;
	if (vlen != e.valLength || ewidth != e.boxWidth) {

		if (hCheck &amp;&amp; (vlen &lt; e.valLength || ewidth != e.boxWidth)) e.style.height = &quot;0px&quot;;
		var h = Math.max(e.expandMin, Math.min(e.scrollHeight, e.expandMax));

		e.style.overflow = (e.scrollHeight &gt; h ? &quot;auto&quot; : &quot;hidden&quot;);
		e.style.height = h + &quot;px&quot;;

		e.valLength = vlen;
		e.boxWidth = ewidth;
	}

	return true;
};
</code></pre>
<p>This function is passed the argument &#8216;e&#8217;. This is either a textarea node (during initialization) or an event object (when keyup or focus occurs).</p>
<ol>
<li>The first line changes &#8216;e&#8217; to a textarea node object if an event was fired.</li>
<li>The number of characters entered in the textarea is assigned to vlen. The pixel-width of the box is assigned to ewidth. If these values have not changed, we do not need to worry about resizing the box (the user could just be moving the cursor). vlen and ewidth are retained as properties of the textarea node object named valLength and boxWidth. These are set after the textarea is resized so resizing will always occur the first time ResizeTextarea is called.</li>
<li>The next line resets the textarea height to 0px. This only occurs for non-IE/Opera browsers if content has been deleted or the box width has been changed.</li>
<li>The textarea&#8217;s scrollHeight value is now assigned to variable &#8216;h&#8217;. Math.min and Math.max are used to ensure the value falls within the minimum and maximum pixel limits defined for this textarea.</li>
<li>Before we change the textarea height, we change the CSS overflow property. The scrollbars will only be shown if the content height exceeds the textarea height.</li>
<li>We can now modify the textarea height and update the values of valLength and boxWidth.</li>
<li>Finally, the function returns true to ensure other textarea event handlers are not cancelled.</li>
</ol>
<p>Our TextAreaExpander jQuery plugin is complete. However, we need to ensure that the effect is applied to all <code>textarea</code> tags with an HTML &#8220;expand&#8221; class. At the end of our file, we can add an event which initializes all appropriate textareas after the page has loaded:</p>
<pre><code class="javascript">
// initialize all expanding textareas
jQuery(document).ready(function() {
	jQuery(&quot;textarea[class*=expand]&quot;).TextAreaExpander();
});
</code></pre>
<p>I hope you&#8217;ve found this series of tutorials helpful. Feel free to use the auto-expanding textarea plugin in your own projects.</p>
<p>Useful resources:</p>
<ul>
<li><a href="http://blogs.sitepointstatic.com/examples/tech/textarea-expander/index.html">Expanding textarea example page</a></li>
<li><a href="http://blogs.sitepointstatic.com/examples/tech/textarea-expander/index.html.txt">Example page HTML</a></li>
<li><a href="http://blogs.sitepointstatic.com/examples/tech/textarea-expander/jquery.textarea-expander.js">Full jQuery plugin code (jquery.textarea-expander.js)</a></li>
<li><a href="http://blogs.sitepointstatic.com/examples/tech/textarea-expander/textarea-expander.zip">Download full code in a ZIP file</a></li>
</ul>
<p>See also:</p>
<ul>
<li><a href="http://www.sitepoint.com/blogs/2009/07/29/build-auto-expanding-textarea-1/">Part 1: building an auto-expanding textarea</a></li>
<li><a href="http://www.sitepoint.com/blogs/2009/07/29/build-auto-expanding-textarea-2/">Part 2: textarea initialization</a></li>
<li><a href="http://www.sitepoint.com/blogs/2009/07/22/how-to-develop-a-jquery-plugin/">How To Develop a jQuery Plugin</a></li>
</ul>
<script src="http://adscluster.aws.sitepoint.com/openx/adjs.sp.php?region=14&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/07/29/build-auto-expanding-textarea-2/' rel='bookmark' title='Permanent Link: How to Build an Auto-Expanding Textarea jQuery Plugin, Part 2'>How to Build an Auto-Expanding Textarea jQuery Plugin, Part 2</a> <small>Auto-expanding HTML textarea boxes have become popular on many web...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/07/29/build-auto-expanding-textarea-1/' rel='bookmark' title='Permanent Link: How to Build an Auto-Expanding Textarea jQuery Plugin, Part 1'>How to Build an Auto-Expanding Textarea jQuery Plugin, Part 1</a> <small>Auto-expanding HTML textarea boxes have become popular on many web...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/07/22/how-to-develop-a-jquery-plugin/' rel='bookmark' title='Permanent Link: How To Develop a jQuery Plugin'>How To Develop a jQuery Plugin</a> <small>Creating a jQuery plugin is easier than you might think....</small></li></ol></p><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://ads.pheedo.com/click.phdo?s=a5850385ed4baa0f7b158986884c0092&p=1"><img alt="" style="border: 0;" border="0" src="http://ads.pheedo.com/img.phdo?s=a5850385ed4baa0f7b158986884c0092&p=1"/></a>
<!-- foo -->]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/07/30/build-auto-expanding-textarea-3/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
<!-- Dynamic Page Served (once) in 8.553 seconds -->
<!-- Cached page served by WP-Cache -->