<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
> <channel><title>SitePoint » Learn CSS &#124; HTML5 &#124; JavaScript &#124; Wordpress &#124; Tutorials-Web Development &#124; Reference &#124; Books and More &#187; JavaScript &amp; CSS</title> <atom:link href="http://www.sitepoint.com/category/tech/dhtml-css/feed/" rel="self" type="application/rss+xml" /><link>http://www.sitepoint.com</link> <description></description> <lastBuildDate>Sun, 27 May 2012 15:59:16 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" /> <item><title>Laconic: a New Way to Generate DOM Content from JavaScript</title><link>http://www.sitepoint.com/laconic-javascript-dom-content-generation/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=laconic-javascript-dom-content-generation</link> <comments>http://www.sitepoint.com/laconic-javascript-dom-content-generation/#comments</comments> <pubDate>Tue, 08 May 2012 15:00:48 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[JavaScript]]></category> <category><![CDATA[JavaScript & Ajax Tutorials]]></category> <category><![CDATA[JavaScript & CSS]]></category> <category><![CDATA[jQuery]]></category> <category><![CDATA[Opinion]]></category> <category><![CDATA[DOM]]></category> <category><![CDATA[javascript]]></category> <category><![CDATA[jQuery Tutorials & Articles]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=54308</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2009/01/dom-exception-tree-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="DOM Exception Tree" title="DOM Exception Tree" />Craig looks at Laconic: a small standalone JavaScript library for easy content creation using standard DOM insertion methods.]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2009/01/dom-exception-tree-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="DOM Exception Tree" title="DOM Exception Tree" /><p></p><p>Content can be inserted into your page using innerHTML or outerHTML&hellip;</p><pre><code>
var container = document.getElementById(&quot;container&quot;);
container.innerHTML = &quot;&lt;p&gt;Here's some new &lt;strong&gt;DOM&lt;/strong&gt; content.&lt;/p&gt;&quot;;
</code></pre><p><em>(Note that jQuery also uses innerHTML for DOM content manipulation).</em></p><p>It&#8217;s fast and easy &#8212; but it&#8217;s not without problems:</p><ol><li>Invalid HTML strings can be inserted which make errors difficult to spot and debug.</li><li>You may encounter browser issues if you attempt complex activities such as using or modifying nodes in the resulting DOM content.</li><li>Although it&#8217;s well supported, innerHTML is a proprietary technology and not part of the W3C DOM. It offends the standards gods.</li></ol><p>So let&#8217;s look at the DOM-based alternative:</p><pre><code>
var newpara = document.createElement(&quot;p&quot;);
var newstrong = document.createElement(&quot;strong&quot;);
newstrong.appendChild(document.createTextNode(&quot;DOM&quot;));
newpara.appendChild(document.createTextNode(&quot;Here's some new &quot;));
newpara.appendChild(newstrong);
newpara.appendChild(document.createTextNode(&quot; content.&quot;));
var container = document.getElementById(&quot;container&quot;);
container.appendChild(newpara);
</code></pre><p>Nasty. It&#8217;s three times longer, slower to execute and still prone to human error.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>Several years ago I devised by own solution, <a
href="http://www.optimalworks.net/resources/betterinnerhtml/">BetterInnerHTML</a>, which loaded an HTML string as XML, recursed the structure and inserted appropriate nodes into the DOM. It worked, but I was never totally happy with performance or issues such as HTML entities.</p><p>Fortunately, Joe Stelmach has devised an alternative. It&#8217;s a small standalone utility named <a
href="https://github.com/joestelmach/laconic">Laconic</a> which uses a logical JavaScript notation to map directly to HTML, e.g.</p><pre><code>
$.el.p(
	&quot;Here's some new &quot;,
	$.el.strong(&quot;DOM&quot;),
	&quot; content.&quot;
).appendTo(document.getElementById(&quot;container&quot;));
</code></pre><p>Attributes are supported using object literal notation:</p><pre><code>
// produce &lt;div class=&quot;example&quot;&gt;&lt;div&gt;Content&lt;/div&gt;&lt;/div&gt;
$.el.div(
	{ &quot;class&quot;: &quot;example&quot;},
	$.el.div(&quot;Content&quot;)
);
</code></pre><p>I like it. While innerHTML remains the best option for quick and dirty DOM content generation, Laconic will be useful in those odd situations when it fails to work as expected.</p><p>For more information and downloads, refer to:</p><ul><li><a
href="https://github.com/joestelmach/laconic">Laconic on GitHub</a></li><li><a
href="http://joestelmach.github.com/laconic/">Laconic example page</a></li></ul> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/laconic-javascript-dom-content-generation/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Judgment Day Arrives: Opera Implements the CSS3 Webkit Prefix</title><link>http://www.sitepoint.com/opera-css3-webkit-prefix/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=opera-css3-webkit-prefix</link> <comments>http://www.sitepoint.com/opera-css3-webkit-prefix/#comments</comments> <pubDate>Sat, 05 May 2012 12:05:30 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[Android]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[Discussion]]></category> <category><![CDATA[HTML & CSS]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[iOS]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[JavaScript & CSS]]></category> <category><![CDATA[Mobile Web Dev]]></category> <category><![CDATA[Mobile Web Development]]></category> <category><![CDATA[Opinion]]></category> <category><![CDATA[Web Tech]]></category> <category><![CDATA[apple]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[HTML5 Tutorials & Articles]]></category> <category><![CDATA[microsoft]]></category> <category><![CDATA[Mozilla]]></category> <category><![CDATA[opera]]></category> <category><![CDATA[webkit]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=54305</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/02/641-css-vendor-prefix-crisis-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="641-css-vendor-prefix-crisis" title="641-css-vendor-prefix-crisis" />Opera is implementing 14 regularly-used webkit-prefixed properties in their browser. Is this the beginning of the end for CSS3 vendor prefixes?]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/02/641-css-vendor-prefix-crisis-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="641-css-vendor-prefix-crisis" title="641-css-vendor-prefix-crisis" /><p></p><p>In February 2012, we reported the minutes of W3C meeting where <a
href="http://www.sitepoint.com/w3c-css-webkit-prefix-crisis/">Mozilla, Opera and Microsoft discussed implementing -webkit prefixes</a> in non-webkit browsers. The reason: some developers use only webkit prefixes &#8212; their sites look good in some browsers, but broken in others even when they offer the same level of CSS3 support. The issue is especially prevalent on mobile browsers and many developers fail to look beyond their high-end Apple or Android devices.</p><p><a
href="http://dev.opera.com/articles/view/opera-mobile-emulator-experimental-webkit-prefix-support/">Opera has now announced support for 14 CSS3 webkit properties</a> in their Mobile Emulator. The implementation will eventually reach all editions of their desktop and mobile browsers. If you&#8217;re thinking <em>&#8220;Opera has a tiny market share&#8221;</em>, think again: <a
href="http://www.sitepoint.com/browser-trends-may-2012/">it&#8217;s the world&#8217;s most-used mobile browser</a>.</p><p>Perhaps I&#8217;m being overly dramatic, but Charlton Heston&#8217;s famous line comes to mind: <em>&#8220;They finally, really did it. You manics. You blew it up!&#8221;</em></p><h2>Opera -webkit Aliasing</h2><p>Opera analyzed stylesheets from 10,000 popular websites to determine which CSS values/properties would receive -webkit aliases:<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><table
summary="Opera CSS webkit aliases" width="70%" style="text-align:left !important;margin:20px auto"><tr><th>-o- prefix</th><th>-webkit- alias</th></tr><tr><td>-o-linear-gradient</td><td>-webkit-linear-gradient</td></tr><tr><td>box-shadow</td><td>-webkit-box-shadow</td></tr><tr><td>-o-transform</td><td>-webkit-transform</td></tr><tr><td>-o-transform-origin</td><td>-webkit-transform-origin</td></tr><tr><td>border-radius</td><td>-webkit-border-radius</td></tr><tr><td>border-top-left-radius</td><td>-webkit-border-top-left-radius</td></tr><tr><td>border-top-right-radius</td><td>-webkit-border-top-right-radius</td></tr><tr><td>border-bottom-left-radius</td><td>-webkit-border-bottom-left-radius</td></tr><tr><td>border-bottom-right-radius</td><td>-webkit-border-bottom-right-radius</td></tr><tr><td>-o-transition</td><td>-webkit-transition</td></tr><tr><td>-o-transition-delay</td><td>-webkit-transition-delay</td></tr><tr><td>-o-transition-duration</td><td>-webkit-transition-duration</td></tr><tr><td>-o-transition-property</td><td>-webkit-transition-property</td></tr><tr><td>-o-transition-timing-function</td><td>-webkit-transition-timing-function</td></tr></table><p>If the browser encounters a property such as <code>-webkit-border-radius</code>, it will apply that effect. If you&#8217;ve defined <code>-webkit-border-radius</code>, <code>-o-border-radius</code> and <code>border-radius</code>, normal CSS cascading rules apply and the last defined rule or most appropriate selector will be applied, e.g.</p><pre><code>
#myelement
{
	-o-border-radius: 3px;
	border-radius: 6px;
	-webkit-border-radius: 9px;
}
</code></pre><p>All properties are considered to have equal priority so Opera applies a border radius of 9px.</p><p>With regard to differences in behavior, Opera state:</p><blockquote><p> As far as we can tell, the behavior the properties that we have aliased is identical in WebKit and Opera, or at least close enough that the differences will not matter in practice. If it turns out that there are differences big enough to cause breakage, we will consider our options, one of which is to align the behavior of our -webkit- prefixed variant to what WebKit actually does.</p></blockquote><p>Opera make a reasonable case to justify their decision. While they understand the complaints, their primary goal is to create a browser which works well for users &#8212; who outnumber developers by many thousands to one.</p><h2>The Backlash</h2><p>Most developers understand the problem but disagree with the solution. It&#8217;s crude and has the potential to break the web. Taking the decision to it&#8217;s logical extreme, all vendors would support every prefix but any implementation differences would render the CSS property useless.</p><p>The solution rewards bad development practices. While Opera advises you use all vendor prefixes, they will exacerbate the problem:</p><ul><li>Less conscientious developers will see this as justification for only targeting webkit browsers.</li><li>If your site uses differing -webkit and -o values, it will now be affected by CSS cascade rules. Is it easier to analyze and retest your code or simply remove the Opera properties?</li><li>It will become easier to accidentally omit the -o prefix since sites will work as expected.</li></ul><p>Several problems have already been reported. For example, Modernizr evaluates prefixes in turn until it finds one the browser supports. Therefore:</p><pre><code>
Modernizr.prefixed("transition");
</code></pre><p>now returns <code>WebkitTransition</code> in Opera. Transitions are new to Opera and the browser doesn&#8217;t support every webkit CSS and JavaScript property. If you want to adjust or disable effects in Opera, you can&#8217;t rely on Modernizr-like detection code. You may even need to implement <a
href="http://www.sitepoint.com/why-browser-sniffing-stinks/">nasty browser sniffing</a>.</p><p>However, my biggest issue is this: <em>where are all these problem sites?</em> Has user experience suffered from the lack of rounded corner, gradient, shadow, transition and transform effects? Are those sites genuinely broken or has Opera taken a (marketing) opportunity to make their browser look better?</p><p>Since Opera has analyzed 10,000 websites they can contact the owners directly. At the very least, they could publish a &#8220;hall of shame&#8221; which provides examples and highlights the technical issues. Many developers would happily contact companies on Opera&#8217;s behalf. Some would be prepared to fix sites for free since it could lead to future contracts.</p><p>There are <a
href="http://www.sitepoint.com/css3-vendor-prefix-crisis-solutions/">no easy solutions to the vendor prefix crisis</a>. I understand Opera&#8217;s reasons but, regardless of how this is implemented, it&#8217;s inevitable that something will end up broken.</p><p><strong>Some good news:</strong> Microsoft has announced they will not support webkit prefixes in Internet Explorer (although there&#8217;s nothing to prevent them reversing that decision). Mozilla is yet to reveal their intentions &#8212; they will be watching Opera&#8217;s situation closely.</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/opera-css3-webkit-prefix/feed/</wfw:commentRss> <slash:comments>29</slash:comments> </item> <item><title>How to Use the Mouse Wheel Event in HTML5 Pages</title><link>http://www.sitepoint.com/html5-javascript-mouse-wheel/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=html5-javascript-mouse-wheel</link> <comments>http://www.sitepoint.com/html5-javascript-mouse-wheel/#comments</comments> <pubDate>Fri, 13 Apr 2012 18:00:36 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[HTML & CSS]]></category> <category><![CDATA[HTML & XHTML Tutorials]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[JavaScript & Ajax Tutorials]]></category> <category><![CDATA[JavaScript & CSS]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[HTML5 Tutorials & Articles]]></category> <category><![CDATA[javascript]]></category> <category><![CDATA[mouse]]></category> <category><![CDATA[wheel]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=52648</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/03/655-html5-mouse-wheel-event-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="655-html5-mouse-wheel-event" title="655-html5-mouse-wheel-event" />Craig's brief tutorial explains how you can utilize the mouse wheel in your HTML5 application to do more than just scrolling.]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/03/655-html5-mouse-wheel-event-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="655-html5-mouse-wheel-event" title="655-html5-mouse-wheel-event" /><p></p><p>Supporting the mouse wheel can add further interactivity to your HTML5 web pages. Rather than scrolling the page, you could perform a different action such as zooming in or out.</p><p><a
href="http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html"><strong>View the mouse wheel demonstration page&hellip;</strong></a></p><p>Most browsers support the &#8220;mousewheel&#8221; event for any element. You can register a handling function which is passed an event object. This exposes a <code>wheelDelta</code> property; a positive value for scrolling up or a negative value for scolling down. The larger or smaller the value, the bigger the movement.</p><p>Unfortunately, there&#8217;s one browser which doesn&#8217;t support the the &#8220;mousewheel&#8221; event. You&#8217;re wrong: <em>it&#8217;s Firefox</em>. Mozilla has implemented a &#8220;DOMMouseScroll&#8221; event. This passes an event object with a <code>detail</code> property but, unlike <code>wheelDelta</code>, it returns a positive value for scrolling down. So, until Mozilla adopt the event, we have a bizarre situation where it&#8217;s actually a little easier to code for IE6! That&#8217;s not something you hear said every day.</p><p>You should also note that Apple disable the scroll wheel in Safari, but support is available in the webkit engine so your code won&#8217;t cause any problems.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><h2>Adding a mousewheel Event Handler</h2><p>Let&#8217;s add an image to our web page which will zoom in and out in response to the mouse wheel:</p><pre><code>
&lt;img id=&quot;myimage&quot; src=&quot;myimage.jpg&quot; alt=&quot;my image&quot; /&gt;
</code></pre><p>We can now attach the mousewheel event handler:</p><pre><code>
var myimage = document.getElementById(&quot;myimage&quot;);
if (myimage.addEventListener) {
	// IE9, Chrome, Safari, Opera
	myimage.addEventListener(&quot;mousewheel&quot;, MouseWheelHandler, false);
	// Firefox
	myimage.addEventListener(&quot;DOMMouseScroll&quot;, MouseWheelHandler, false);
}
// IE 6/7/8
else myimage.attachEvent(&quot;onmousewheel&quot;, MouseWheelHandler);
</code></pre><h2>The Cross-Browser mousewheel Event Handling Function</h2><p>Our MouseWheelHandler can now determine the wheel movement delta. In this case, we&#8217;re going to reverse Firefox&#8217;s <code>detail</code> value and return either 1 for up or -1 for down:</p><pre><code>
function MouseWheelHandler(e) {
	// cross-browser wheel delta
	var e = window.event || e; // old IE support
	var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
</code></pre><p>We can now size the image accordingly. The code below sets a width between 50px and 800px, but you could <a
href="http://www.sitepoint.com/html5-responsive-design-image-dimensions/">determine the image&#8217;s natural dimensions</a> and use that.</p><pre><code>
	myimage.style.width = Math.max(50, Math.min(800, myimage.width + (30 * delta))) + &quot;px&quot;;
	return false;
}
</code></pre><p>Finally, we return false to cancel the standard event which would normally scroll the page.</p><p><a
href="http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html"><strong>View the mouse wheel demonstration page&hellip;</strong></a></p><p>The code works in every browser, including IE6, 7 and 8, but Safari users won&#8217;t see anything happening.</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/html5-javascript-mouse-wheel/feed/</wfw:commentRss> <slash:comments>14</slash:comments> </item> <item><title>Goodbye -9999px: A New CSS Image Replacement Technique</title><link>http://www.sitepoint.com/new-css-image-replacement-technique/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=new-css-image-replacement-technique</link> <comments>http://www.sitepoint.com/new-css-image-replacement-technique/#comments</comments> <pubDate>Tue, 10 Apr 2012 17:00:28 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[CSS Tutorials]]></category> <category><![CDATA[HTML & CSS]]></category> <category><![CDATA[JavaScript & CSS]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[html]]></category> <category><![CDATA[images]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=52738</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/03/659-image-replacement1-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="659-image-replacement" title="659-image-replacement" />The -9999px text indent has served us well but there's a new image replacement kid on the block. Craig analyses the latest technique.]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/03/659-image-replacement1-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="659-image-replacement" title="659-image-replacement" /><p></p><p>The -9999px image replacement technique has been popular for the best part of a decade. To replace a text element with an image, you use the following code:</p><pre><code>
&lt;h1&gt;This Text is Replaced&lt;/h1&gt;
&lt;style&gt;
h1
{
	background: url(&quot;myimage&quot;) 0 0 no-repeat;
	text-indent: -9999px;
}
&lt;/style&gt;
</code></pre><p>The element&#8217;s background is displayed and it&#8217;s text is moved off-screen so it doesn&#8217;t get in the way. Simple and effective. It was often adopted to show graphical titles &#8212; that&#8217;s rarely necessary now we have webfonts, but you&#8217;ll still find it used all over the web.</p><p>Until now.</p><p>A new technique has been discovered by <a
href="http://scottkellum.com/">Scott Kellum</a> and promoted at <a
href="http://www.zeldman.com/2012/03/01/replacing-the-9999px-hack-new-image-replacement/">Zeldman.com</a>:</p><pre><code>
#replace
{
	text-indent: 100%;
	white-space: nowrap;
	overflow: hidden;
}
</code></pre><p>The code indents the text beyond the width of its container but it won&#8217;t wrap and the overflow is hidden.</p><p>While it&#8217;s a little longer and more difficult to remember, performance can be improved because the browser&#8217;s no longer drawing a 9,999px box behind the scenes. It will also prevent the weird left-extended outlines you&#8217;ll see around links using hidden text.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>I haven&#8217;t been able to discover any downsides &#8212; only than I wish I&#8217;d discovered it first. Have you adopted the technique? Have you experienced any issues?</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/new-css-image-replacement-technique/feed/</wfw:commentRss> <slash:comments>56</slash:comments> </item><div><div
class="post_box two_ads" style="float:left;padding-left:2px;"><div
id='div-gpt-ad-1328645237920-0' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328645237920-0'); });</script> </div></div></div><div
class="clear">&nbsp;</div> <item><title>How to Use the HTML5 Full-Screen API</title><link>http://www.sitepoint.com/html5-full-screen-api/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=html5-full-screen-api</link> <comments>http://www.sitepoint.com/html5-full-screen-api/#comments</comments> <pubDate>Thu, 05 Apr 2012 16:00:53 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[CSS3]]></category> <category><![CDATA[HTML & CSS]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript & Ajax Tutorials]]></category> <category><![CDATA[JavaScript & CSS]]></category> <category><![CDATA[api]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[javascript]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=52577</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/03/653-html5-fullscreen-api-50x50.png" class="attachment-thumbnail wp-post-image" alt="653-html5-fullscreen-api" title="653-html5-fullscreen-api" />Craig's latest tutorial shows how you can view games, videos and images in full-screen mode using a new HTML5 API provided in Firefox, Chrome and Safari.]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/03/653-html5-fullscreen-api-50x50.png" class="attachment-thumbnail wp-post-image" alt="653-html5-fullscreen-api" title="653-html5-fullscreen-api" /><p></p><p>Flash has offered a full-screen mode for many years but, until now, browser vendors have resisted the feature. The main reason: security. If you can force an app to run full-screen, the user loses their browser, taskbar and standard operating system controls. They may not be able to close the window or, worse, nefarious developers could emulate the OS and trick users into handing over passwords, credit card details, etc.</p><p>At the time of writing, the HTML5 full-screen API has been implemented in Firefox, Chrome and Safari. <a
href="https://wiki.mozilla.org/Gecko:FullScreenAPI">Mozilla provide good cross-browser details</a> but it&#8217;s worth noting that the specifications and implementation details are likely to change.</p><p>Unlike pressing F11 to make your browser go full-screen, the API sets a single element full-screen. It&#8217;s intended for images, videos and games using the canvas element. Once an element goes full-screen, a message appears temporarily to inform the user that they can press ESC at any time to return to windowed mode.</p><p>The main properties, methods and styles are:</p><p><strong>element.requestFullScreen()</strong><br
/> Makes an individual element full-screen, e.g. document.getElementById(&#8220;myvideo&#8221;).requestFullScreen().</p><p><strong>document.cancelFullScreen()</strong><br
/> Exits full-screen mode and returns to the document view.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p><strong>document.fullScreen</strong><br
/> Returns true if the browser is in full-screen mode.</p><p><strong>:full-screen</strong><br
/> A CSS pseudo-class which applies to an element when it&#8217;s in full-screen mode.</p><h2>Vexing Vendor Prefixes</h2><p>Don&#8217;t bother trying to use these API names. You&#8217;ll require vendor prefixes for <strong>BOTH</strong> the CSS and JavaScript properties:</p><table
style="width:80%;margin:1em auto"><tr><th>Standard</th><th>Chrome/Safari</th><th>Firefox</th></tr><tr><td>.requestFullScreen()</td><td>.webkitRequestFullScreen()</td><td>.mozRequestFullScreen()</td></tr><tr><td>.cancelFullScreen()</td><td>.webkitCancelFullScreen()</td><td>.mozCancelFullScreen()</td></tr><tr><td>.fullScreen</td><td>.webkitIsFullScreen</td><td>.mozfullScreen</td></tr><tr><td>:full-screen</td><td>:-webkit-full-screen</td><td>:-moz-full-screen</td></tr></table><p>There&#8217;s no support in Internet Explorer or Opera yet, but I would suggest you use the &#8216;ms&#8217; and &#8216;o&#8217; prefixes for future proofing.</p><p>I&#8217;ve developed a function in the <a
href="http://blogs.sitepointstatic.com/examples/tech/full-screen/index.html"><strong>demonstration page</strong></a> which handles the prefix shenanigans for you:</p><pre><code>
var pfx = [&quot;webkit&quot;, &quot;moz&quot;, &quot;ms&quot;, &quot;o&quot;, &quot;&quot;];
function RunPrefixMethod(obj, method) {
	var p = 0, m, t;
	while (p &lt; pfx.length &amp;&amp; !obj[m]) {
		m = method;
		if (pfx[p] == &quot;&quot;) {
			m = m.substr(0,1).toLowerCase() + m.substr(1);
		}
		m = pfx[p] + m;
		t = typeof obj[m];
		if (t != &quot;undefined&quot;) {
			pfx = [pfx[p]];
			return (t == &quot;function&quot; ? obj[m]() : obj[m]);
		}
		p++;
	}
}
</code></pre><p>We can then make any element viewable full screen by attaching a handler function which determines whether it&#8217;s in full-screen mode already and acts accordingly:</p><pre><code>
var e = document.getElementById(&quot;fullscreen&quot;);
e.onclick = function() {
	if (RunPrefixMethod(document, &quot;FullScreen&quot;) || RunPrefixMethod(document, &quot;IsFullScreen&quot;)) {
		RunPrefixMethod(document, &quot;CancelFullScreen&quot;);
	}
	else {
		RunPrefixMethod(e, &quot;RequestFullScreen&quot;);
	}
}
</code></pre><h2>The CSS</h2><p>Once the browser enters full-screen mode you&#8217;ll almost certainly want to modify the styles for the element and it&#8217;s children. For example, if your element normally has a width of 500px, you&#8217;ll want to change that to 100% so it uses the space available, e.g.</p><pre><code>
#myelement
{
	width: 500px;
}
#myelement:full-screen
{
	width: 100%;
}
#myelement:full-screen img
{
	width: 100%;
}
</code></pre><p>However, <strong>you cannot use a list of vendor prefixed selectors</strong>:</p><pre><code>
/* THIS DOES NOT WORK */
#myelement:-webkit-full-screen,
#myelement:-moz-full-screen,
#myelement:-ms-full-screen,
#myelement:-o-full-screen,
#myelement:full-screen
{
	width: 100%;
}
</code></pre><p>For some bizarre reason, you must repeat the styles in their own blocks or they won&#8217;t be applied:</p><pre><code>
/* this works */
#myelement:-webkit-full-screen	{ width: 100% }
#myelement:-moz-full-screen		{ width: 100% }
#myelement:-ms-full-screen		{ width: 100% }
#myelement:-o-full-screen		{ width: 100% }
#myelement:full-screen			{ width: 100% }
</code></pre><p>Weird.</p><p><a
href="http://blogs.sitepointstatic.com/examples/tech/full-screen/index.html"><strong>View the demonstration page in Firefox, Chrome or Safari&hellip;</strong></a></p><p>The technique works well. The only issue I&#8217;ve discovered concerns Safari on a two-monitor desktop &#8212; it insists on using the first monitor for full-screen mode even if the browser is running on the second screen?</p><p>While it&#8217;s possibly a little early to use full-screen mode, games developers and video producers should keep an eye on progress.</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/html5-full-screen-api/feed/</wfw:commentRss> <slash:comments>19</slash:comments> </item> <item><title>10 Tips for Developing Better jQuery Plugins</title><link>http://www.sitepoint.com/10-tips-better-jquery-plugins/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=10-tips-better-jquery-plugins</link> <comments>http://www.sitepoint.com/10-tips-better-jquery-plugins/#comments</comments> <pubDate>Thu, 29 Mar 2012 15:27:53 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[Best Practices]]></category> <category><![CDATA[HTML & CSS]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[JavaScript & Ajax Tutorials]]></category> <category><![CDATA[JavaScript & CSS]]></category> <category><![CDATA[jQuery]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[HTML5 Tutorials & Articles]]></category> <category><![CDATA[javascript]]></category> <category><![CDATA[jQuery Tutorials & Articles]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=52533</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2010/10/435-jquery-143.jpg" class="attachment-thumbnail wp-post-image" alt="435-jquery-143" title="435-jquery-143" />Craig provides his top 10 tips for developers who want to write successful jQuery plugins.]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2010/10/435-jquery-143.jpg" class="attachment-thumbnail wp-post-image" alt="435-jquery-143" title="435-jquery-143" /><p></p><p>There are some great <a
href="http://www.jqueryplugins.com/">jQuery plugins</a>. The better ones are adopted by thousands of web developers throughout the world. Unfortunately, the worse ones fail and disappear into obscurity. Here are some tips to ensure your plugins reach their full potential&hellip;</p><h2>1. Don&#8217;t Break the Chain</h2><p>Unless your plugin returns a value, the last line of your plugin function must be:</p><pre><code>
return this;
</code></pre><p><code>this</code> ensures method calls can be chained, e.g.</p><pre><code>
$("div#myid").yourPlugin().anotherPlugin().yetAnotherPlugin();
</code></pre><h2>2. Make it Easy to Use</h2><p>In most cases, your plugin should simply work without the developer having to wade though documentation, set options or edit your plugin code.</p><p>If it&#8217;s a visual widget, the developer shouldn&#8217;t need to edit any JavaScript. You can simply provide HTML with a class/ID which will automatically launch your code, e.g.</p><pre><code>
&lt;section class=&quot;myjqWidget&quot;&gt;
&lt;p&gt;My content&lt;/p&gt;
&lt;/section&gt;
</code></pre><p>Your plugin can initialize itself, e.g.</p><pre><code>
$(function() {
		$(&quot;section.myjqWidget&quot;).myjqWidget();
});
</code></pre><h2>3. Use Suitable Naming and Version Control Numbers</h2><p>There are a lot of jQuery plugins. If you&#8217;re considering the name &#8220;tab&#8221; for your tab-handling plugin, there&#8217;s a strong possibility it&#8217;s been used already. That may not always matter but avoid using names which are ambiguous or likely to clash.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>Version numbering is also useful. It&#8217;s becomes especially important when developers report problems.</p><h2>4. Use a Closure</h2><p>Never depend on &#8216;$&#8217; referencing jQuery. If the developer has another library installed, it may have grabbed it before jQuery was loaded. The simplest way to solve the issue is to pass jQuery as the &#8216;$&#8217; argument for an anonymous self-starting function, e.g.</p><pre><code>
(function($) {
	// code here can use $ to reference jQuery
})(jQuery);
</code></pre><h2>5. Set Default Parameters</h2><p>Most plugins set parameters using JavaScript object literal notation, e.g.</p><pre><code>
$(&quot;#select&quot;).MyPlugin({opt1: 1, opt2: 2, opt3: &quot;three&quot;});
</code></pre><p>This has several advantages: parameters are easy to read, can be ordered in any way and omitted completely. However, you should set defaults within your plugin code and override them accordingly, e.g.</p><pre><code>
$.fn.PlugIn = function(opts) {
	// default configuration
	var config = $.extend({}, {
		opt1: 1,
		opt2: 2,
		opt3: 3,
		opt4: 4,
		opt5: 5
	}, opts);
</code></pre><p>Your plugin can then reference parameters using code such as <code>config.opt1</code>.</p><h2>6. Support HTML Parameters</h2><p>Ideally, HTML widgets should be able to set parameters without the developer needing to change JavaScript code. You could consider HTML5 data attributes, e.g.</p><pre><code>
&lt;section class=&quot;myjqWidget&quot; data-opt1=&quot;1&quot; data-opt2=&quot;two&quot;&gt;
&lt;p&gt;My content&lt;/p&gt;
&lt;/section&gt;
</code></pre><p>These can be accessed via jQuery&#8217;s data method: <code>.data(&quot;opt1&quot;)</code>.</p><h2>7. Document Your Code</h2><p>Add concise comments to the top of your plugin which describe:</p><ul><li>the plugin name and version</li><li>what the plugin does</li><li>example uses</li><li>the parameters</li><li>contact and support links</li></ul><p>If it&#8217;s particularly complex, consider a separate readme file.</p><h2>8. Test Your Plugin Thoroughly</h2><p>Test it. Then test it again. In all browsers.</p><p>There may be issues you&#8217;re not prepared to fix, e.g. IE6 compatibility problems. That&#8217;s fine, but ensure it&#8217;s mentioned within your documentation.</p><h2>9. Use a Good Template</h2><p>Here&#8217;s the template code I use when creating a new plugin:</p><pre><code>
/*!
 * jQuery plugin
 * What does it do
 */
(function($) {
	$.fn.PlugInName = function(opts) {
		// default configuration
		var config = $.extend({}, {
			opt1: null
		}, opts);
		// main function
		function DoSomething(e) {
		}
		// initialize every element
		this.each(function() {
			DoSomething($(this));
		});
		return this;
	};
	// start
	$(function() {
		$(&quot;#select&quot;).PlugInName();
	});
})(jQuery);
</code></pre><p>It provides a good starting point:</p><ul><li>The plugin is wrapped in an enclosure.</li><li>It sets default options which are overridden by plugin parameters.</li><li>Each selected element is passed to the DoSomething function as a jQuery object.</li><li><code>return this;</code> is included.</li><li>Auto-start code is provided at the end.</li></ul><h2>10. Get The Word Out</h2><p>If you want developers to use your plugin, upload it to repositories such as <a
href="http://github.com/">GitHub</a>, <a
href="http://code.google.com/">Google Code</a> and jQuery Plugin directories. Create demonstration pages, publicize it in articles and tweet about it incessantly.</p><p>Then be prepared to support the plugin and update it when necessary. You will receive dumb questions and bizarre feature requests, but that&#8217;s all part of being a successful plugin author.</p><p>Do you have any top-tips for effective jQuery plugin development?</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/10-tips-better-jquery-plugins/feed/</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>How to Create a CSS3 Ajax Loading Icon Without Images</title><link>http://www.sitepoint.com/css3-ajax-loading-icon/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=css3-ajax-loading-icon</link> <comments>http://www.sitepoint.com/css3-ajax-loading-icon/#comments</comments> <pubDate>Wed, 21 Mar 2012 17:23:47 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[CSS Tutorials]]></category> <category><![CDATA[HTML & CSS]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript & CSS]]></category> <category><![CDATA[ajax]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[HTML5 Tutorials & Articles]]></category> <category><![CDATA[icon]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=51529</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/02/642-css3-ajax-spinner-50x50.png" class="attachment-thumbnail wp-post-image" alt="642-css3-ajax-spinner" title="642-css3-ajax-spinner" />There's no need to use an old-school animated GIF for Ajax "loading" icons when you can use CSS3! Craig's demonstration shows several different effects and discusses browser support.]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/02/642-css3-ajax-spinner-50x50.png" class="attachment-thumbnail wp-post-image" alt="642-css3-ajax-spinner" title="642-css3-ajax-spinner" /><p></p><p>There&#8217;s an inevitable delay whenever your web application interacts with the server. That could be for an Ajax request, uploading a file, or using newer HTML5 APIs such as web sockets or server-sent events.</p><p>Ideally, you should give the user some feedback to indicate their action is being processed. You&#8217;ll often see small animated GIFs with rotating patterns. There are several sites which will create them for you, such as <a
href="http://preloaders.net/">preloaders.net</a> and <a
href="http://www.ajaxload.info/">ajaxload.info</a>.</p><p>Images are the best cross-browser option but they have a number of issues:</p><ul><li>GIFs do not support alpha-transparency. You need to be careful when placing the image on a colored background.</li><li>Bitmap images won&#8217;t scale nicely. If you change the dimensions, you need to create a new image.</li><li>If you&#8217;re not careful, animated graphics can have a large file size.</li><li>Images incur an additional HTTP request. While the image will be cached, the initial download may take longer than the background process it represents! You can code around this issue by pre-loading the image or using embedded data URLs but it&#8217;s more effort.</li></ul><p>Fortunately, CSS3 allows us to create loading icons without images. They&#8217;re easy to create, scale, re-color, use on any background and don&#8217;t incur image downloads. You require:<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><ol><li>A single HTML element, e.g. <code>&lt;div id=&quot;ajaxloader&quot;&gt;&lt;/div&gt;</code>.</li><li>A few CSS backgrounds, border and shading effects to create a graphical icon.</li><li>CSS3 transformations and animations to rotate or move the element.</li></ol><p><a
href="http://blogs.sitepointstatic.com/examples/tech/css3-ajax-icon/index.html"><strong>View the demonstration page&hellip;</strong></a></p><h2>Browser Compatibility</h2><p>CSS3 transformations and animations are experimental properties which require vendor prefixes &#8212; <a
href="http://www.sitepoint.com/w3c-css-webkit-prefix-crisis/">and you know what trouble they cause</a>. The example code implements the final property as well as prefixes for -webkit (Chrome and Safari), -moz (Firefox), -ms (IE), and -o (Opera), but there&#8217;s no guarantee they&#8217;ll work consistently if at all.</p><p>At the time of writing, recent versions of Chrome, Safari and Firefox offer CSS3 animations. IE9/8/7/6 and Opera show a static image, although IE10 and Opera 12 may support the properties.</p><p>Just to complicate matters further, Firefox allows you to animate pseudo elements separately. You can therefore add a couple of elements using :before and :after and rotate or move them in different directions to create more complex animations. While I&#8217;d initially hoped to do that, it doesn&#8217;t work in the webkit browsers. Chrome and Safari only allow <em>real</em> elements to be animated. It appears to be a bug or oversight, but it&#8217;s not been fixed in the current or beta releases.</p><h2>Creating the Icon</h2><p>Our HTML <code>div</code> can be placed anywhere in the document although it might be best to append it as the last child of the <code>body</code>. It will then appear above other elements and can be positioned in relation to the page.</p><p>The icon CSS simply sets wide white rounded border. The right border color is then set to transparent and a little shading is applied:</p><pre><code>
#ajaxloader
{
	position: absolute;
	width: 30px;
	height: 30px;
	border: 8px solid #fff;
	border-right-color: transparent;
	border-radius: 50%;
	box-shadow: 0 0 25px 2px #eee;
}
</code></pre><p>The result:</p><p><img
src="http://blogs.sitepointstatic.com/images/tech/642-css3-ajax-spinner1.png" width="100" height="104" alt="CSS Ajax icon 1" class="center" /></p><p>It&#8217;s easy to tweak the properties for different effects, e.g. adding <code>border-right: 0 none;</code> produces:</p><p><img
src="http://blogs.sitepointstatic.com/images/tech/642-css3-ajax-spinner2.png" width="100" height="104" alt="CSS Ajax icon 2" class="center" /></p><h2>Animating the Icon</h2><p>To make the icon spin and pulsate, we apply rotation transformations and opacity changes within a CSS3 animation. The animation name, duration, easing type and repeat are applied to the element:</p><pre><code>
#ajaxloader
{
	animation: spin 1s linear infinite;
}
</code></pre><p>followed by the animation keyframes:</p><pre><code>
@keyframes spin
{
	from { transform: rotate(0deg);   opacity: 0.2; }
	50%  { transform: rotate(180deg); opacity: 1.0; }
	to   { transform: rotate(360deg); opacity: 0.2; }
}
</code></pre><p>None of the browsers support animation without vendor prefixes so you&#8217;ll see -webkit, -moz, -ms and -o alternatives within the source code when you <a
href="http://blogs.sitepointstatic.com/examples/tech/css3-ajax-icon/index.html"><strong>view the demonstration page</strong></a>.</p><p>The icon can now be displayed using a little JavaScript whenever an Ajax request is initiated. It&#8217;s a great effect which can be customized easily and works on <a
href="http://www.sitepoint.com/browser-trends-march-2012/">55% of current browsers</a>.</p><p>Unfortunately, 45% of web users won&#8217;t see the animation. That number will fall when IE10 is released and users switch to recent versions of other browsers, but it remains a large percentage. You could fall back to an image but, if you&#8217;re doing that, you might as well use the image for all browsers.</p><p>I therefore suggest you look at your own statistics. If your visitors are are predominately using Chrome, Safari and Firefox you could adopt the technique today. If not, stick with images for now and wait a little longer for more consistent browser support.</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/css3-ajax-loading-icon/feed/</wfw:commentRss> <slash:comments>13</slash:comments> </item> <item><title>5 Things I Hate About CSS3</title><link>http://www.sitepoint.com/5-things-i-hate-about-css3/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=5-things-i-hate-about-css3</link> <comments>http://www.sitepoint.com/5-things-i-hate-about-css3/#comments</comments> <pubDate>Tue, 20 Mar 2012 18:51:13 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[CSS3]]></category> <category><![CDATA[HTML & CSS]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript & CSS]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[HTML5 Tutorials & Articles]]></category> <category><![CDATA[javascript]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=52728</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/03/657-css3-hate-50x50.png" class="attachment-thumbnail wp-post-image" alt="657-css3-hate" title="657-css3-hate" />Craig brings balance to the web development universe by listing his five biggest frustrations with CSS3.]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/03/657-css3-hate-50x50.png" class="attachment-thumbnail wp-post-image" alt="657-css3-hate" title="657-css3-hate" /><p></p><p>You knew this was coming. Yes, I still love CSS3 and use it every day &#8212; but that doesn&#8217;t mean I&#8217;m happy with everything. To counterbalance <a
href="http://www.sitepoint.com/5-things-i-love-about-css3-2/" class="broken_link">Viki Hoo&#8217;s 5 Things I Love About CSS3</a>, here are five things which frustrate me&hellip;</p><h2>1. Property Overload</h2><p>How often did you consult manuals or reference materials when writing CSS2.1 code? After learning the basics, I suspect you only required a cursory glance now and again.</p><p>Those days are gone. Perhaps it&#8217;s just me but the sheer volume of new tags is overwhelming. Even when I know a property exists it&#8217;s impossible to recall the values. Has anyone learned the all the background gradient and border image options?</p><p>While CSS3 definitely saves time, you&#8217;ll need to consult online manuals or tools every few minutes.</p><h2>2. Vendor Prefixes</h2><p>Vendor prefixes are absolutely necessary. I use them and accept it&#8217;s the price to pay for cutting-edge techniques. That doesn&#8217;t mean I have to like them. Other developers don&#8217;t either &#8212; otherwise we wouldn&#8217;t be heading for a <a
href="http://www.sitepoint.com/w3c-css-webkit-prefix-crisis/">CSS3 catastrophe</a>.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>At best, prefixes result in clunky repetition. At worst, they use completely different syntaxes. There are JavaScript and server-side pre-processors which help ease the burden but none are perfect. After all, if a property doesn&#8217;t work in a particular browser is it a problem with your CSS, the browser, or the automatic code-creation tool you&#8217;re using?</p><h2>3. Developer Tools</h2><p>It&#8217;s difficult for any IDE vendor to keep up with the rapid pace of CSS3 development. Does anyone know of an editor which supports all the new properties and syntaxes with all the vendor-prefixed differences? I don&#8217;t.</p><p>It&#8217;s not all bad; there are a number of great <a
href="http://www.sitepoint.com/7-best-css3-utilities/">online CSS3 tools</a>. However, you still won&#8217;t find many decent validators.</p><h2>4. Browser Support and W3C Politics</h2><p>Browser vendors have different priorities and release schedules. While it&#8217;s easy to pick on IE (IE9 doesn&#8217;t support text shadow), even webkit isn&#8217;t consistently ahead of the game (Chrome doesn&#8217;t support separate animation of pseudo elements). One browser will always be more capable than another, but hype and marketing often get in the way of development. How often have you assumed a browser supports property X, written some code and found it doesn&#8217;t work?</p><p>The major vendors belong to the W3C and work together to agree standards. In reality, they&#8217;re competitors:</p><ul><li>Apple has been accused of implementing iPhone/iPad-specific features which are promoted as an &#8220;HTML5 standard&#8221; but never submitted to the W3C.</li><li>The <a
href="http://www.sitepoint.com/w3c-css-webkit-prefix-crisis/">proposal to support webkit prefixes in non-webit browsers</a> could break CSS3 as we know it.</li><li>The lethargic rate of the standards approval process highlights the disagreements and political battles.</li></ul><p>It&#8217;s frustrating. Developers are caught in the crossfire but there isn&#8217;t a simple solution. And, before anyone suggests it again, dropping all but one of the rendering engines is not an option and will stagnate innovation.</p><h2>5. Silly Shim Shenanigans</h2><p>CSS3 rounded corners have save hours of time during every project. There&#8217;s no need for convoluted layouts or multiple background images. Unfortunately, they won&#8217;t work in IE8 or previous incarnations of the browser. You therefore have three options:</p><ol><li>Forget CSS3 and use traditional development techniques.</li><li>Accept that no two browsers render the same. IE8 is three years old and was released before the industry jumped on the HTML5 bandwagon. Pages viewed in IE8 will look different (and uglier) to IE9, Firefox, Chrome, Safari and Opera.</li><li>Try and make IE8 look good using JavaScript shims which normally implement old IE-specific filters.</li></ol><p>I recommend option two. You may need to educate your clients but their costs will be reduced and, ultimately, it may persuade users to upgrade their browser.</p><p>Unfortunately, I keep find sites which add a plethora of shims in a futile attempt to achieve pixel perfection. While pages may look better, it results in bulky code and IE8 often becomes frustratingly slow. I can&#8217;t believe their clients were pleased with the result.</p><h2>In Summary</h2><p>CSS3 is great. In terms of practicality, it&#8217;s progressed faster and is more useful than HTML5 or the assorted JavaScript APIs.</p><p>Browser compatibility is an issue but Viki is confident that <em>&#8220;the day they are unified will eventually come&#8221;</em>. I&#8217;m not convinced. We will reach a point when CSS3 is fully implemented but we&#8217;ll be moaning about CSS4 by then!</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/5-things-i-hate-about-css3/feed/</wfw:commentRss> <slash:comments>20</slash:comments> </item><div><div
class="post_box two_ads" style="float:left;padding-left:2px;"><div
id='div-gpt-ad-1328645237920-1' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328645237920-1'); });</script> </div></div></div><div
class="clear">&nbsp;</div> <item><title>Best Practice for Programming with Vendor Prefixes</title><link>http://www.sitepoint.com/best-practice-for-programming-with-vendor-prefixes/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=best-practice-for-programming-with-vendor-prefixes</link> <comments>http://www.sitepoint.com/best-practice-for-programming-with-vendor-prefixes/#comments</comments> <pubDate>Tue, 14 Feb 2012 13:06:13 +0000</pubDate> <dc:creator>John Hrvatin</dc:creator> <category><![CDATA[CSS Tutorials]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript & CSS]]></category> <category><![CDATA[Web Tech]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=51471</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2011/05/522-browser-trends-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="522-browser-trends" title="522-browser-trends" />In a timely article, John Hrvatin recounts how working with mutiple vendor prefixes can be made significantly easier. ]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2011/05/522-browser-trends-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="522-browser-trends" title="522-browser-trends" /><p></p><p>Vendor prefixes enable web developers to experiment with new standards before they reach the <a
href="http://www.w3.org/Consortium/Process/Process-19991111/tr.html#RecsCR">Candidate Recommendation</a> stage. I previously <a
href="http://blogs.msdn.com/b/ie/archive/2010/11/15/ie9-vendor-prefixes-and-developers.aspx">wrote</a> how these prefixes are also a mechanism browser vendors use for handling timing conflicts between implementations and specifications. In building demos of new features for our <a
href="http://ie.microsoft.com/testdrive/">IE Test Drive</a> site and in various presentations, many of us on the IE team deal extensively with vendor prefixes.</p><p>This article describes a pattern our team has used to make things significantly easier when developing with vendor prefixes.  We’d like to share it with you and hear your thoughts on this approach or any others you consider a best practice.</p><h3>Error-Prone Code</h3><p>When using script to access CSS properties with vendor prefixes, it’s easy to end up with code that looks like this:</p><pre>var elm = document.getElementById("myElement");
elm.style.msTransitionProperty = "all";
elm.style.msTransitionDuration = "3s";
elm.style.msTransitionDelay = "0s";
elm.style.webkitTransitionProperty = "all";
elm.style.webkitTransitionDuration = "3s";
elm.style.webkitTransitionDelay = "0s";
elm.style.MozTransitionProperty = "all";
elm.style.MozTransitionDuration = "3s";
elm.style.MozTransitionDelay = "0s";
elm.style.OTransitionProperty = "all";
elm.style.OTransitionDuration = "3s";
elm.style.OTransitionDelay = "0s";</pre><p>While functional, it’s bloated, ugly, and error-prone.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><h3>Consolidating Vendor-Prefixed Properties to a Single Name</h3><p>A better pattern is to define a method that loops through a list of property names and returns the first supported property or null if the browser doesn’t support any of them.</p><pre>function FirstSupportedPropertyName(prefixedPropertyNames) {
    var tempDiv = document.createElement("div");
    for (var i = 0; i &lt; prefixedPropertyNames.length; ++i) {
        if (typeof tempDiv.style[prefixedPropertyNames[i]] != 'undefined')
            return prefixedPropertyNames[i];
    }
    return null;
}</pre><p>We then initialize a variable for each vendor-prefixed property we use, passing it an array of possible properties in the order we prefer to use them.</p><pre>var transformName = FirstSupportedPropertyName(["transform", "msTransform", "MozTransform", "WebkitTransform", "OTransform"]);
var backfaceVisibilityName = FirstSupportedPropertyName(["backfaceVisibility", "msBackfaceVisibility", "MozBackfaceVisibility", "WebkitBackfaceVisibility", "OBackfaceVisibility"]);
var transitionName = FirstSupportedPropertyName(["transition", "msTransition", "MozTransition", "WebkitTransition", "OTransition"]);
var animationName = FirstSupportedPropertyName(["animation", "msAnimation", "MozAnimation", "WebkitAnimation", "OAnimation"]);
var gridName = FirstSupportedPropertyName(["gridRow", "msGridRow", "MozGridRow", "WebkitGridRow", "OGridRow"]);
var regionsName = FirstSupportedPropertyName(["flowFrom", "msFlowFrom", "MozFlowFrom", "WebkitFlowFrom", "OFlowFrom"]);
var hyphensName = FirstSupportedPropertyName(["hyphens", "msHyphens", "MozHyphens", "WebkitHyphens", "OHyphens"]);
var columnName = FirstSupportedPropertyName(["columnCount", "msColumnCount", "MozColumnCount", "WebkitColumnCount", "OColumnCount"]);</pre><p>Then code throughout your site that uses these properties becomes something like this:</p><pre>var elm = document.getElementById("myElement");
if (transitionName) {
    elm.style[transitionName + "Property"] = "all";
    elm.style[transitionName + "Duration"] = "3s";
    elm.style[transitionName + "Delay"] = "0s";
}
else {
    // fallback for browsers without CSS3 transitions
}</pre><p>Note the simple <a
href="http://blogs.msdn.com/b/ie/archive/2010/04/14/same-markup-writing-cross-browser-code.aspx">feature detection</a> enabled by returning <code>null</code> in <code>FirstSupportedPropertyName</code>.</p><p>That pattern also works when CSS <em>properties </em>have vendor prefixes. You can use a slightly different pattern for cases where a CSS <em>value </em>(for example, linear-gradient) has vendor prefixes:</p><pre>function FirstSupportedFunctionName(property, prefixedFunctionNames, argString) {
    var tempDiv = document.createElement("div");
    for (var i = 0; i &lt; prefixedFunctionNames.length; ++i) {
        tempDiv.style[property] = prefixedFunctionNames[i] + argString;
        if (tempDiv.style[property] != "")
            return prefixedFunctionNames[i];
    }
    return null;
}
var linearGradientName = FirstSupportedFunctionName("backgroundImage", ["-ms-linear-gradient", "-moz-linear-gradient", "-webkit-linear-gradient", "-o-linear-gradient"], "(top, black, white)");
var radialGradientName = FirstSupportedFunctionName("backgroundImage", ["-ms-radial-gradient", "-moz-radial-gradient", "-webkit-radial-gradient", "-o-radial-gradient"], "(50% 50%, circle cover, black, white)");</pre><h3>Testing Sites that Use Vendor-Prefixed Properties</h3><p>A common question is what property names to use if some browsers don’t yet support the property or if no browser supports the standards-based property without a prefix. There are a couple approaches, each with merit:</p><ol><li><strong>Always include all expected names, even if they don’t yet work in shipping browsers. </strong>The benefit of this path is that as browsers add support with their vendor prefix or add support for the non-prefixed property, your site will “just work” without changes. The risk is that the site will automatically pick up behavior you’ve never tested. A vendor prefix indicates the behavior isn’t finalized and all prefixed properties and the non-prefixed property may not behave the same, so as browsers add support your site might “just <em>not</em> work.”</li><li><strong>Only include property names you can test.</strong> The benefit is that your site will behave the same as when you first wrote it even as browsers add support for new properties. The risk is that you have unnecessarily degraded functionality. For sample or demo sites, people can interpret this as a browser not having a feature at all.</li></ol><p>You need to determine the right path for your site. In most of our demos we want to show off new web platform functionality in any browser that supports it. And since small errors in these demos don’t create big problems for users, we usually choose option #1. On the other hand, if you have a production site where a change in behavior will cause a problem for your business, you may opt for the more risk-averse path.</p><p>Regardless of which path you choose, the one constant is testing. When using vendor-prefixed properties you’re leveraging early, often unstable functionality that can change even after a browser first introduces support for a property, so it’s critical to test with each browser update to make sure your site functions as expected.</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/best-practice-for-programming-with-vendor-prefixes/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Take the jQuery Ninja Test</title><link>http://www.sitepoint.com/take-the-jquery-ninja-test/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=take-the-jquery-ninja-test</link> <comments>http://www.sitepoint.com/take-the-jquery-ninja-test/#comments</comments> <pubDate>Mon, 13 Feb 2012 11:34:36 +0000</pubDate> <dc:creator>Mick Gibson</dc:creator> <category><![CDATA[JavaScript]]></category> <category><![CDATA[JavaScript & CSS]]></category> <category><![CDATA[jQuery]]></category> <category><![CDATA[Tech]]></category> <category><![CDATA[Tutorial]]></category> <category><![CDATA[Tutorials]]></category> <category><![CDATA[jQuery Tutorials & Articles]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=51131</guid> <description><![CDATA[<img
width="38" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/02/jquery21-38x50.png" class="attachment-thumbnail wp-post-image" alt="jQuery: Novice to Ninja, 2nd Edition - New Kicks and Tricks" title="jQuery: Novice to Ninja, 2nd Edition - New Kicks and Tricks" />As part of the launch of our latest book <a
href="http://www.sitepoint.com/launch/f7066a"><em>jQuery: Novice to Ninja, 2nd Edition. — New Kicks and Tricks</em></a> we're laying down the challenge for all of you to test your jQuery knowledge.]]></description> <content:encoded><![CDATA[<img
width="38" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/02/jquery21-38x50.png" class="attachment-thumbnail wp-post-image" alt="jQuery: Novice to Ninja, 2nd Edition - New Kicks and Tricks" title="jQuery: Novice to Ninja, 2nd Edition - New Kicks and Tricks" /><p></p><p><img
class="alignleft size-medium wp-image-51136" src="http://www.sitepoint.com/wp-content/uploads/2012/02/jquery21-88x115.png" alt="jQuery: Novice to Ninja, 2nd Edition - New Kicks and Tricks" width="88" height="115" /></p><p>Hey there, all you JavaScript and jQuery wannabes!</p><p>As part of the launch of our latest book &#8220;<em><a
href="http://www.sitepoint.com/launch/f7066a">jQuery: Novice to Ninja, 2nd Edition. — New Kicks and Tricks</a></em>&#8221; we&#8217;re laying down the challenge for all of you to test your jQuery knowledge. Below, you&#8217;ll see a screenshot of the first of nine sets of questions from our jQuery Ninja Test.</p><p><a
href="http://www.sitepoint.com/quiz-jquery/"><img
class="aligncenter size-full wp-image-51132" src="http://www.sitepoint.com/wp-content/uploads/2012/02/Screen-shot-2012-02-07-at-4.09.09-PM.png" alt="Take the Quiz" width="569" height="398" /></a><strong><a
href="http://www.sitepoint.com/quiz-jquery/">Take the test</a></strong>, <strong>and see if you can attain jQuery Ninja status!</strong></p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/take-the-jquery-ninja-test/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>The Impending CSS Vendor Prefix Catastrophe</title><link>http://www.sitepoint.com/w3c-css-webkit-prefix-crisis/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=w3c-css-webkit-prefix-crisis</link> <comments>http://www.sitepoint.com/w3c-css-webkit-prefix-crisis/#comments</comments> <pubDate>Mon, 13 Feb 2012 10:35:42 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[Discussion]]></category> <category><![CDATA[HTML & CSS]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript & CSS]]></category> <category><![CDATA[News & Trends]]></category> <category><![CDATA[Opinion]]></category> <category><![CDATA[browser]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[standards]]></category> <category><![CDATA[vendor prefixes]]></category> <category><![CDATA[w3c]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=51435</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/02/641-css-vendor-prefix-crisis-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="641-css-vendor-prefix-crisis" title="641-css-vendor-prefix-crisis" />Vendors may be adding CSS3 -webkit prefixes to their non-webkit browsers. Craig discusses why it's being considered by the W3C and why it should be prevented.]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/02/641-css-vendor-prefix-crisis-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="641-css-vendor-prefix-crisis" title="641-css-vendor-prefix-crisis" /><p></p><p>Developers have a love-hate relationship with CSS vendor prefixes. They allow us to use bleeding-edge technologies at the expense of long-winded declarations:</p><pre><code>
background-image: -webkit-linear-gradient(#fff, #000);
background-image: -moz-linear-gradient(#fff, #000);
background-image: -ms-linear-gradient(#fff, #000);
background-image: -o-linear-gradient(#fff, #000);
background-image: linear-gradient(#fff, #000);
</code></pre><p>It works well in theory but consider what happens in the wild:</p><ol><li>Experimental properties are often implemented in the webkit engine first and there&#8217;s no guarantee they&#8217;ll be replicated in other browsers.</li><li>It&#8217;s often difficult to determine whether a vendor-prefixed property is part of the CSS specification. Some vendors don&#8217;t submit properties for standardization.</li><li>Even if the standard property changes, the incorrect vendor-prefixed version continues to be supported. Your old code still works; you won&#8217;t revisit it to correct the implementation.</li></ol><p>You&#8217;ll often find sites using the -webkit prefixes alone &#8212; even if other browsers support the property or it has widespread availability without a prefix (such as <code>border-radius</code>). Chrome and Safari therefore look better than competing browsers &#8212; <em>and the other vendors aren&#8217;t happy</em>.</p><p>The issue was raised and discussed in the <a
href="http://lists.w3.org/Archives/Public/www-style/2012Feb/0313.html">W3C meeting on February 7, 2012</a>:<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><blockquote><p> Web standards activists are teaching people to use webkit. You will see presentations from all the web standards advocates advocating people to use webkit prefixes.</p><p>Our job is to solve interoperability.</p><p>At this point we&#8217;re trying to figure out which and how many webkit prefix properties to actually implement support for in Mozilla.</p><p>If we don&#8217;t support webkit prefixes, we are locking ourselves out of parts of the mobile web.</p></blockquote><p>Let that sink in for a moment.</p><p>Non-webkit browsers will support the -webkit prefix. That is the solution being considered by the W3C.</p><p>The idea is likely to fail miserably. Two or more implementations of the same webkit property won&#8217;t be compatible so developers won&#8217;t be able to use it anywhere. No one wins &#8212; including Apple and Google.</p><p>But I&#8217;m more concerned about the irreparable damage it&#8217;ll cause if the solution <em>is</em> successful. Once developers discover webkit prefixes working in Firefox, IE and Opera, they&#8217;ll expect them to work on all properties. Webkit-only adoption will rise exponentially and the vendors will be forced to implement the prefixes throughout. At that point, webkit properties will become the de facto standard regardless of any W3C specification. Game over: the open web is closed.</p><p>The implications also go further than CSS: many of the new JavaScript APIs have vendor prefixes.</p><h2>Who&#8217;s to Blame?</h2><p>We can point the sticky finger of failure at:</p><p><strong>The W3C Working Group</strong><br
/> It takes too long for web standards to reach maturity. That may be unavoidable but browser vendors are bypassing the process.</p><p><strong>Browser Vendors</strong><br
/> In their rush to push new technologies, it&#8217;s too easy for vendors to add a prefix and forget about it. Web developers require more information: is the property being considered by the W3C and when will the prefix be dropped?</p><p>In an ideal world, experimental prefixes would disappear once the browser implements the standard property. Vendors won&#8217;t do that because it&#8217;d break sites, but they could do more to highlight the problem, e.g. provide obsolescence detection tools or output error messages to the developer console.</p><p><strong>Apple and Google</strong><br
/> Both are guilty of promoting webkit prefixes as though they&#8217;re a standard part of day-to-day HTML5 web development. Apple has been accused of actively working against the W3C.</p><p><strong>Mozilla, Microsoft and Opera</strong><br
/> Other vendors are often months behind the webkit browsers &#8212; if not years. Adding webkit prefixes is a ludicrous solution: it&#8217;s time to up their game.</p><p><strong>Technology Websites and Evangelists</strong><br
/> We all love cool demonstrations but evangelists often neglect to mention that properties are experimental and may never have full browser support <em>(and, yes, that includes SitePoint)</em>. Ideally, code should work in at least two browsers; at least it would indicate that multiple vendor prefixes are required.</p><p><strong>Web Developers</strong><br
/> We&#8217;re too lazy. We&#8217;re writing browser-specific code and, while we may have good intentions about correcting it later, we rarely do.</p><p>Do you recall the last time developers targeted a specific browser? <strong>It was IE6.</strong> We&#8217;re still living with the legacy of that decision a decade later. Do you really want history to repeat itself?</p><h2>It&#8217;s Time to Act</h2><p>I&#8217;m opposed to non-webkit browsers supporting webkit prefixes. At best, it makes prefixes unusable. At worst, it breaks the whole standardization process. You may agree or disagree but make your opinion known to colleagues, in blogs and on social networks. The W3C and browser vendors will listen to your feedback; you just need to provide some.</p><p>Then test your site in multiple browsers. A little graceful degradation is fine but neglecting one or more modern browsers with equivalent support is not. Fix the code, otherwise your site is contributing to the problem.</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/w3c-css-webkit-prefix-crisis/feed/</wfw:commentRss> <slash:comments>53</slash:comments> </item> <item><title>The JS1k Competition Returns</title><link>http://www.sitepoint.com/js1k-competition-2012/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=js1k-competition-2012</link> <comments>http://www.sitepoint.com/js1k-competition-2012/#comments</comments> <pubDate>Sat, 11 Feb 2012 15:01:28 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[Gems]]></category> <category><![CDATA[HTML & CSS]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[JavaScript & CSS]]></category> <category><![CDATA[canvas]]></category> <category><![CDATA[competition]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[HTML5 Tutorials & Articles]]></category> <category><![CDATA[javascript]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=51352</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/02/640-1k-javascript-returns-50x50.png" class="attachment-thumbnail wp-post-image" alt="640-1k-javascript-returns" title="640-1k-javascript-returns" />The JS1K competition is back! What amazing demonstrations and applications can you create in 1 Kilobyte of JavaScript code?]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/02/640-1k-javascript-returns-50x50.png" class="attachment-thumbnail wp-post-image" alt="640-1k-javascript-returns" title="640-1k-javascript-returns" /><p></p><p>The <a
href="http://js1k.com/2012-love/">js1k</a> competition is back. While it may have started as a joke, it continues to attract amazing entries from JavaScript ninjas eager to demonstrate their coding prowess.</p><p>The competition &#8212; code named <em>Love &#8217;12</em> &#8212; runs until midnight on March 14, 2012. There are various cash prizes for the winners and the rules remain simple:</p><ul><li>You may submit as many entries as you like but only one submission per person will be entered in the competition.</li><li>You must provide a JavaScript code of no more than 1,024 bytes (that&#8217;s not necessarily characters).</li><li>An <a
href="http://js1k.com/2012-love/shim.html">HTML5 page is provided</a> which contains a single canvas tag, some set-up variables and a <code>script</code> tag for your code. You don&#8217;t need to use canvas or the variables although most entries do.</li><li>Minification is permitted but it must not change your original variable names.</li><li>Loading external resources, libraries, frames or other sites is forbidden. You&#8217;ll be found out so don&#8217;t bother trying!</li><li>Your code must run in the latest versions of <a
href="http://www.sitepoint.com/firefox-10-whats-new/">Firefox</a>, <a
href="http://www.sitepoint.com/whats-new-in-chrome-17/">Chrome</a>, Opera and Safari. Preferably, it&#8217;ll run in IE9/10 too but that&#8217;s not essential since the browsers are only available on recent editions of Windows.</li><li>Your code should behave itself, not cause crashes and behave equally well in all browsers.</li></ul><p>The theme of &#8220;Love&#8221; is suggested but it&#8217;s not a requirement <em>(there are far too many animated hearts already!)</em> My favorites so far include:<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><ul><li><a
href="http://js1k.com/2012-love/demo/1019">Chain Reaction</a></li><li><a
href="http://js1k.com/2012-love/demo/1048">1K Minesweeper</a></li><li><a
href="http://js1k.com/2012-love/demo/1022">A Rose is a Rose</a></li><li><a
href="http://js1k.com/2012-love/demo/1004">Campsite Firefighter</a></li><li><a
href="http://js1k.com/2012-love/demo/1001">Funky Fabric</a></li></ul><p>What are you waiting for? Happy coding and feel free to post a link to your submissions in the comments section below&hellip;</p><p>See also: <a
href="http://www.sitepoint.com/1-kilobyte-css-gallery/"><em>What can YOU do with 1 Kilobyte of CSS?</em></a></p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/js1k-competition-2012/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Build Awesome Apps with CSS3 Animations</title><link>http://www.sitepoint.com/build-awesome-apps-with-css3-animations/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=build-awesome-apps-with-css3-animations</link> <comments>http://www.sitepoint.com/build-awesome-apps-with-css3-animations/#comments</comments> <pubDate>Fri, 03 Feb 2012 13:25:28 +0000</pubDate> <dc:creator>David Rousset</dc:creator> <category><![CDATA[CSS Tutorials]]></category> <category><![CDATA[HTML & CSS]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript & CSS]]></category> <category><![CDATA[Web Tech]]></category> <category><![CDATA[animation]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=51035</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/02/feature1-50x50.png" class="attachment-thumbnail wp-post-image" alt="feature" title="feature" />Today’s HTML5 applications can provide awesome experiences thanks partly  to CSS3 specifications like Animations. David Rousset walks you (and a Star Wars AT-AT) through the motions.]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/02/feature1-50x50.png" class="attachment-thumbnail wp-post-image" alt="feature" title="feature" /><p></p><p>Today’s HTML5 applications can provide awesome experiences thanks to the new CSS3 specifications. One of them is <strong>CSS3 Animations</strong>. It can help you building rich animations on HTML elements. This can provide interesting feedbacks to the users and enables fast &amp; fluid UIs. As those new animations are most of the time hardware accelerated by the GPU, they definitely raise the quality bar of the new generation of HTML5 applications.</p><p>According to the “CSS Animation Module Level 3” specification on the <a
href="http://www.w3.org/TR/css3-animations/">W3C site</a>, CSS3 Animations <em>introduces defined animations, which specify the values that CSS properties will take over a given time interval. This specification is an extension to CSS Transitions</em>.</p><p>As CSS3 Animation is an <strong>extension to CSS3 Transitions</strong>, you should first read the article of my colleague David Catuhe on Transitions here: <a
href="http://blogs.msdn.com/b/eternalcoding/archive/2011/11/01/css3-transitions.aspx">Introduction to CSS3 Transitions</a>.</p><p>We’ll see in this article an interesting demo highlighting the potential of CSS3 animations, how to build simple animations &amp; how to handle fallback in JavaScript:</p><ol
start="1"><li><a
href="http://blogs.msdn.com/b/davrous/archive/2011/12/06/introduction-to-css3-animations.aspx#intro">CSS3 Animations</a></li><li><a
href="http://blogs.msdn.com/b/davrous/archive/2011/12/06/introduction-to-css3-animations.aspx#support">Browsers Support</a></li><li><a
href="http://blogs.msdn.com/b/davrous/archive/2011/12/06/introduction-to-css3-animations.aspx#fallback">CSS3 Animations JavaScript fallback library</a></li><li><a
href="http://blogs.msdn.com/b/davrous/archive/2011/12/06/introduction-to-css3-animations.aspx#conclusion">Conclusion</a></li></ol><p>Let’s first start by quickly demonstrating what CSS3 Animations are. Here is a sample animation of a Star Wars AT-AT which uses CSS3 Animations to animate parts of the transport (and which will fall back to JavaScript if your browser doesn’t support CSS3 Animations):<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p><iframe
style="border-width: 0px; border-style: solid; border-color: #ffffff;" src="http://david.blob.core.windows.net/html5/css3atat/index.htm" scrolling="no" width="716" height="570"></iframe></p><p>You can test this sample also in a separate window here: <a
title="http://david.blob.core.windows.net/html5/css3atat/index.htm" href="http://david.blob.core.windows.net/html5/css3atat/index.htm">http://david.blob.core.windows.net/html5/css3atat/index.htm</a></p><p><strong><span
style="text-decoration: underline;">Note:</span></strong> this sample has been tested successfully with native animations under IE10 PP3/PP4, Chrome 15, Firefox 8 &amp; iPad 2 and with JS fallback under IE9 desktop &amp; mobile (Windows Phone). For an unknown reason, it behaves in weird way under Opera 11.50 but works fine with the 11.60. Moreover, our lovely blogging platform is most of the time forcing the IE9 rendering engine via a meta tag. To force it back to the IE10 standards mode, press the F12 key and change the value of “Document Mode” back to IE10. Otherwise, view the demo in a separate window.</p><p>This sample is based on the awesome work done by <a
href="http://twitter.com/acalzadilla">Anthony Calzadilla</a>. You can check other incredible demos on his website here: <a
href="http://www.anthonycalzadilla.com/">http://www.anthonycalzadilla.com</a> . I’m a huge fan of the <a
href="http://www.anthonycalzadilla.com/i-twitty-the-fool/">I twitty the fool</a> sample using SVG &amp; CSS3 Animation for instance.</p><h3>CSS3 Animations</h3><h4>Introduction</h4><p>Let’s first review on what you can play to build the animations. CSS3 Animations works basically on the same values as CSS3 Transition.</p><p>Here they are:</p><ul><li><strong>color</strong>: interpolated via red, green, blue and alpha components (treating each as a number, see below)</li><li><strong>length</strong>: interpolated as real numbers.</li><li><strong>percentage</strong>: interpolated as real numbers.</li><li><strong>integer</strong>: interpolated via discrete steps (whole numbers). The interpolation happens in real number space and is converted to an integer using floor().</li><li><strong>number</strong>: interpolated as real (floating point) numbers.</li><li><strong>transform list</strong>: see CSS Transforms specification: <a
href="http://www.w3.org/TR/css3-2d-transforms/">http://www.w3.org/TR/css3-2d-transforms/</a></li><li><strong>rectangle</strong>: interpolated via the x, y, width and height components (treating each as a number).</li><li><strong>visibility</strong>: interpolated via a discrete step. The interpolation happens in real number space between 0 and 1, where 1 is &#8220;visible&#8221; and all other values are &#8220;hidden&#8221;.</li><li><strong>shadow</strong>: interpolated via the color, x, y and blur components (treating them as color and numbers where appropriate). In the case where there are lists of shadows, the shorter list is padded at the end with shadows whose color is transparent and all lengths (x, y, blur) are 0.</li><li><strong>gradient</strong>: interpolated via the positions and colors of each stop. They must have the same type (radial or linear) and same number of stops in order to be animated.</li><li><strong>paint server</strong> (SVG): interpolation is only supported between: gradient to gradient and color to color. They then work as above.</li><li><strong>space-separated list of above</strong>: If the lists have the same number of items, each item in the list is interpolated using the rules above. Otherwise, no interpolation.</li><li><strong>a shorthand property</strong>: If all the parts of a shorthand can be animated, then interpolation is performed as if each property was individually specified.</li></ul><p>And the following properties must be supported for animations:</p><ul><li>background-color (<em>color</em>)</li><li>background-image (<em>only gradients</em>)</li><li>background-position (<em>percentage and length</em>)</li><li>border-bottom-color (<em>color</em>)</li><li>border-bottom-width (<em>length</em>)</li><li>border-color (<em>color</em>)</li><li>border-left-color (<em>color</em>)</li><li>border-left-width (<em>length</em>)</li><li>border-right-color (<em>color</em>)</li><li>border-right-width (<em>length</em>)</li><li>border-spacing (<em>length</em>)</li><li>border-top-color (<em>color</em>)</li><li>border-top-width (<em>length</em>)</li><li>border-width (<em>length</em>)</li><li>bottom (<em>length and percentage</em>)</li><li>color (<em>color</em>)</li><li>crop (<em>rectangle</em>)</li><li>font-size (<em>length and percentage</em>)</li><li>font-weight (<em>number</em>)</li><li>grid-* (<em>various</em>)</li><li>height (<em>length and percentage</em>)</li><li>left (<em>length and percentage</em>)</li><li>letter-spacing (<em>length</em>)</li><li>line-height (<em>number, length and percentage</em>)</li><li>margin-bottom (<em>length</em>)</li><li>margin-left (<em>length</em>)</li><li>margin-right (<em>length</em>)</li><li>margin-top (<em>length</em>)</li><li>max-height (<em>length and percentage</em>)</li><li>max-width (<em>length and percentage</em>)</li><li>min-height (<em>length and percentage</em>)</li><li>min-width (<em>length and percentage</em>)</li><li>opacity (<em>number</em>)</li><li>outline-color (<em>color</em>)</li><li>outline-offset (<em>integer</em>)</li><li>outline-width (<em>length</em>)</li><li>padding-bottom (<em>length</em>)</li><li>padding-left (<em>length</em>)</li><li>padding-right (<em>length</em>)</li><li>padding-top (<em>length</em>)</li><li>right (<em>length and percentage</em>)</li><li>text-indent (<em>length and percentage</em>)</li><li>text-shadow (<em>shadow</em>)</li><li>top (<em>length and percentage</em>)</li><li>vertical-align (<em>keywords, length and percentage</em>)</li><li>visibility (<em>visibility</em>)</li><li>width (<em>length and percentage</em>)</li><li>word-spacing (<em>length and percentage</em>)</li><li>z-index (<em>integer</em>)</li><li>zoom (<em>number</em>)</li></ul><h4>SVG</h4><p>The properties of SVG objects are animatable when they are defined as <strong>animatable:true</strong> in the SVG specification: <a
href="http://www.w3.org/TR/SVG/struct.html">http://www.w3.org/TR/SVG/struct.html</a>. But at the time where this article is written, I didn’t manage to combine CSS3 Animation directly on SVG elements in any of the latest browsers versions. Today’s samples on the web are then doing a little trick: they are embedding SVG resources into different DIV animated by CSS3 like the <a
href="http://www.anthonycalzadilla.com/i-twitty-the-fool/">I twitty the fool</a> sample.</p><h4>Declarations</h4><p>To declare an animation in a CSS file, here is the kind of generic code you’ll need to write:</p><pre>@keyframes name_of_the_animation {
  from {
    property_to_animate: initial_value;
  }
  50% {
    property_to_animate: intermediate_value;
  }
  to {
    property_to_animate: final_value;
  }
}</pre><p>Which could also be written like that:</p><pre>@keyframes name_of_the_animation {
  0% {
    property_to_animate: initial_value;
  }
  50% {
    property_to_animate: intermediate_value;
  }
  100% {
    property_to_animate: final_value;
  }
}</pre><p>This animation definition declares 3 steps 0, 50 &amp; 100%. You should at least set a <strong><em>from</em></strong> (or 0%) and a <strong><em>to</em></strong> (or 100%) steps to build a correct animation (minimum 2 steps thus). Once done, you may add as many keyframes as you’d like between 0 and 100% to handle precisely the various steps of your animations.</p><p>Once the definition is declared, you can affect it to an element using the classical CSS3 selectors and you’ll need also to configure the animation options. Here the kind of generic blocks you’ll see:</p><pre>#id_of_the_html_element {
    animation-name: name_of_the_animation;
    animation-duration: number_of_seconds s;
    animation-iteration-count: number | infinite;
}</pre><p>To better understand, let’s review a real sample. First of all, as the CSS3 Animations specification is still in a draft stage, you’ll need to use the appropriate vendor prefix. Let’s use IE10 as a sample with the –ms prefix then. Let’s now see how the head of our AT-AT is moving.</p><p>Here’s the animation declaration:</p><pre>@-ms-keyframes rotate-skull {
    0% {
        -ms-transform: rotate(0deg)
    }
    25% {
        -ms-transform: rotate(15deg)
    }
    50% {
        -ms-transform: rotate(-5deg)
    }
    55% {
        -ms-transform: rotate(0deg)
    }
    75% {
        -ms-transform: rotate(-10deg)
    }
    100% {
        -ms-transform: rotate(0deg)
    }
}</pre><p>We’ve got 6 steps (0, 25, 50, 55, 75 &amp; 100%) working on the CSS3 2D transform attributes by changing the value of the rotation.</p><p>The animation is then applied via this CSS rule:</p><pre>#skull
{
    -ms-animation-name: rotate-skull;
    -ms-animation-duration: 7s;
    -ms-animation-iteration-count: infinite;
}</pre><p>We’re targeting the <code>&lt;div&gt;</code> element having the “<code>id=<strong>skull</strong></code>” and we’re applying the animation named “<strong><code>rotate-skull</code></strong>” on it. The animation will have to be completed in <strong>7s</strong> and be played an <strong>infinite</strong> number of times.</p><p>Here is the living result if your browser supports CSS3 Animations:</p><p><iframe
style="border: #ffffff 0px solid;" src="http://david.blob.core.windows.net/html5/css3atat/AnimSkullATAT.htm" scrolling="no" width="400" height="200"></iframe></p><p>We could have written this rule in a shorter manner using the animation shorthand property:</p><pre>#skull {
    -ms-animation: rotate-skull 7s infinite;
}</pre><p>The animations will be triggered as soon as a matching rule is applied. You can then play or stop animations simply via <strong>JavaScript</strong> or via CSS3 to play with the <strong>classes affected to a tag</strong>.</p><h4>Non-linear animations</h4><p>The “animation-timing-function” property can be used if you want non-linear animations. You can even mix the type of timing functions during each keyframe.</p><p>Basically, CSS3 animations will use <a
href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve#Cubic_B.C3.A9zier_curves">cubic bezier curve</a> to smooth the animation by computing different speed over its duration.</p><p>The following functions are supported:</p><ul><li><em>linear</em>: Constant speed</li><li><em>cubic-bezier</em>: Speed will be computed according to a cubic bezier curve define by two control points : P0 and P1 (so you will have to define 4 values here : P0x, P0y and P1x, P1y.</li><li><em>ease</em>: Speed will be computed with cubic-bezier(0.25, 0.1, 0.25, 1)</li><li><em>ease-in</em>: Speed will be computed with cubic-bezier(0.42, 0, 1, 1)</li><li><em>ease-inout</em>: Speed will be computed with cubic-bezier(0.42, 0, 0.58, 1)</li><li><em>ease-out</em>: Speed will be computed with cubic-bezier(0, 0, 0.58, 1)</li></ul><p>Here is a simulation tool written by <a
href="http://blogs.msdn.com/b/eternalcoding/archive/2011/11/01/css3-transitions.aspx">David Catuhe</a> that uses pure JavaScript to show the impact of each timing function:</p><p><iframe
style="border: #ffffff 0px solid;" src="http://www.catuhe.com/msdn/transitions/easingfunctions.htm" width="1000" height="650"></iframe></p><p><strong><span
style="text-decoration: underline;">Note:</span></strong> this tool uses in-line SVG supported by Firefox, Chrome, Opera 11.60 &amp; IE9/10. It won’t work properly under Opera 11.50 &amp; Safari on iPad thus.</p><p>This is an awesome tool using SVG. You can even play with your mouse on the custom function to edit the curve. If you’d like to know more about this tool, please again have a look to David’s article.</p><p>If your browser supports CSS3 animations, let’s now see a simple demo using <strong>easing functions to animate a canvas tag</strong> containing an animated sprite with CSS3.</p><p>Here is the CSS3 animations code that will be used in this demo:</p><pre>@-ms-keyframes demo {
    from {
    -ms-animation-timing-function: ease;
    -ms-transform: translateX(0px);
    }
    50% {
    -ms-animation-timing-function: ease-in;
    -ms-transform: translateX(300px);
    }
    to {
    -ms-animation-timing-function: ease-inout;
    -ms-transform: translateX(900px);
    }
}
#testCanvas
{
    -ms-animation-delay: 0s;
    -ms-animation-duration: 6s;
    -ms-animation-iteration-count: infinite;
    -ms-animation-name: demo;
}</pre><p>As well as all the vendor prefixes variations to make sure it works also in Google Chrome &amp; Mozilla Firefox. And here’s the living output:</p><p><iframe
style="border: #ffffff 0px solid;" src="http://david.blob.core.windows.net/html5/css3animcanvas/sprites.htm" width="1000" height="90"></iframe></p><p>If your browser doesn’t support CSS3 Animation but support canvas, the sprite’s running animation should be displayed but the character won’t move through the width of the screen.</p><p><strong><span
style="text-decoration: underline;">Note:</span></strong> if you’d like to know more about canvas and sprites animation, you can have a look to this article: <a
href="http://blogs.msdn.com/b/davrous/archive/2011/07/21/html5-gaming-animating-sprites-in-canvas-with-easeljs.aspx">HTML5 Gaming: animating sprites in Canvas with EaselJS</a></p><h4>Delay</h4><p>The “animation-delay” property simply allows an animation to begin execution some time after it is applied.</p><h4>Events</h4><p>3 <strong>events</strong> could be raised during an animation. They are named “Animation<em>Start</em>”, “Animation<em>End</em>” and “Animation<em>Iteration</em>”. Depending on your browser, the correct name will be for instance:</p><ul><li>Chrome:<em> webkitAnimationEnd</em></li><li>Firefox: <em>mozAnimationEnd</em></li><li>Internet Explorer:<em> MSAnimationEnd</em></li></ul><p>The event will give you the following details:</p><ul><li><em>animationName</em>: name of the animation which raised the event</li><li><em>elapsedTime</em>: the amount of time the animation has been running, in seconds</li></ul><p>Here is an usage sample for IE10:</p><pre>elementToAnimate.addEventListener("MSAnimationEnd", function () {
    alert("the end !");
}, false);</pre><h3>More about CSS3 animations</h3><p>CSS3 animations are really useful for 2 main reasons:</p><ul><li><strong>Hardware acceleration:</strong> CSS3 Animations are most of the time directly handled by the GPU and could produce smoother results. This could then be a very interesting approach for mobile devices.</li><li><strong>Better separation between code and design</strong>: I know there is some debates on this point but with David, we think that a developer shouldn’t be aware of animations or anything related to design as much as possible. In the same way the designer/artist must not be aware of JavaScript. CSS3 offers then this possibility and could let the designers work with their classical tools to generate the appropriate animations on elements, between screens, etc.</li></ul><p>To highlight this importance in performance, the following HTML5 game I wrote using a full frame &lt;canvas&gt;: <a
title="http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-the-complete-port-of-the-xna-game-to-lt-canvas-gt-with-easeljs.aspx" href="http://blogs.msdn.com/b/davrous/archive/2011/09/09/html5-platformer-the-complete-port-of-the-xna-game-to-lt-canvas-gt-with-easeljs.aspx">HTML5 Platformer</a> run at 60 fps in IE9/IE10 on my PC but at 10 fps max on a iPad 2. This is because its CPU is much more limited and the iPad is currently not hardware-accelerating &lt;canvas&gt;. Using CSS3 Transitions/Animations to animate several smaller &lt;canvas&gt; elements could provide a huge performance boost for this game. Think about it when you’re targeting mobile devices!</p><h3>Browsers Support</h3><p>Since the Platform Preview 3 of IE10 available in the <a
href="http://msdn.microsoft.com/en-us/windows/apps/br229516">Windows Developer Preview</a>, we’re supporting CSS3 Animations. And as you can see on the following report produced by <a
href="http://caniuse.com/#search=CSS3%20animation">caniuse.com</a>, the CSS3 animations are now supported on a wide range of browsers:</p><p><img
class="alignnone size-full wp-image-51037" title="fig2" src="http://www.sitepoint.com/wp-content/uploads/2012/02/fig2.png" alt="browser support" width="761" height="275" /></p><p>But as the specification is not finished yet (<em>working draft</em>), you must use vendor’s prefixes such as –ms-, –moz-, –webkit-, –o- to make a cross-browsers compatible application.</p><p>But the question could be: how to handle browsers that don’t support this new feature?</p><p>First option is to just do nothing. Thanks to the beauty of graceful degradation, you could just let the user only see a static image if you’ve worked correctly. This is for instance the case of these 2 original samples of Anthony: <a
href="http://www.anthonycalzadilla.com/i-twitty-the-fool/">I Twitty the Fool!</a> and <a
href="http://www.anthonycalzadilla.com/css3-ATAT/">Pure CSS3 AT-AT Walker</a> . When watched in IE9, it looks like we only have a static image. When watched in IE10, the very same code shows nice animations. IE10 users will then have an enhanced version while IE9 will still be able to view and use properly the website. The more modern your browser is, the more visual bonus you will have.</p><p>The second option is to detect the feature via a JS library like Modernizr and try to offer the same animation via a JavaScript library that will mimic the animations. This is what we usually call a fallback mechanism. Unfortunately, I haven’t found today a working &amp; complete JS library that could replace CSS3 animations when not supported by the browser.</p><p>I have then written a sample JS library more or less specifically designed for the AT-AT sample.</p><h3>CSS3 Animations JavaScript fallback library</h3><p>Animations are nothing more than a series of transitions separated by a certain duration defined via the keyframes. I’ve then reused the concepts built by David Catuhe in his transitions helper library. I let you reviewing his article to check the base of the concepts behind the code.</p><p>On my side, I’ve added some support to animate the CSS3 2D Transform rotation &amp; translation values and a way to iterate through the keyframes.</p><p>Here is the main part of the library you need to review:</p><pre>// Animation object
// It need the HTML targeted element, the name of the animation, its duration &amp; iteration count and
// the keyframes contained in an array object
// View the animation simply as a sequence of transitions played a certain number of times
ANIMATIONSHELPER.animation = function (target, name, duration, iterationcount, keyframes) {
    // saving the properties values
    this.name = name;
    this.duration = duration;
    this.iterationcount = iterationcount;
    this.target = target;
    var elapsedtime = 0;
    var keyframeduration = 0;
    var elapsedtime = 0;
    // Transforming the percentage of each keyframe into duration value
    for (var i = 0; i &lt; keyframes.length; i++) {
        keyframeduration = ((keyframes[i].percentage * duration) / 100) - elapsedtime;
        keyframes[i].duration = keyframeduration;
        elapsedtime += keyframeduration;
    }
    this.currentTransition = { isPlaying: false };
    this.keyframes = keyframes;
    this.keyframesCount = keyframes.length;
    this.currentKeyFrameIndex = 0;
    // The nextTransition() function return the next transition to run
    // based on the current keyframe to play
    this.nextTransition = function (keyframe, ease, customEaseP1X, customEaseP1Y, customEaseP2X, customEaseP2Y) {
        var properties = [];
        var finalValues = [];
        var transition;
        // Compared to the original TRANSITIONSHELPER of David Catuhe
        // We need a specific code to play with the CSS3 2D Transform properties values
        if (keyframe.propertyToAnimate === "transform") {
            for (var i = 0; i &lt; keyframe.transformType.length; i++) {
                properties.push(keyframe.transformType[i].type);
                if (keyframe.transformType[i].type == "rotate") {
                    finalValues.push({ deg: keyframe.transformType[i].value1 });
                }
                else {
                    finalValues.push({ x: keyframe.transformType[i].value1, y: keyframe.transformType[i].value2 });
                }
            }
            // Create a new transition
            transition = {
                name: this.name + this.currentKeyFrameIndex,
                target: this.target,
                properties: properties,
                finalValues: finalValues,
                originalValues: ANIMATIONSHELPER.extractValues(target.style[ANIMATIONSHELPER.currentTransformProperty], this.name),
                duration: keyframe.duration,
                startDate: (new Date).getTime(),
                currentDate: (new Date).getTime(),
                ease: ease,
                customEaseP1X: customEaseP1X,
                customEaseP2X: customEaseP2X,
                customEaseP1Y: customEaseP1Y,
                customEaseP2Y: customEaseP2Y,
                isPlaying: true,
                type: "transform"
            };
            return transition;
        }
        // If it's a classic property to animate, we're using more or less the TRANSITIONSHELPER as-is
        else {
            return TRANSITIONSHELPER.transition(this.target, keyframe.propertyToAnimate, keyframe.value, keyframe.duration, TRANSITIONSHELPER.easingFunctions.linear);
        }
    };
    // each animation object has a tick function
    // that will be called every 17 ms (to target 60 fps)
    // This ticker is monitoring the current state of the transition and
    // create a new transition as soon as the old one is finished/dead
    this.tick = function () {
        if (this.iterationcount &gt; 0) {
            if (!this.currentTransition.isPlaying) {
                this.currentTransition = this.nextTransition(this.keyframes[this.currentKeyFrameIndex], ANIMATIONSHELPER.easingFunctions.linear);
                // We're using our own global ticker only for the 2D transformations
                // Otherwise, we're using the one from the TRANSITIONSHELPER library
                if (this.currentTransition.type === "transform") {
                    ANIMATIONSHELPER.currentTransitions.push(this.currentTransition);
                }
                this.currentKeyFrameIndex++;
                // We've reached the last keyframe (100%). We're starting back from the beginning
                if (this.currentKeyFrameIndex &gt;= this.keyframesCount) {
                    this.currentKeyFrameIndex = 0;
                    this.iterationcount--;
                }
            }
        }
    };
};</pre><p>The first part of the code is iterating through each keyframe to compute the exact duration specified by each percentage. We’re then defining a <code>nextTransition()</code> function that will dynamically build the next transition to play based on the current index into the keyframes collection. At last, we’ve got a <code>tick()</code> function that will monitor the current state of the transition applied. Once the transition is finished or dead, it asks for the next transition, push it to the stack of transitions to be played and moves the indexes.</p><p>This <code>tick()</code> function is called thanks to this code:</p><pre>ANIMATIONSHELPER.launchAnimation = function (animation) {
    // Launching the tick service if required
    if (ANIMATIONSHELPER.tickIntervalID == 0) {
        ANIMATIONSHELPER.tickIntervalID = setInterval(ANIMATIONSHELPER.tick, 17);
    }
    // Little closure to launch the tick method on the appropriate animation instance
    setInterval(function () { animation.tick(); }, 17);
};</pre><p>At last, we have this kind of code that helps us building the keyframes:</p><pre>// Object to build a new generic keyframe (not working on the CSS3 2D Transform properties thus)
ANIMATIONSHELPER.keyframe = function (percentage, propertyToAnimate, value) {
    this.percentage = percentage;
    this.propertyToAnimate = propertyToAnimate;
    this.value = value;
};
//Objects to build specific rotation keyframes
ANIMATIONSHELPER.rotationkeyframe = function (percentage, value) {
    this.percentage = percentage;
    this.propertyToAnimate = "transform";
    this.transformType = [];
    this.transformType.push(new ANIMATIONSHELPER.transformType("rotate", value));
};</pre><p>To highlight its usage, let’s recreate the previous simple CSS3 Animation skull sample with this library :</p><pre>// number of times you'd like the animations to be run
var iterationsNumber = 100;
var skullElement = document.getElementById("skull");
var keyframes = [];
keyframes.push(new ANIMATIONSHELPER.rotationkeyframe(25, 15));
keyframes.push(new ANIMATIONSHELPER.rotationkeyframe(50, -5));
keyframes.push(new ANIMATIONSHELPER.rotationkeyframe(55, 0));
keyframes.push(new ANIMATIONSHELPER.rotationkeyframe(75, -10));
keyframes.push(new ANIMATIONSHELPER.rotationkeyframe(100, 0));
var animation1 = new ANIMATIONSHELPER.animation(skullElement, "rotate-skull", 7000,
                            iterationsNumber, keyframes);
ANIMATIONSHELPER.launchAnimation(animation1, ANIMATIONSHELPER.easingFunctions.linear);</pre><p>And here is the result that will now work in every browser supporting CSS3 2D Transform:</p><p><iframe
style="border: #ffffff 0px solid;" src="http://david.blob.core.windows.net/html5/css3atat/indexSkullJS.htm" scrolling="no" width="400" height="200"></iframe></p><p>At last, the very first sample demonstrated at the beginning of this article uses Modernizr to check the support for CSS3 Animations. If it’s not the case, it loads the code that will mimic the keyframes defined in the file master.css, moz-master.css &amp; ms-master.css :</p><pre>// Checking if CSS3 animations is supported
if (!Modernizr.cssanimations) {
// if so, we can use our JS fallback library
    supportElement.innerHTML = "CSS3 Animations &lt;strong&gt;are not supported&lt;/strong&gt;";
    LoadJSAnimationsFallback();
}
else {
    // if CSS3 animation is supported, we have nothing to do.
    // The *master.css stylesheets will be automatically applied &amp; used.
    supportElement.innerHTML = "CSS3 Animations &lt;strong&gt;are supported&lt;/strong&gt;";
}</pre><p>The <em>LoadJSAnimationsFallback()</em> function is defined into <em>jsfallback-master.js</em> which simply contains all the keyframes declarations and the 19 animations needed to mimic the behavior created by Anthony in pure CSS3. In this approach, the designer then needs to rewrite all rules using the library. Another approach could be to parse one of the CSS file using an XHR call and to create dynamically the JavaScript calls to the library. This needs more work as you almost need to reimplement the CSS3 animations specifications in JavaScript!</p><p>You now have an idea on the way to build a fallback mechanism to support more browsers while starting to use the latest CSS3 specifications.</p><p>You can download the files for the main sample here: <a
title="http://david.blob.core.windows.net/html5/css3atat/CSS3ATATNonMinified.zip" href="http://david.blob.core.windows.net/html5/css3atat/CSS3ATATNonMinified.zip">http://david.blob.core.windows.net/html5/css3atat/CSS3ATATNonMinified.zip</a></p><p>It contains the unminified versions of the animationsHelper.js, transitionsHelper.js, jsfallback-master.js JavaScript files as well as the various CSS3 declinaison files for the main vendors prefixes.</p><h3>Conclusion</h3><p>CSS3 Animations is a powerful technology to push HTML5 applications to a new level. It offers interesting scenarios. Designers could use it to create a new generation of UI screens with smooth &amp; fluid animations without the need of developers. As it’s hardware-accelerated most of the time, developers should also pay attention to this specification. At last, both could collaborate. Designers could work on a series of predefined animations covering most scenarios. Developers could then create JavaScript libraries that will implement those animations. This library could offer in a transparent way 2 implementations: a dynamic generation of CSS3 on the fly or a fallback for older browsers.</p><h3>Going further</h3><ul><li>Article about CSS3 Transitions by David Catuhe: <a
href="http://blogs.msdn.com/b/eternalcoding/archive/2011/11/01/css3-transitions.aspx">Introduction to CSS3 Transitions</a></li><li>CSS3 Animations specifications: <a
title="http://www.w3.org/TR/css3-animations/" href="http://www.w3.org/TR/css3-animations/">http://www.w3.org/TR/css3-animations/</a></li><li>IE Test Drive on CSS3 animations: <a
title="http://ie.microsoft.com/testdrive/Graphics/hands-on-css3/hands-on_animations.htm" href="http://ie.microsoft.com/testdrive/Graphics/hands-on-css3/hands-on_animations.htm">http://ie.microsoft.com/testdrive/Graphics/hands-on-css3/hands-on_animations.htm</a></li></ul><p><strong>Other useful posts:</strong></p><ul><li>Events are relatively limited in the CSS3 Animation spec. Joe Lambert is proposing an interesting solution to trigger events on each keyframe: <a
href="http://blog.joelambert.co.uk/2011/05/20/css-animation-keyframe-events-javascript-solution/">CSS Animation Keyframe Events (Javascript solution)</a></li><li><a
title="CSS3 animation tutorial" href="http://designfestival.com/playing-with-fire-organic-css3-animation/">CSS3 animation tutorial</a> form SitePoint’s own Lead Designer Alex Walker, full of examples.</li></ul> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/build-awesome-apps-with-css3-animations/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>How to Put Your CSS3 on :target</title><link>http://www.sitepoint.com/css3-target-selector/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=css3-target-selector</link> <comments>http://www.sitepoint.com/css3-target-selector/#comments</comments> <pubDate>Mon, 30 Jan 2012 12:56:51 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[CSS Tutorials]]></category> <category><![CDATA[HTML & CSS]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript & CSS]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[HTML5 Tutorials & Articles]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=50855</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/01/630-css3-target-50x50.png" class="attachment-thumbnail wp-post-image" alt="630-css3-target" title="630-css3-target" />Craig's latest tutorial looks at the CSS3 :target selector, a powerful pseudo-class hidden in the depths of the W3C specifications which you may have missed...]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/01/630-css3-target-50x50.png" class="attachment-thumbnail wp-post-image" alt="630-css3-target" title="630-css3-target" /><p></p><p>CSS pseudo-classes which change styles in response to user actions have been with us for many years. You&#8217;ve almost certainly used :hover, :active and :focus; I can <em>(only just)</em> remember the excitement of changing IE4&#8242;s link colors back in 1997.</p><p>CSS3 also introduced :target; a powerful pseudo-class which can reduce the need for scripting in interactive widgets. Consider a page URL such as http://mysite.com/page<strong>#mytarget</strong>; an element with the id &#8220;mytarget&#8221; can have matching :target styles applied.</p><h2>:target Browser Support</h2><p>All modern browsers support :target and you won&#8217;t experience problems with IE9 or most versions of Chrome, Firefox, Safari and Opera. Unfortunately, that still leaves us with the older versions of IE. I wouldn&#8217;t worry too much about IE6 and 7, but <a
href="http://www.sitepoint.com/browser-trends-january-2012/">IE8 remains the world&#8217;s most used browser version</a>. All is not lost, however, since shims such as <a
href="http://selectivizr.com/">selectivizr</a> can add :target support without requiring complex workarounds.</p><h2>A Simple Document :target</h2><p>We&#8217;ve recently been discussing <a
href="http://www.sitepoint.com/how-to-guarantee-client-payment/">website contracts</a>. Generic contract small print such as payment schedules, hosting conditions, cancellation terms, support policies, glossaries etc. could be contained in one or more web pages. The document could grow to a considerable length even if you try and keep it concise!<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>Let&#8217;s look at a snippet of the document&#8217;s HTML5 in <em>contract.html</em>:</p><pre><code>
&lt;h1&gt;Website Contract&lt;/h1&gt;
&lt;nav&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href=&quot;#payment&quot;&gt;Payment Schedule&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#support&quot;&gt;Support &amp;amp; Maintenance&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#hosting&quot;&gt;Hosting Terms&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#glossary&quot;&gt;Glossary&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;
&lt;/nav&gt;
&lt;article id=&quot;payment&quot;&gt;
&lt;h2&gt;Payment Schedule&lt;/h2&gt;
&lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit.&lt;/p&gt;
&lt;/article&gt;
&lt;article id=&quot;support&quot;&gt;
&lt;h2&gt;Support &amp;amp; Maintenance&lt;/h2&gt;
&lt;p&gt;Ut euismod tempor porttitor.&lt;/p&gt;
&lt;/article&gt;
&lt;article id=&quot;hosting&quot;&gt;
&lt;h2&gt;Hosting Terms&lt;/h2&gt;
&lt;p&gt;Suspendisse ac nisl lorem, ut fermentum erat.&lt;/p&gt;
&lt;/article&gt;
&lt;article id=&quot;glossary&quot;&gt;
&lt;h2&gt;Glossary&lt;/h2&gt;
&lt;p&gt;Aenean id nibh eget nisl blandit hendrerit lobortis ac tortor.&lt;/p&gt;
&lt;/article&gt;
</code></pre><p>We can use the :target attribute to highlight active sections, e.g.</p><pre><code>
article:target
{
	background-color: #ffc;
	border: 2px solid #fcc;
}
</code></pre><p>Anyone <a
href="http://blogs.sitepointstatic.com/examples/tech/css3-target/document.html"><strong>viewing the contract</strong></a> can click a navigation menu item to highlight the appropriate section. You can also issue direct links to clients who require specific information, e.g. <a
href="http://blogs.sitepointstatic.com/examples/tech/css3-target/document.html#support"><strong>contract.html#support</strong></a>.</p><p>The :target selector offers further versatility &#8212; it&#8217;s possible to create dynamic effects in HTML5 and CSS without using JavaScript. Further SitePoint articles are coming soon&hellip;</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/css3-target-selector/feed/</wfw:commentRss> <slash:comments>22</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using memcached
Database Caching 33/100 queries in 0.089 seconds using memcached
Object Caching 3305/3415 objects using memcached

Served from: www.sitepoint.com @ 2012-05-27 10:01:40 -->
